BuddyPress - Version 1.2.8

Version Description

Compatibility with WordPress 3.1

=

Download this release

Release Info

Developer Otto42
Plugin Icon 128x128 BuddyPress
Version 1.2.8
Comparing to
See all releases

Code changes from version 2.9.4 to 1.2.8

Files changed (62) hide show
  1. bp-activity.php +1215 -0
  2. bp-activity/admin/css/admin-rtl.css +0 -105
  3. bp-activity/admin/css/admin-rtl.min.css +0 -1
  4. bp-activity/admin/css/admin.css +0 -105
  5. bp-activity/admin/css/admin.min.css +0 -1
  6. bp-activity/admin/js/admin.js +0 -175
  7. bp-activity/admin/js/admin.min.js +0 -1
  8. bp-activity/bp-activity-actions.php +0 -854
  9. bp-activity/bp-activity-admin.php +0 -1066
  10. bp-activity/bp-activity-adminbar.php +0 -47
  11. bp-activity/bp-activity-akismet.php +0 -72
  12. bp-activity/bp-activity-cache.php +0 -86
  13. bp-activity/bp-activity-classes.php +553 -0
  14. bp-activity/bp-activity-cssjs.php +0 -76
  15. bp-activity/bp-activity-embeds.php +0 -352
  16. bp-activity/bp-activity-filters.php +52 -744
  17. bp-activity/bp-activity-functions.php +0 -3851
  18. bp-activity/bp-activity-loader.php +0 -23
  19. bp-activity/bp-activity-notifications.php +126 -325
  20. bp-activity/bp-activity-screens.php +0 -379
  21. bp-activity/bp-activity-template.php +0 -3881
  22. bp-activity/bp-activity-templatetags.php +1074 -0
  23. bp-activity/classes/class-bp-activity-activity.php +0 -1875
  24. bp-activity/classes/class-bp-activity-component.php +0 -384
  25. bp-activity/classes/class-bp-activity-feed.php +0 -468
  26. bp-activity/classes/class-bp-activity-list-table.php +0 -857
  27. bp-activity/classes/class-bp-activity-oembed-extension.php +0 -329
  28. bp-activity/classes/class-bp-activity-query.php +0 -247
  29. bp-activity/classes/class-bp-activity-template.php +0 -408
  30. bp-activity/classes/class-bp-activity-theme-compat.php +0 -180
  31. bp-activity/classes/class-bp-akismet.php +0 -651
  32. bp-activity/css/mentions-rtl.css +0 -106
  33. bp-activity/css/mentions-rtl.min.css +0 -1
  34. bp-activity/css/mentions.css +0 -108
  35. bp-activity/css/mentions.min.css +0 -1
  36. bp-activity/feeds/bp-activity-favorites-feed.php +63 -0
  37. bp-activity/feeds/bp-activity-friends-feed.php +59 -0
  38. bp-activity/feeds/bp-activity-group-feed.php +53 -0
  39. bp-activity/feeds/bp-activity-mentions-feed.php +58 -0
  40. bp-activity/feeds/bp-activity-mygroups-feed.php +58 -0
  41. bp-activity/feeds/bp-activity-personal-feed.php +58 -0
  42. bp-activity/feeds/bp-activity-sitewide-feed.php +54 -0
  43. bp-activity/js/mentions.js +0 -255
  44. bp-activity/js/mentions.min.js +0 -1
  45. bp-blogs.php +821 -0
  46. bp-blogs/bp-blogs-actions.php +0 -34
  47. bp-blogs/bp-blogs-activity.php +0 -1446
  48. bp-blogs/bp-blogs-cache.php +0 -68
  49. bp-blogs/bp-blogs-classes.php +313 -0
  50. bp-blogs/bp-blogs-filters.php +0 -137
  51. bp-blogs/bp-blogs-functions.php +0 -1434
  52. bp-blogs/bp-blogs-loader.php +0 -25
  53. bp-blogs/bp-blogs-screens.php +0 -73
  54. bp-blogs/bp-blogs-template.php +0 -1544
  55. bp-blogs/bp-blogs-templatetags.php +544 -0
  56. bp-blogs/bp-blogs-widgets.php +77 -16
  57. bp-blogs/classes/class-bp-blogs-blog.php +0 -665
  58. bp-blogs/classes/class-bp-blogs-component.php +0 -317
  59. bp-blogs/classes/class-bp-blogs-recent-posts-widget.php +0 -164
  60. bp-blogs/classes/class-bp-blogs-template.php +0 -246
  61. bp-blogs/classes/class-bp-blogs-theme-compat.php +0 -201
  62. bp-core.php +974 -0
bp-activity.php ADDED
@@ -0,0 +1,1215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ define ( 'BP_ACTIVITY_DB_VERSION', '2100' );
4
+
5
+ /* Define the slug for the component */
6
+ if ( !defined( 'BP_ACTIVITY_SLUG' ) )
7
+ define ( 'BP_ACTIVITY_SLUG', 'activity' );
8
+
9
+ require ( BP_PLUGIN_DIR . '/bp-activity/bp-activity-classes.php' );
10
+ require ( BP_PLUGIN_DIR . '/bp-activity/bp-activity-templatetags.php' );
11
+ require ( BP_PLUGIN_DIR . '/bp-activity/bp-activity-filters.php' );
12
+
13
+ function bp_activity_install() {
14
+ global $wpdb, $bp;
15
+
16
+ if ( !empty($wpdb->charset) )
17
+ $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
18
+
19
+ /* Rename the old user activity cached table if needed. */
20
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '%{$wpdb->base_prefix}bp_activity_user_activity_cached%'" ) )
21
+ $wpdb->query( "RENAME TABLE {$wpdb->base_prefix}bp_activity_user_activity_cached TO {$bp->activity->table_name}" );
22
+
23
+ /* Rename fields from pre BP 1.2 */
24
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '%{$bp->activity->table_name}%'" ) ) {
25
+ if ( $wpdb->get_var( "SHOW COLUMNS FROM {$bp->activity->table_name} LIKE 'component_action'" ) )
26
+ $wpdb->query( "ALTER TABLE {$bp->activity->table_name} CHANGE component_action type varchar(75) NOT NULL" );
27
+
28
+ if ( $wpdb->get_var( "SHOW COLUMNS FROM {$bp->activity->table_name} LIKE 'component_name'" ) )
29
+ $wpdb->query( "ALTER TABLE {$bp->activity->table_name} CHANGE component_name component varchar(75) NOT NULL" );
30
+ }
31
+
32
+ /**
33
+ * Build the tables
34
+ */
35
+ $sql[] = "CREATE TABLE {$bp->activity->table_name} (
36
+ id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
37
+ user_id bigint(20) NOT NULL,
38
+ component varchar(75) NOT NULL,
39
+ type varchar(75) NOT NULL,
40
+ action text NOT NULL,
41
+ content longtext NOT NULL,
42
+ primary_link varchar(150) NOT NULL,
43
+ item_id varchar(75) NOT NULL,
44
+ secondary_item_id varchar(75) DEFAULT NULL,
45
+ date_recorded datetime NOT NULL,
46
+ hide_sitewide bool DEFAULT 0,
47
+ mptt_left int(11) NOT NULL DEFAULT 0,
48
+ mptt_right int(11) NOT NULL DEFAULT 0,
49
+ KEY date_recorded (date_recorded),
50
+ KEY user_id (user_id),
51
+ KEY item_id (item_id),
52
+ KEY secondary_item_id (secondary_item_id),
53
+ KEY component (component),
54
+ KEY type (type),
55
+ KEY mptt_left (mptt_left),
56
+ KEY mptt_right (mptt_right),
57
+ KEY hide_sitewide (hide_sitewide)
58
+ ) {$charset_collate};";
59
+
60
+ $sql[] = "CREATE TABLE {$bp->activity->table_name_meta} (
61
+ id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
62
+ activity_id bigint(20) NOT NULL,
63
+ meta_key varchar(255) DEFAULT NULL,
64
+ meta_value longtext DEFAULT NULL,
65
+ KEY activity_id (activity_id),
66
+ KEY meta_key (meta_key)
67
+ ) {$charset_collate};";
68
+
69
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
70
+ dbDelta($sql);
71
+
72
+ update_site_option( 'bp-activity-db-version', BP_ACTIVITY_DB_VERSION );
73
+ }
74
+
75
+ function bp_activity_setup_globals() {
76
+ global $bp, $current_blog;
77
+
78
+ /* Internal identifier */
79
+ $bp->activity->id = 'activity';
80
+
81
+ $bp->activity->slug = BP_ACTIVITY_SLUG;
82
+
83
+ $bp->activity->table_name = $bp->table_prefix . 'bp_activity';
84
+ $bp->activity->table_name_meta = $bp->table_prefix . 'bp_activity_meta';
85
+
86
+ $bp->activity->format_notification_function = 'bp_activity_format_notifications';
87
+
88
+ /* Register this in the active components array */
89
+ $bp->active_components[$bp->activity->slug] = $bp->activity->id;
90
+
91
+ do_action( 'bp_activity_setup_globals' );
92
+ }
93
+ add_action( 'bp_setup_globals', 'bp_activity_setup_globals' );
94
+
95
+ function bp_activity_check_installed() {
96
+ global $bp;
97
+
98
+ if ( get_site_option( 'bp-activity-db-version' ) < BP_ACTIVITY_DB_VERSION )
99
+ bp_activity_install();
100
+ }
101
+ add_action( is_multisite() ? 'network_admin_menu' : 'admin_menu', 'bp_activity_check_installed' );
102
+
103
+ function bp_activity_setup_root_component() {
104
+ /* Register 'activity' as a root component (for RSS feed use) */
105
+ bp_core_add_root_component( BP_ACTIVITY_SLUG );
106
+ }
107
+ add_action( 'bp_setup_root_components', 'bp_activity_setup_root_component' );
108
+
109
+ function bp_activity_setup_nav() {
110
+ global $bp;
111
+
112
+ /* Add 'Activity' to the main navigation */
113
+ bp_core_new_nav_item( array( 'name' => __( 'Activity', 'buddypress' ), 'slug' => $bp->activity->slug, 'position' => 10, 'screen_function' => 'bp_activity_screen_my_activity', 'default_subnav_slug' => 'just-me', 'item_css_id' => $bp->activity->id ) );
114
+
115
+ $user_domain = ( !empty( $bp->displayed_user->domain ) ) ? $bp->displayed_user->domain : $bp->loggedin_user->domain;
116
+ $user_login = ( !empty( $bp->displayed_user->userdata->user_login ) ) ? $bp->displayed_user->userdata->user_login : $bp->loggedin_user->userdata->user_login;
117
+ $activity_link = $user_domain . $bp->activity->slug . '/';
118
+
119
+ /* Add the subnav items to the activity nav item if we are using a theme that supports this */
120
+ bp_core_new_subnav_item( array( 'name' => __( 'Personal', 'buddypress' ), 'slug' => 'just-me', 'parent_url' => $activity_link, 'parent_slug' => $bp->activity->slug, 'screen_function' => 'bp_activity_screen_my_activity', 'position' => 10 ) );
121
+
122
+ if ( bp_is_active( 'friends' ) )
123
+ bp_core_new_subnav_item( array( 'name' => __( 'Friends', 'buddypress' ), 'slug' => BP_FRIENDS_SLUG, 'parent_url' => $activity_link, 'parent_slug' => $bp->activity->slug, 'screen_function' => 'bp_activity_screen_friends', 'position' => 20, 'item_css_id' => 'activity-friends' ) );
124
+
125
+ if ( bp_is_active( 'groups' ) )
126
+ bp_core_new_subnav_item( array( 'name' => __( 'Groups', 'buddypress' ), 'slug' => BP_GROUPS_SLUG, 'parent_url' => $activity_link, 'parent_slug' => $bp->activity->slug, 'screen_function' => 'bp_activity_screen_groups', 'position' => 30, 'item_css_id' => 'activity-groups' ) );
127
+
128
+ bp_core_new_subnav_item( array( 'name' => __( 'Favorites', 'buddypress' ), 'slug' => 'favorites', 'parent_url' => $activity_link, 'parent_slug' => $bp->activity->slug, 'screen_function' => 'bp_activity_screen_favorites', 'position' => 40, 'item_css_id' => 'activity-favs' ) );
129
+ bp_core_new_subnav_item( array( 'name' => sprintf( __( '@%s Mentions', 'buddypress' ), $user_login ), 'slug' => 'mentions', 'parent_url' => $activity_link, 'parent_slug' => $bp->activity->slug, 'screen_function' => 'bp_activity_screen_mentions', 'position' => 50, 'item_css_id' => 'activity-mentions' ) );
130
+
131
+ if ( $bp->current_component == $bp->activity->slug ) {
132
+ if ( bp_is_my_profile() ) {
133
+ $bp->bp_options_title = __( 'My Activity', 'buddypress' );
134
+ } else {
135
+ $bp->bp_options_avatar = bp_core_fetch_avatar( array( 'item_id' => $bp->displayed_user->id, 'type' => 'thumb' ) );
136
+ $bp->bp_options_title = $bp->displayed_user->fullname;
137
+ }
138
+ }
139
+
140
+ do_action( 'bp_activity_setup_nav' );
141
+ }
142
+ add_action( 'bp_setup_nav', 'bp_activity_setup_nav' );
143
+
144
+ function bp_activity_directory_activity_setup() {
145
+ global $bp;
146
+
147
+ if ( $bp->current_component == $bp->activity->slug && empty( $bp->current_action ) ) {
148
+ $bp->is_directory = true;
149
+
150
+ do_action( 'bp_activity_directory_activity_setup' );
151
+ bp_core_load_template( apply_filters( 'bp_activity_directory_activity_setup', 'activity/index' ) );
152
+ }
153
+ }
154
+ add_action( 'wp', 'bp_activity_directory_activity_setup', 2 );
155
+
156
+
157
+ /********************************************************************************
158
+ * Screen Functions
159
+ *
160
+ * Screen functions are the controllers of BuddyPress. They will execute when their
161
+ * specific URL is caught. They will first save or manipulate data using business
162
+ * functions, then pass on the user to a template file.
163
+ */
164
+
165
+ function bp_activity_screen_my_activity() {
166
+ do_action( 'bp_activity_screen_my_activity' );
167
+ bp_core_load_template( apply_filters( 'bp_activity_template_my_activity', 'members/single/home' ) );
168
+ }
169
+
170
+ function bp_activity_screen_friends() {
171
+ global $bp;
172
+
173
+ if ( !bp_is_active( 'friends' ) )
174
+ return false;
175
+
176
+ if ( !is_super_admin() )
177
+ $bp->is_item_admin = false;
178
+
179
+ do_action( 'bp_activity_screen_friends' );
180
+ bp_core_load_template( apply_filters( 'bp_activity_template_friends_activity', 'members/single/home' ) );
181
+ }
182
+
183
+ function bp_activity_screen_groups() {
184
+ global $bp;
185
+
186
+ if ( !bp_is_active( 'groups' ) )
187
+ return false;
188
+
189
+ if ( !is_super_admin() )
190
+ $bp->is_item_admin = false;
191
+
192
+ do_action( 'bp_activity_screen_groups' );
193
+ bp_core_load_template( apply_filters( 'bp_activity_template_groups_activity', 'members/single/home' ) );
194
+ }
195
+
196
+ function bp_activity_screen_favorites() {
197
+ global $bp;
198
+
199
+ if ( !is_super_admin() )
200
+ $bp->is_item_admin = false;
201
+
202
+ do_action( 'bp_activity_screen_favorites' );
203
+ bp_core_load_template( apply_filters( 'bp_activity_template_favorite_activity', 'members/single/home' ) );
204
+ }
205
+
206
+ function bp_activity_screen_mentions() {
207
+ global $bp;
208
+
209
+ if ( !is_super_admin() )
210
+ $bp->is_item_admin = false;
211
+
212
+ do_action( 'bp_activity_screen_mentions' );
213
+ bp_core_load_template( apply_filters( 'bp_activity_template_mention_activity', 'members/single/home' ) );
214
+ }
215
+
216
+ function bp_activity_screen_single_activity_permalink() {
217
+ global $bp;
218
+
219
+ if ( !$bp->displayed_user->id || $bp->current_component != $bp->activity->slug )
220
+ return false;
221
+
222
+ if ( empty( $bp->current_action ) || !is_numeric( $bp->current_action ) )
223
+ return false;
224
+
225
+ /* Get the activity details */
226
+ $activity = bp_activity_get_specific( array( 'activity_ids' => $bp->current_action ) );
227
+
228
+ if ( !$activity = $activity['activities'][0] )
229
+ bp_core_redirect( $bp->root_domain );
230
+
231
+ $has_access = true;
232
+ /* Redirect based on the type of activity */
233
+ if ( $activity->component == $bp->groups->id ) {
234
+ if ( !function_exists( 'groups_get_group' ) )
235
+ bp_core_redirect( $bp->root_domain );
236
+
237
+ if ( $group = groups_get_group( array( 'group_id' => $activity->item_id ) ) ) {
238
+ /* Check to see if the group is not public, if so, check the user has access to see this activity */
239
+ if ( 'public' != $group->status ) {
240
+ if ( !groups_is_user_member( $bp->loggedin_user->id, $group->id ) )
241
+ $has_access = false;
242
+ }
243
+ }
244
+ }
245
+
246
+ $has_access = apply_filters( 'bp_activity_permalink_access', $has_access, &$activity );
247
+
248
+ do_action( 'bp_activity_screen_single_activity_permalink', $activity, $has_access );
249
+
250
+ if ( !$has_access ) {
251
+ bp_core_add_message( __( 'You do not have access to this activity.', 'buddypress' ), 'error' );
252
+
253
+ if ( is_user_logged_in() )
254
+ bp_core_redirect( $bp->loggedin_user->domain );
255
+ else
256
+ bp_core_redirect( site_url( 'wp-login.php?redirect_to=' . esc_url( $bp->root_domain . '/' . $bp->activity->slug . '/p/' . $bp->current_action ) ) );
257
+ }
258
+
259
+ bp_core_load_template( apply_filters( 'bp_activity_template_profile_activity_permalink', 'members/single/activity/permalink' ) );
260
+ }
261
+ /* This screen is not attached to a nav item, so we need to add an action for it. */
262
+ add_action( 'wp', 'bp_activity_screen_single_activity_permalink', 3 );
263
+
264
+ function bp_activity_screen_notification_settings() {
265
+ global $bp; ?>
266
+ <table class="notification-settings zebra" id="activity-notification-settings">
267
+ <thead>
268
+ <tr>
269
+ <th class="icon"></th>
270
+ <th class="title"><?php _e( 'Activity', 'buddypress' ) ?></th>
271
+ <th class="yes"><?php _e( 'Yes', 'buddypress' ) ?></th>
272
+ <th class="no"><?php _e( 'No', 'buddypress' )?></th>
273
+ </tr>
274
+ </thead>
275
+
276
+ <tbody>
277
+ <tr>
278
+ <td></td>
279
+ <td><?php printf( __( 'A member mentions you in an update using "@%s"', 'buddypress' ), bp_core_get_username( $bp->loggedin_user->id, $bp->loggedin_user->userdata->user_nicename, $bp->loggedin_user->userdata->user_login ) ) ?></td>
280
+ <td class="yes"><input type="radio" name="notifications[notification_activity_new_mention]" value="yes" <?php if ( !get_user_meta( $bp->loggedin_user->id, 'notification_activity_new_mention', true ) || 'yes' == get_user_meta( $bp->loggedin_user->id, 'notification_activity_new_mention', true ) ) { ?>checked="checked" <?php } ?>/></td>
281
+ <td class="no"><input type="radio" name="notifications[notification_activity_new_mention]" value="no" <?php if ( 'no' == get_user_meta( $bp->loggedin_user->id, 'notification_activity_new_mention', true ) ) { ?>checked="checked" <?php } ?>/></td>
282
+ </tr>
283
+ <tr>
284
+ <td></td>
285
+ <td><?php printf( __( "A member replies to an update or comment you've posted", 'buddypress' ), $current_user->user_login ) ?></td>
286
+ <td class="yes"><input type="radio" name="notifications[notification_activity_new_reply]" value="yes" <?php if ( !get_user_meta( $bp->loggedin_user->id, 'notification_activity_new_reply', true ) || 'yes' == get_user_meta( $bp->loggedin_user->id, 'notification_activity_new_reply', true ) ) { ?>checked="checked" <?php } ?>/></td>
287
+ <td class="no"><input type="radio" name="notifications[notification_activity_new_reply]" value="no" <?php if ( 'no' == get_user_meta( $bp->loggedin_user->id, 'notification_activity_new_reply', true ) ) { ?>checked="checked" <?php } ?>/></td>
288
+ </tr>
289
+
290
+ <?php do_action( 'bp_activity_screen_notification_settings' ) ?>
291
+ </tbody>
292
+ </table>
293
+ <?php
294
+ }
295
+ add_action( 'bp_notification_settings', 'bp_activity_screen_notification_settings', 1 );
296
+
297
+ /********************************************************************************
298
+ * Action Functions
299
+ *
300
+ * Action functions are exactly the same as screen functions, however they do not
301
+ * have a template screen associated with them. Usually they will send the user
302
+ * back to the default screen after execution.
303
+ */
304
+
305
+ function bp_activity_action_permalink_router() {
306
+ global $bp;
307
+
308
+ if ( $bp->current_component != $bp->activity->slug || $bp->current_action != 'p' )
309
+ return false;
310
+
311
+ if ( empty( $bp->action_variables[0] ) || !is_numeric( $bp->action_variables[0] ) )
312
+ return false;
313
+
314
+ /* Get the activity details */
315
+ $activity = bp_activity_get_specific( array( 'activity_ids' => $bp->action_variables[0] ) );
316
+
317
+ if ( !$activity = $activity['activities'][0] )
318
+ bp_core_redirect( $bp->root_domain );
319
+
320
+ $redirect = false;
321
+ /* Redirect based on the type of activity */
322
+ if ( $activity->component == $bp->groups->id ) {
323
+ if ( $activity->user_id )
324
+ $redirect = bp_core_get_user_domain( $activity->user_id, $activity->user_nicename, $activity->user_login ) . $bp->activity->slug . '/' . $activity->id . '/';
325
+ else {
326
+ if ( $group = groups_get_group( array( 'group_id' => $activity->item_id ) ) )
327
+ $redirect = bp_get_group_permalink( $group ) . $bp->activity->slug . '/' . $activity->id . '/';
328
+ }
329
+ } else
330
+ $redirect = bp_core_get_user_domain( $activity->user_id, $activity->user_nicename, $activity->user_login ) . $bp->activity->slug . '/' . $activity->id;
331
+
332
+ $redirect = apply_filters( 'bp_activity_permalink_redirect_url', $redirect, &$activity );
333
+
334
+ if ( !$redirect )
335
+ bp_core_redirect( $bp->root_domain );
336
+
337
+ /* Redirect to the actual activity permalink page */
338
+ bp_core_redirect( $redirect );
339
+ }
340
+ add_action( 'wp', 'bp_activity_action_permalink_router', 3 );
341
+
342
+ function bp_activity_action_delete_activity() {
343
+ global $bp;
344
+
345
+ if ( $bp->current_component != $bp->activity->slug || $bp->current_action != 'delete' )
346
+ return false;
347
+
348
+ if ( empty( $bp->action_variables[0] ) || !is_numeric( $bp->action_variables[0] ) )
349
+ return false;
350
+
351
+ /* Check the nonce */
352
+ check_admin_referer( 'bp_activity_delete_link' );
353
+
354
+ $activity_id = $bp->action_variables[0];
355
+ $activity = new BP_Activity_Activity( $activity_id );
356
+
357
+ /* Check access */
358
+ if ( !is_super_admin() && $activity->user_id != $bp->loggedin_user->id )
359
+ return false;
360
+
361
+ /* Call the action before the delete so plugins can still fetch information about it */
362
+ do_action( 'bp_activity_action_delete_activity', $activity_id, $activity->user_id );
363
+
364
+ /* Now delete the activity item */
365
+ if ( bp_activity_delete( array( 'id' => $activity_id, 'user_id' => $activity->user_id ) ) )
366
+ bp_core_add_message( __( 'Activity deleted', 'buddypress' ) );
367
+ else
368
+ bp_core_add_message( __( 'There was an error when deleting that activity', 'buddypress' ), 'error' );
369
+
370
+ bp_core_redirect( wp_get_referer() );
371
+ }
372
+ add_action( 'wp', 'bp_activity_action_delete_activity', 3 );
373
+
374
+ function bp_activity_action_post_update() {
375
+ global $bp;
376
+
377
+ if ( !is_user_logged_in() || $bp->current_component != $bp->activity->slug || $bp->current_action != 'post' )
378
+ return false;
379
+
380
+ /* Check the nonce */
381
+ check_admin_referer( 'post_update', '_wpnonce_post_update' );
382
+
383
+ $content = apply_filters( 'bp_activity_post_update_content', $_POST['whats-new'] );
384
+ $object = apply_filters( 'bp_activity_post_update_object', $_POST['whats-new-post-object'] );
385
+ $item_id = apply_filters( 'bp_activity_post_update_item_id', $_POST['whats-new-post-in'] );
386
+
387
+ if ( empty( $content ) ) {
388
+ bp_core_add_message( __( 'Please enter some content to post.', 'buddypress' ), 'error' );
389
+ bp_core_redirect( wp_get_referer() );
390
+ }
391
+
392
+ if ( !(int)$item_id ) {
393
+ $activity_id = bp_activity_post_update( array( 'content' => $content ) );
394
+
395
+ } else if ( 'groups' == $object && function_exists( 'groups_post_update' ) ) {
396
+ if ( (int)$item_id ) {
397
+ $activity_id = groups_post_update( array( 'content' => $content, 'group_id' => $item_id ) );
398
+ }
399
+ } else
400
+ $activity_id = apply_filters( 'bp_activity_custom_update', $object, $item_id, $content );
401
+
402
+ if ( !empty( $activity_id ) )
403
+ bp_core_add_message( __( 'Update Posted!', 'buddypress' ) );
404
+ else
405
+ bp_core_add_message( __( 'There was an error when posting your update, please try again.', 'buddypress' ), 'error' );
406
+
407
+ bp_core_redirect( wp_get_referer() );
408
+ }
409
+ add_action( 'wp', 'bp_activity_action_post_update', 3 );
410
+
411
+ function bp_activity_action_post_comment() {
412
+ global $bp;
413
+
414
+ if ( !is_user_logged_in() || $bp->current_component != $bp->activity->slug || $bp->current_action != 'reply' )
415
+ return false;
416
+
417
+ /* Check the nonce */
418
+ check_admin_referer( 'new_activity_comment', '_wpnonce_new_activity_comment' );
419
+
420
+ $activity_id = apply_filters( 'bp_activity_post_comment_activity_id', $_POST['comment_form_id'] );
421
+ $content = apply_filters( 'bp_activity_post_comment_content', $_POST['ac_input_' . $activity_id] );
422
+
423
+ if ( empty( $content ) ) {
424
+ bp_core_add_message( __( 'Please do not leave the comment area blank.', 'buddypress' ), 'error' );
425
+ bp_core_redirect( wp_get_referer() . '#ac-form-' . $activity_id );
426
+ }
427
+
428
+ $comment_id = bp_activity_new_comment( array(
429
+ 'content' => $content,
430
+ 'activity_id' => $activity_id,
431
+ 'parent_id' => $parent_id
432
+ ));
433
+
434
+ if ( !empty( $comment_id ) )
435
+ bp_core_add_message( __( 'Reply Posted!', 'buddypress' ) );
436
+ else
437
+ bp_core_add_message( __( 'There was an error posting that reply, please try again.', 'buddypress' ), 'error' );
438
+
439
+ bp_core_redirect( wp_get_referer() . '#ac-form-' . $activity_id );
440
+ }
441
+ add_action( 'wp', 'bp_activity_action_post_comment', 3 );
442
+
443
+ function bp_activity_action_mark_favorite() {
444
+ global $bp;
445
+
446
+ if ( !is_user_logged_in() || $bp->current_component != $bp->activity->slug || $bp->current_action != 'favorite' )
447
+ return false;
448
+
449
+ /* Check the nonce */
450
+ check_admin_referer( 'mark_favorite' );
451
+
452
+ if ( bp_activity_add_user_favorite( $bp->action_variables[0] ) )
453
+ bp_core_add_message( __( 'Activity marked as favorite.', 'buddypress' ) );
454
+ else
455
+ bp_core_add_message( __( 'There was an error marking that activity as a favorite, please try again.', 'buddypress' ), 'error' );
456
+
457
+ bp_core_redirect( wp_get_referer() . '#activity-' . $bp->action_variables[0] );
458
+ }
459
+ add_action( 'wp', 'bp_activity_action_mark_favorite', 3 );
460
+
461
+ function bp_activity_action_remove_favorite() {
462
+ global $bp;
463
+
464
+ if ( !is_user_logged_in() || $bp->current_component != $bp->activity->slug || $bp->current_action != 'unfavorite' )
465
+ return false;
466
+
467
+ /* Check the nonce */
468
+ check_admin_referer( 'unmark_favorite' );
469
+
470
+ if ( bp_activity_remove_user_favorite( $bp->action_variables[0] ) )
471
+ bp_core_add_message( __( 'Activity removed as favorite.', 'buddypress' ) );
472
+ else
473
+ bp_core_add_message( __( 'There was an error removing that activity as a favorite, please try again.', 'buddypress' ), 'error' );
474
+
475
+ bp_core_redirect( wp_get_referer() . '#activity-' . $bp->action_variables[0] );
476
+ }
477
+ add_action( 'wp', 'bp_activity_action_remove_favorite', 3 );
478
+
479
+ function bp_activity_action_sitewide_feed() {
480
+ global $bp, $wp_query;
481
+
482
+ if ( $bp->current_component != $bp->activity->slug || $bp->current_action != 'feed' || $bp->displayed_user->id || $bp->groups->current_group )
483
+ return false;
484
+
485
+ $wp_query->is_404 = false;
486
+ status_header( 200 );
487
+
488
+ include_once( 'bp-activity/feeds/bp-activity-sitewide-feed.php' );
489
+ die;
490
+ }
491
+ add_action( 'wp', 'bp_activity_action_sitewide_feed', 3 );
492
+
493
+ function bp_activity_action_personal_feed() {
494
+ global $bp, $wp_query;
495
+
496
+ if ( $bp->current_component != $bp->activity->slug || !$bp->displayed_user->id || $bp->current_action != 'feed' )
497
+ return false;
498
+
499
+ $wp_query->is_404 = false;
500
+ status_header( 200 );
501
+
502
+ include_once( 'bp-activity/feeds/bp-activity-personal-feed.php' );
503
+ die;
504
+ }
505
+ add_action( 'wp', 'bp_activity_action_personal_feed', 3 );
506
+
507
+ function bp_activity_action_friends_feed() {
508
+ global $bp, $wp_query;
509
+
510
+ if ( $bp->current_component != $bp->activity->slug || !$bp->displayed_user->id || $bp->current_action != 'friends' || $bp->action_variables[0] != 'feed' )
511
+ return false;
512
+
513
+ $wp_query->is_404 = false;
514
+ status_header( 200 );
515
+
516
+ include_once( 'bp-activity/feeds/bp-activity-friends-feed.php' );
517
+ die;
518
+ }
519
+ add_action( 'wp', 'bp_activity_action_friends_feed', 3 );
520
+
521
+ function bp_activity_action_my_groups_feed() {
522
+ global $bp, $wp_query;
523
+
524
+ if ( $bp->current_component != $bp->activity->slug || !$bp->displayed_user->id || $bp->current_action != 'groups' || $bp->action_variables[0] != 'feed' )
525
+ return false;
526
+
527
+ $wp_query->is_404 = false;
528
+ status_header( 200 );
529
+
530
+ include_once( 'bp-activity/feeds/bp-activity-mygroups-feed.php' );
531
+ die;
532
+ }
533
+ add_action( 'wp', 'bp_activity_action_my_groups_feed', 3 );
534
+
535
+ function bp_activity_action_mentions_feed() {
536
+ global $bp, $wp_query;
537
+
538
+ if ( $bp->current_component != $bp->activity->slug || !$bp->displayed_user->id || $bp->current_action != 'mentions' || $bp->action_variables[0] != 'feed' )
539
+ return false;
540
+
541
+ $wp_query->is_404 = false;
542
+ status_header( 200 );
543
+
544
+ include_once( 'bp-activity/feeds/bp-activity-mentions-feed.php' );
545
+ die;
546
+ }
547
+ add_action( 'wp', 'bp_activity_action_mentions_feed', 3 );
548
+
549
+ function bp_activity_action_favorites_feed() {
550
+ global $bp, $wp_query;
551
+
552
+ if ( $bp->current_component != $bp->activity->slug || !$bp->displayed_user->id || $bp->current_action != 'favorites' || $bp->action_variables[0] != 'feed' )
553
+ return false;
554
+
555
+ $wp_query->is_404 = false;
556
+ status_header( 200 );
557
+
558
+ include_once( 'bp-activity/feeds/bp-activity-favorites-feed.php' );
559
+ die;
560
+ }
561
+ add_action( 'wp', 'bp_activity_action_favorites_feed', 3 );
562
+
563
+ /********************************************************************************
564
+ * Business Functions
565
+ *
566
+ * Business functions are where all the magic happens in BuddyPress. They will
567
+ * handle the actual saving or manipulation of information. Usually they will
568
+ * hand off to a database class for data access, then return
569
+ * true or false on success or failure.
570
+ */
571
+
572
+ function bp_activity_get( $args = '' ) {
573
+ $defaults = array(
574
+ 'max' => false, // Maximum number of results to return
575
+ 'page' => 1, // page 1 without a per_page will result in no pagination.
576
+ 'per_page' => false, // results per page
577
+ 'sort' => 'DESC', // sort ASC or DESC
578
+ 'display_comments' => false, // false for no comments. 'stream' for within stream display, 'threaded' for below each activity item
579
+
580
+ 'search_terms' => false, // Pass search terms as a string
581
+ 'show_hidden' => false, // Show activity items that are hidden site-wide?
582
+
583
+ /**
584
+ * Pass filters as an array -- all filter items can be multiple values comma separated:
585
+ * array(
586
+ * 'user_id' => false, // user_id to filter on
587
+ * 'object' => false, // object to filter on e.g. groups, profile, status, friends
588
+ * 'action' => false, // action to filter on e.g. activity_update, profile_updated
589
+ * 'primary_id' => false, // object ID to filter on e.g. a group_id or forum_id or blog_id etc.
590
+ * 'secondary_id' => false, // secondary object ID to filter on e.g. a post_id
591
+ * );
592
+ */
593
+ 'filter' => array()
594
+ );
595
+
596
+ $r = wp_parse_args( $args, $defaults );
597
+ extract( $r, EXTR_SKIP );
598
+
599
+ /* Attempt to return a cached copy of the first page of sitewide activity. */
600
+ if ( 1 == (int)$page && empty( $max ) && empty( $search_terms ) && empty( $filter ) && 'DESC' == $sort ) {
601
+ if ( !$activity = wp_cache_get( 'bp_activity_sitewide_front', 'bp' ) ) {
602
+ $activity = BP_Activity_Activity::get( $max, $page, $per_page, $sort, $search_terms, $filter, $display_comments, $show_hidden );
603
+ wp_cache_set( 'bp_activity_sitewide_front', $activity, 'bp' );
604
+ }
605
+ } else
606
+ $activity = BP_Activity_Activity::get( $max, $page, $per_page, $sort, $search_terms, $filter, $display_comments, $show_hidden );
607
+
608
+ return apply_filters( 'bp_activity_get', $activity, &$r );
609
+ }
610
+
611
+ function bp_activity_get_specific( $args = '' ) {
612
+ $defaults = array(
613
+ 'activity_ids' => false, // A single activity_id or array of IDs.
614
+ 'page' => 1, // page 1 without a per_page will result in no pagination.
615
+ 'per_page' => false, // results per page
616
+ 'max' => false, // Maximum number of results to return
617
+ 'sort' => 'DESC', // sort ASC or DESC
618
+ 'display_comments' => false // true or false to display threaded comments for these specific activity items
619
+ );
620
+
621
+ $r = wp_parse_args( $args, $defaults );
622
+ extract( $r, EXTR_SKIP );
623
+
624
+ return apply_filters( 'bp_activity_get_specific', BP_Activity_Activity::get_specific( $activity_ids, $max, $page, $per_page, $sort, $display_comments ) );
625
+ }
626
+
627
+ function bp_activity_add( $args = '' ) {
628
+ global $bp;
629
+
630
+ $defaults = array(
631
+ 'id' => false, // Pass an existing activity ID to update an existing entry.
632
+
633
+ 'action' => '', // The activity action - e.g. "Jon Doe posted an update"
634
+ 'content' => '', // Optional: The content of the activity item e.g. "BuddyPress is awesome guys!"
635
+
636
+ 'component' => false, // The name/ID of the component e.g. groups, profile, mycomponent
637
+ 'type' => false, // The activity type e.g. activity_update, profile_updated
638
+ 'primary_link' => '', // Optional: The primary URL for this item in RSS feeds (defaults to activity permalink)
639
+
640
+ 'user_id' => $bp->loggedin_user->id, // Optional: The user to record the activity for, can be false if this activity is not for a user.
641
+ 'item_id' => false, // Optional: The ID of the specific item being recorded, e.g. a blog_id
642
+ 'secondary_item_id' => false, // Optional: A second ID used to further filter e.g. a comment_id
643
+ 'recorded_time' => bp_core_current_time(), // The GMT time that this activity was recorded
644
+ 'hide_sitewide' => false // Should this be hidden on the sitewide activity stream?
645
+ );
646
+
647
+ $params = wp_parse_args( $args, $defaults );
648
+ extract( $params, EXTR_SKIP );
649
+
650
+ /* Make sure we are backwards compatible */
651
+ if ( empty( $component ) && !empty( $component_name ) )
652
+ $component = $component_name;
653
+
654
+ if ( empty( $type ) && !empty( $component_action ) )
655
+ $type = $component_action;
656
+
657
+ $activity = new BP_Activity_Activity( $id );
658
+
659
+ $activity->user_id = $user_id;
660
+ $activity->component = $component;
661
+ $activity->type = $type;
662
+ $activity->action = $action;
663
+ $activity->content = $content;
664
+ $activity->primary_link = $primary_link;
665
+ $activity->item_id = $item_id;
666
+ $activity->secondary_item_id = $secondary_item_id;
667
+ $activity->date_recorded = $recorded_time;
668
+ $activity->hide_sitewide = $hide_sitewide;
669
+
670
+ if ( !$activity->save() )
671
+ return false;
672
+
673
+ /* If this is an activity comment, rebuild the tree */
674
+ if ( 'activity_comment' == $activity->type )
675
+ BP_Activity_Activity::rebuild_activity_comment_tree( $activity->item_id );
676
+
677
+ wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
678
+ do_action( 'bp_activity_add', $params );
679
+
680
+ return $activity->id;
681
+ }
682
+
683
+ function bp_activity_post_update( $args = '' ) {
684
+ global $bp;
685
+
686
+ $defaults = array(
687
+ 'content' => false,
688
+ 'user_id' => $bp->loggedin_user->id
689
+ );
690
+
691
+ $r = wp_parse_args( $args, $defaults );
692
+ extract( $r, EXTR_SKIP );
693
+
694
+ if ( empty( $content ) || !strlen( trim( $content ) ) )
695
+ return false;
696
+
697
+ /* Record this on the user's profile */
698
+ $from_user_link = bp_core_get_userlink( $user_id );
699
+ $activity_action = sprintf( __( '%s posted an update:', 'buddypress' ), $from_user_link );
700
+ $activity_content = $content;
701
+
702
+ $primary_link = bp_core_get_userlink( $user_id, false, true );
703
+
704
+ /* Now write the values */
705
+ $activity_id = bp_activity_add( array(
706
+ 'user_id' => $user_id,
707
+ 'action' => apply_filters( 'bp_activity_new_update_action', $activity_action ),
708
+ 'content' => apply_filters( 'bp_activity_new_update_content', $activity_content ),
709
+ 'primary_link' => apply_filters( 'bp_activity_new_update_primary_link', $primary_link ),
710
+ 'component' => $bp->activity->id,
711
+ 'type' => 'activity_update'
712
+ ) );
713
+
714
+ /* Add this update to the "latest update" usermeta so it can be fetched anywhere. */
715
+ update_user_meta( $bp->loggedin_user->id, 'bp_latest_update', array( 'id' => $activity_id, 'content' => wp_filter_kses( $content ) ) );
716
+
717
+ /* Require the notifications code so email notifications can be set on the 'bp_activity_posted_update' action. */
718
+ require_once( BP_PLUGIN_DIR . '/bp-activity/bp-activity-notifications.php' );
719
+
720
+ do_action( 'bp_activity_posted_update', $content, $user_id, $activity_id );
721
+
722
+ return $activity_id;
723
+ }
724
+
725
+ function bp_activity_new_comment( $args = '' ) {
726
+ global $bp;
727
+
728
+ $defaults = array(
729
+ 'id' => false,
730
+ 'content' => false,
731
+ 'user_id' => $bp->loggedin_user->id,
732
+ 'activity_id' => false, // ID of the root activity item
733
+ 'parent_id' => false // ID of a parent comment (optional)
734
+ );
735
+
736
+ $params = wp_parse_args( $args, $defaults );
737
+ extract( $params, EXTR_SKIP );
738
+
739
+ if ( empty($content) || empty($user_id) || empty($activity_id) )
740
+ return false;
741
+
742
+ if ( empty($parent_id) )
743
+ $parent_id = $activity_id;
744
+
745
+ /* Check to see if the parent activity is hidden, and if so, hide this comment publically. */
746
+ $activity = new BP_Activity_Activity( $activity_id );
747
+ $is_hidden = ( (int)$activity->hide_sitewide ) ? 1 : 0;
748
+
749
+ /* Insert the activity comment */
750
+ $comment_id = bp_activity_add( array(
751
+ 'id' => $id,
752
+ 'action' => apply_filters( 'bp_activity_comment_action', sprintf( __( '%s posted a new activity comment:', 'buddypress' ), bp_core_get_userlink( $user_id ) ) ),
753
+ 'content' => apply_filters( 'bp_activity_comment_content', $content ),
754
+ 'component' => $bp->activity->id,
755
+ 'type' => 'activity_comment',
756
+ 'user_id' => $user_id,
757
+ 'item_id' => $activity_id,
758
+ 'secondary_item_id' => $parent_id,
759
+ 'hide_sitewide' => $is_hidden
760
+ ) );
761
+
762
+ /* Send an email notification if settings allow */
763
+ require_once( BP_PLUGIN_DIR . '/bp-activity/bp-activity-notifications.php' );
764
+ bp_activity_new_comment_notification( $comment_id, $user_id, $params );
765
+
766
+ /* Clear the comment cache for this activity */
767
+ wp_cache_delete( 'bp_activity_comments_' . $parent_id );
768
+
769
+ do_action( 'bp_activity_comment_posted', $comment_id, $params );
770
+
771
+ return $comment_id;
772
+ }
773
+
774
+ /**
775
+ * bp_activity_get_activity_id()
776
+ *
777
+ * Fetch the activity_id for an existing activity entry in the DB.
778
+ *
779
+ * @package BuddyPress Activity
780
+ */
781
+ function bp_activity_get_activity_id( $args = '' ) {
782
+ $defaults = array(
783
+ 'user_id' => false,
784
+ 'component' => false,
785
+ 'type' => false,
786
+ 'item_id' => false,
787
+ 'secondary_item_id' => false,
788
+ 'action' => false,
789
+ 'content' => false,
790
+ 'date_recorded' => false,
791
+ );
792
+
793
+ $r = wp_parse_args( $args, $defaults );
794
+ extract( $r, EXTR_SKIP );
795
+
796
+ return apply_filters( 'bp_activity_get_activity_id', BP_Activity_Activity::get_id( $user_id, $component, $type, $item_id, $secondary_item_id, $action, $content, $date_recorded ) );
797
+ }
798
+
799
+ /***
800
+ * Deleting Activity
801
+ *
802
+ * If you're looking to hook into one action that provides the ID(s) of
803
+ * the activity/activities deleted, then use:
804
+ *
805
+ * add_action( 'bp_activity_deleted_activities', 'my_function' );
806
+ *
807
+ * The action passes one parameter that is a single activity ID or an
808
+ * array of activity IDs depending on the number deleted.
809
+ *
810
+ * If you are deleting an activity comment please use bp_activity_delete_comment();
811
+ */
812
+
813
+ function bp_activity_delete( $args = '' ) {
814
+ global $bp;
815
+
816
+ /* Pass one or more the of following variables to delete by those variables */
817
+ $defaults = array(
818
+ 'id' => false,
819
+ 'action' => false,
820
+ 'content' => false,
821
+ 'component' => false,
822
+ 'type' => false,
823
+ 'primary_link' => false,
824
+ 'user_id' => false,
825
+ 'item_id' => false,
826
+ 'secondary_item_id' => false,
827
+ 'date_recorded' => false,
828
+ 'hide_sitewide' => false
829
+ );
830
+
831
+ $args = wp_parse_args( $args, $defaults );
832
+
833
+ if ( !$activity_ids_deleted = BP_Activity_Activity::delete( $args ) )
834
+ return false;
835
+
836
+ /* Check if the user's latest update has been deleted */
837
+ if ( empty( $args['user_id'] ) )
838
+ $user_id = $bp->loggedin_user->id;
839
+ else
840
+ $user_id = $args['user_id'];
841
+
842
+ $latest_update = get_user_meta( $user_id, 'bp_latest_update', true );
843
+ if ( !empty( $latest_update ) ) {
844
+ if ( in_array( (int)$latest_update['id'], (array)$activity_ids_deleted ) )
845
+ delete_user_meta( $user_id, 'bp_latest_update' );
846
+ }
847
+
848
+ do_action( 'bp_activity_delete', $args );
849
+ do_action( 'bp_activity_deleted_activities', $activity_ids_deleted );
850
+
851
+ wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
852
+
853
+ return true;
854
+ }
855
+ /* The following functions have been deprecated in place of bp_activity_delete() */
856
+ function bp_activity_delete_by_item_id( $args = '' ) {
857
+ global $bp;
858
+
859
+ $defaults = array( 'item_id' => false, 'component' => false, 'type' => false, 'user_id' => false, 'secondary_item_id' => false );
860
+ $r = wp_parse_args( $args, $defaults );
861
+ extract( $r, EXTR_SKIP );
862
+
863
+ return bp_activity_delete( array( 'item_id' => $item_id, 'component' => $component, 'type' => $type, 'user_id' => $user_id, 'secondary_item_id' => $secondary_item_id ) );
864
+ }
865
+
866
+ function bp_activity_delete_by_activity_id( $activity_id ) {
867
+ return bp_activity_delete( array( 'id' => $activity_id ) );
868
+ }
869
+
870
+ function bp_activity_delete_by_content( $user_id, $content, $component, $type ) {
871
+ return bp_activity_delete( array( 'user_id' => $user_id, 'content' => $content, 'component' => $component, 'type' => $type ) );
872
+ }
873
+
874
+ function bp_activity_delete_for_user_by_component( $user_id, $component ) {
875
+ return bp_activity_delete( array( 'user_id' => $user_id, 'component' => $component ) );
876
+ }
877
+ /* End deprecation */
878
+
879
+ function bp_activity_delete_comment( $activity_id, $comment_id ) {
880
+ /***
881
+ * You may want to hook into this filter if you want to override this function and
882
+ * handle the deletion of child comments differently. Make sure you return false.
883
+ */
884
+ if ( !apply_filters( 'bp_activity_delete_comment_pre', true, $activity_id, $comment_id ) )
885
+ return false;
886
+
887
+ /* Delete any children of this comment. */
888
+ bp_activity_delete_children( $activity_id, $comment_id );
889
+
890
+ /* Delete the actual comment */
891
+ if ( !bp_activity_delete( array( 'id' => $comment_id, 'type' => 'activity_comment' ) ) )
892
+ return false;
893
+
894
+ /* Recalculate the comment tree */
895
+ BP_Activity_Activity::rebuild_activity_comment_tree( $activity_id );
896
+
897
+ do_action( 'bp_activity_delete_comment', $activity_id, $comment_id );
898
+
899
+ return true;
900
+ }
901
+ function bp_activity_delete_children( $activity_id, $comment_id) {
902
+ /* Recursively delete all children of this comment. */
903
+ if ( $children = BP_Activity_Activity::get_child_comments( $comment_id ) ) {
904
+ foreach( (array)$children as $child )
905
+ bp_activity_delete_children( $activity_id, $child->id );
906
+ }
907
+ bp_activity_delete( array( 'secondary_item_id' => $comment_id, 'type' => 'activity_comment', 'item_id' => $activity_id ) );
908
+ }
909
+
910
+ function bp_activity_get_permalink( $activity_id, $activity_obj = false ) {
911
+ global $bp;
912
+
913
+ if ( !$activity_obj )
914
+ $activity_obj = new BP_Activity_Activity( $activity_id );
915
+
916
+ if ( 'new_blog_post' == $activity_obj->type || 'new_blog_comment' == $activity_obj->type || 'new_forum_topic' == $activity_obj->type || 'new_forum_post' == $activity_obj->type )
917
+ $link = $activity_obj->primary_link;
918
+ else {
919
+ if ( 'activity_comment' == $activity_obj->type )
920
+ $link = $bp->root_domain . '/' . BP_ACTIVITY_SLUG . '/p/' . $activity_obj->item_id . '/';
921
+ else
922
+ $link = $bp->root_domain . '/' . BP_ACTIVITY_SLUG . '/p/' . $activity_obj->id . '/';
923
+ }
924
+
925
+ return apply_filters( 'bp_activity_get_permalink', $link );
926
+ }
927
+
928
+ function bp_activity_hide_user_activity( $user_id ) {
929
+ return BP_Activity_Activity::hide_all_for_user( $user_id );
930
+ }
931
+
932
+ /**
933
+ * bp_activity_thumbnail_content_images()
934
+ *
935
+ * Take content, remove all images and replace them with one thumbnail image.
936
+ *
937
+ * @package BuddyPress Activity
938
+ * @param $content str - The content to work with
939
+ * @return $content str - The content with images stripped and replaced with a single thumb.
940
+ */
941
+ function bp_activity_thumbnail_content_images( $content ) {
942
+ preg_match_all( '/<img[^>]*>/Ui', $content, $matches );
943
+ $content = preg_replace('/<img[^>]*>/Ui', '', $content );
944
+
945
+ if ( !empty( $matches ) ) {
946
+ /* Get the SRC value */
947
+ preg_match( '/<img.*?(src\=[\'|"]{0,1}.*?[\'|"]{0,1})[\s|>]{1}/i', $matches[0][0], $src );
948
+
949
+ /* Get the width and height */
950
+ preg_match( '/<img.*?(height\=[\'|"]{0,1}.*?[\'|"]{0,1})[\s|>]{1}/i', $matches[0][0], $height );
951
+ preg_match( '/<img.*?(width\=[\'|"]{0,1}.*?[\'|"]{0,1})[\s|>]{1}/i', $matches[0][0], $width );
952
+
953
+ if ( !empty( $src ) ) {
954
+ $src = substr( substr( str_replace( 'src=', '', $src[1] ), 0, -1 ), 1 );
955
+ $height = substr( substr( str_replace( 'height=', '', $height[1] ), 0, -1 ), 1 );
956
+ $width = substr( substr( str_replace( 'width=', '', $width[1] ), 0, -1 ), 1 );
957
+
958
+ if ( empty( $width ) || empty( $height ) ) {
959
+ $width = 100;
960
+ $height = 100;
961
+ }
962
+
963
+ $ratio = (int)$width / (int)$height;
964
+ $new_height = 100;
965
+ $new_width = $new_height * $ratio;
966
+
967
+ $content = '<img src="' . esc_attr( $src) . '" width="' . $new_width . '" height="' . $new_height . '" alt="' . __( 'Thumbnail', 'buddypress' ) . '" class="align-left thumbnail" />' . $content;
968
+ }
969
+ }
970
+
971
+ return apply_filters( 'bp_activity_thumbnail_content_images', $content, $matches );
972
+ }
973
+
974
+ function bp_activity_set_action( $component_id, $key, $value ) {
975
+ global $bp;
976
+
977
+ if ( empty( $component_id ) || empty( $key ) || empty( $value ) )
978
+ return false;
979
+
980
+ $bp->activity->actions->{$component_id}->{$key} = apply_filters( 'bp_activity_set_action', array(
981
+ 'key' => $key,
982
+ 'value' => $value
983
+ ), $component_id, $key, $value );
984
+ }
985
+
986
+ function bp_activity_get_action( $component_id, $key ) {
987
+ global $bp;
988
+
989
+ if ( empty( $component_id ) || empty( $key ) )
990
+ return false;
991
+
992
+ return apply_filters( 'bp_activity_get_action', $bp->activity->actions->{$component_id}->{$key}, $component_id, $key );
993
+ }
994
+
995
+ function bp_activity_get_user_favorites( $user_id ) {
996
+ $my_favs = maybe_unserialize( get_user_meta( $user_id, 'bp_favorite_activities', true ) );
997
+ $existing_favs = bp_activity_get_specific( array( 'activity_ids' => $my_favs ) );
998
+
999
+ foreach( (array)$existing_favs['activities'] as $fav )
1000
+ $new_favs[] = $fav->id;
1001
+
1002
+ $new_favs = array_unique( (array)$new_favs );
1003
+ update_user_meta( $user_id, 'bp_favorite_activities', $new_favs );
1004
+
1005
+ return apply_filters( 'bp_activity_get_user_favorites', $new_favs );
1006
+ }
1007
+
1008
+ function bp_activity_add_user_favorite( $activity_id, $user_id = false ) {
1009
+ global $bp;
1010
+
1011
+ if ( !$user_id )
1012
+ $user_id = $bp->loggedin_user->id;
1013
+
1014
+ /* Update the user's personal favorites */
1015
+ $my_favs = maybe_unserialize( get_user_meta( $bp->loggedin_user->id, 'bp_favorite_activities', true ) );
1016
+ $my_favs[] = $activity_id;
1017
+
1018
+ /* Update the total number of users who have favorited this activity */
1019
+ $fav_count = bp_activity_get_meta( $activity_id, 'favorite_count' );
1020
+
1021
+ if ( !empty( $fav_count ) )
1022
+ $fav_count = (int)$fav_count + 1;
1023
+ else
1024
+ $fav_count = 1;
1025
+
1026
+ update_user_meta( $bp->loggedin_user->id, 'bp_favorite_activities', $my_favs );
1027
+ bp_activity_update_meta( $activity_id, 'favorite_count', $fav_count );
1028
+
1029
+ do_action( 'bp_activity_add_user_favorite', $activity_id, $user_id );
1030
+
1031
+ return true;
1032
+ }
1033
+
1034
+ function bp_activity_remove_user_favorite( $activity_id, $user_id = false ) {
1035
+ global $bp;
1036
+
1037
+ if ( !$user_id )
1038
+ $user_id = $bp->loggedin_user->id;
1039
+
1040
+ /* Remove the fav from the user's favs */
1041
+ $my_favs = maybe_unserialize( get_user_meta( $user_id, 'bp_favorite_activities', true ) );
1042
+ $my_favs = array_flip( (array) $my_favs );
1043
+ unset( $my_favs[$activity_id] );
1044
+ $my_favs = array_unique( array_flip( $my_favs ) );
1045
+
1046
+ /* Update the total number of users who have favorited this activity */
1047
+ $fav_count = bp_activity_get_meta( $activity_id, 'favorite_count' );
1048
+
1049
+ if ( !empty( $fav_count ) ) {
1050
+ $fav_count = (int)$fav_count - 1;
1051
+ bp_activity_update_meta( $activity_id, 'favorite_count', $fav_count );
1052
+ }
1053
+
1054
+ update_user_meta( $user_id, 'bp_favorite_activities', $my_favs );
1055
+
1056
+ do_action( 'bp_activity_remove_user_favorite', $activity_id, $user_id );
1057
+
1058
+ return true;
1059
+ }
1060
+
1061
+ function bp_activity_check_exists_by_content( $content ) {
1062
+ return apply_filters( 'bp_activity_check_exists_by_content', BP_Activity_Activity::check_exists_by_content( $content ) );
1063
+ }
1064
+
1065
+ function bp_activity_get_last_updated() {
1066
+ return apply_filters( 'bp_activity_get_last_updated', BP_Activity_Activity::get_last_updated() );
1067
+ }
1068
+
1069
+ function bp_activity_total_favorites_for_user( $user_id = false ) {
1070
+ global $bp;
1071
+
1072
+ if ( !$user_id )
1073
+ $user_id = ( $bp->displayed_user->id ) ? $bp->displayed_user->id : $bp->loggedin_user->id;
1074
+
1075
+ return BP_Activity_Activity::total_favorite_count( $user_id );
1076
+ }
1077
+
1078
+ /********************************************************************************
1079
+ * Activity Meta Functions
1080
+ *
1081
+ * Meta functions allow you to store extra data for a particular item.
1082
+ */
1083
+
1084
+ function bp_activity_delete_meta( $activity_id, $meta_key = false, $meta_value = false ) {
1085
+ global $wpdb, $bp;
1086
+
1087
+ if ( !is_numeric( $activity_id ) )
1088
+ return false;
1089
+
1090
+ $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
1091
+
1092
+ if ( is_array( $meta_value ) || is_object( $meta_value ) )
1093
+ $meta_value = serialize( $meta_value );
1094
+
1095
+ $meta_value = trim( $meta_value );
1096
+
1097
+ if ( !$meta_key ) {
1098
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id = %d", $activity_id ) );
1099
+ } else if ( $meta_value ) {
1100
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s AND meta_value = %s", $activity_id, $meta_key, $meta_value ) );
1101
+ } else {
1102
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s", $activity_id, $meta_key ) );
1103
+ }
1104
+
1105
+ wp_cache_delete( 'bp_activity_meta_' . $meta_key . '_' . $activity_id, 'bp' );
1106
+
1107
+ return true;
1108
+ }
1109
+
1110
+ function bp_activity_get_meta( $activity_id, $meta_key = '' ) {
1111
+ global $wpdb, $bp;
1112
+
1113
+ $activity_id = (int)$activity_id;
1114
+
1115
+ if ( !$activity_id )
1116
+ return false;
1117
+
1118
+ if ( !empty($meta_key) ) {
1119
+ $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
1120
+
1121
+ if ( !$metas = wp_cache_get( 'bp_activity_meta_' . $meta_key . '_' . $activity_id, 'bp' ) ) {
1122
+ $metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s", $activity_id, $meta_key ) );
1123
+ wp_cache_set( 'bp_activity_meta_' . $meta_key . '_' . $activity_id, $metas, 'bp' );
1124
+ }
1125
+ } else
1126
+ $metas = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM {$bp->activity->table_name_meta} WHERE activity_id = %d", $activity_id ) );
1127
+
1128
+ if ( empty($metas) )
1129
+ return false;
1130
+
1131
+ $metas = array_map( 'maybe_unserialize', (array)$metas );
1132
+
1133
+ if ( 1 == count($metas) )
1134
+ return $metas[0];
1135
+ else
1136
+ return $metas;
1137
+ }
1138
+
1139
+ function bp_activity_update_meta( $activity_id, $meta_key, $meta_value ) {
1140
+ global $wpdb, $bp;
1141
+
1142
+ if ( !is_numeric( $activity_id ) )
1143
+ return false;
1144
+
1145
+ $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
1146
+
1147
+ if ( is_string( $meta_value ) )
1148
+ $meta_value = stripslashes( $wpdb->escape( $meta_value ) );
1149
+
1150
+ $meta_value = maybe_serialize( $meta_value );
1151
+
1152
+ if ( empty( $meta_value ) ) {
1153
+ return bp_activity_delete_meta( $activity_id, $meta_key );
1154
+ }
1155
+
1156
+ $cur = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s", $activity_id, $meta_key ) );
1157
+
1158
+ if ( !$cur ) {
1159
+ $wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->activity->table_name_meta} ( activity_id, meta_key, meta_value ) VALUES ( %d, %s, %s )", $activity_id, $meta_key, $meta_value ) );
1160
+ } else if ( $cur->meta_value != $meta_value ) {
1161
+ $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name_meta} SET meta_value = %s WHERE activity_id = %d AND meta_key = %s", $meta_value, $activity_id, $meta_key ) );
1162
+ } else {
1163
+ return false;
1164
+ }
1165
+
1166
+ wp_cache_set( 'bp_activity_meta_' . $meta_key . '_' . $activity_id, $meta_value, 'bp' );
1167
+
1168
+ return true;
1169
+ }
1170
+
1171
+ function bp_activity_remove_data( $user_id ) {
1172
+ // Clear the user's activity from the sitewide stream and clear their activity tables
1173
+ bp_activity_delete( array( 'user_id' => $user_id ) );
1174
+
1175
+ // Remove any usermeta
1176
+ delete_user_meta( $user_id, 'bp_latest_update' );
1177
+ delete_user_meta( $user_id, 'bp_favorite_activities' );
1178
+
1179
+ do_action( 'bp_activity_remove_data', $user_id );
1180
+ }
1181
+ add_action( 'wpmu_delete_user', 'bp_activity_remove_data' );
1182
+ add_action( 'delete_user', 'bp_activity_remove_data' );
1183
+ add_action( 'make_spam_user', 'bp_activity_remove_data' );
1184
+
1185
+ /**
1186
+ * updates_register_activity_actions()
1187
+ *
1188
+ * Register the activity stream actions for updates
1189
+ *
1190
+ * @global array $bp
1191
+ */
1192
+ function updates_register_activity_actions() {
1193
+ global $bp;
1194
+
1195
+ bp_activity_set_action( $bp->activity->id, 'activity_update', __( 'Posted an update', 'buddypress' ) );
1196
+
1197
+ do_action( 'updates_register_activity_actions' );
1198
+ }
1199
+ add_action( 'bp_register_activity_actions', 'updates_register_activity_actions' );
1200
+
1201
+ /********************************************************************************
1202
+ * Custom Actions
1203
+ *
1204
+ * Functions to set up custom BuddyPress actions that all other components can
1205
+ * hook in to.
1206
+ */
1207
+
1208
+ /* Allow core components and dependent plugins to register activity actions */
1209
+ function bp_register_activity_actions() {
1210
+ do_action( 'bp_register_activity_actions' );
1211
+ }
1212
+ add_action( 'bp_loaded', 'bp_register_activity_actions', 8 );
1213
+
1214
+
1215
+ ?>
bp-activity/admin/css/admin-rtl.css DELETED
@@ -1,105 +0,0 @@
1
- .akismet-status {
2
- float: left;
3
- }
4
-
5
- .akismet-status a {
6
- color: #aaa;
7
- font-style: italic;
8
- }
9
-
10
- .akismet-history {
11
- margin: 13px;
12
- }
13
-
14
- .akismet-history div {
15
- margin-bottom: 13px;
16
- }
17
-
18
- .akismet-history span {
19
- color: #999;
20
- }
21
-
22
- #wp-bp-activities-wrap {
23
- padding: 5px 0;
24
- }
25
-
26
- #bp-activities {
27
- height: 120px;
28
- }
29
-
30
- #bp-replyhead {
31
- font-size: 1em;
32
- line-height: 1.4;
33
- margin: 0;
34
- }
35
-
36
- #bp-replysubmit {
37
- margin: 0;
38
- padding: 0 0 3px;
39
- text-align: center;
40
- }
41
-
42
- #bp-replysubmit .error {
43
- color: #f00;
44
- line-height: 21px;
45
- text-align: center;
46
- vertical-align: center;
47
- }
48
-
49
- #bp-replysubmit img.waiting {
50
- float: left;
51
- padding: 4px 10px 0;
52
- vertical-align: top;
53
- }
54
-
55
- #bp-activities-form .column-response img {
56
- float: right;
57
- margin-bottom: 5px;
58
- margin-left: 10px;
59
- margin-top: 1px;
60
- }
61
-
62
- .activity-errors {
63
- list-style-type: disc;
64
- margin-right: 2em;
65
- }
66
-
67
- #bp_activity_action div.inside,
68
- #bp_activity_content div.inside {
69
- line-height: 0;
70
- }
71
-
72
- #bp_activity_action h3,
73
- #bp_activity_content h3 {
74
- cursor: auto;
75
- }
76
-
77
- #bp_activity_action td.mceIframeContainer,
78
- #bp_activity_content td.mceIframeContainer {
79
- background-color: #fff;
80
- }
81
-
82
- #post-body #bp-activities-action_resize,
83
- #post-body #bp-activities-content_resize {
84
- position: inherit;
85
- margin-top: -2px;
86
- }
87
-
88
- #bp_activity_link input {
89
- width: 99%;
90
- }
91
-
92
- #bp-activities-primaryid {
93
- margin-bottom: 1em;
94
- }
95
-
96
- .column-action {
97
- width: 12%;
98
- }
99
-
100
- @media screen and (max-width: 782px) {
101
-
102
- body.toplevel_page_bp-activity .wp-list-table tr:not(.inline-edit-row):not(.no-items) td:not(.check-column) {
103
- display: table-cell;
104
- }
105
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/admin/css/admin-rtl.min.css DELETED
@@ -1 +0,0 @@
1
- .akismet-status{float:left}.akismet-status a{color:#aaa;font-style:italic}.akismet-history{margin:13px}.akismet-history div{margin-bottom:13px}.akismet-history span{color:#999}#wp-bp-activities-wrap{padding:5px 0}#bp-activities{height:120px}#bp-replyhead{font-size:1em;line-height:1.4;margin:0}#bp-replysubmit{margin:0;padding:0 0 3px;text-align:center}#bp-replysubmit .error{color:red;line-height:21px;text-align:center;vertical-align:center}#bp-replysubmit img.waiting{float:left;padding:4px 10px 0;vertical-align:top}#bp-activities-form .column-response img{float:right;margin-bottom:5px;margin-left:10px;margin-top:1px}.activity-errors{list-style-type:disc;margin-right:2em}#bp_activity_action div.inside,#bp_activity_content div.inside{line-height:0}#bp_activity_action h3,#bp_activity_content h3{cursor:auto}#bp_activity_action td.mceIframeContainer,#bp_activity_content td.mceIframeContainer{background-color:#fff}#post-body #bp-activities-action_resize,#post-body #bp-activities-content_resize{position:inherit;margin-top:-2px}#bp_activity_link input{width:99%}#bp-activities-primaryid{margin-bottom:1em}.column-action{width:12%}@media screen and (max-width:782px){body.toplevel_page_bp-activity .wp-list-table tr:not(.inline-edit-row):not(.no-items) td:not(.check-column){display:table-cell}}
 
bp-activity/admin/css/admin.css DELETED
@@ -1,105 +0,0 @@
1
- .akismet-status {
2
- float: right;
3
- }
4
-
5
- .akismet-status a {
6
- color: #aaa;
7
- font-style: italic;
8
- }
9
-
10
- .akismet-history {
11
- margin: 13px;
12
- }
13
-
14
- .akismet-history div {
15
- margin-bottom: 13px;
16
- }
17
-
18
- .akismet-history span {
19
- color: #999;
20
- }
21
-
22
- #wp-bp-activities-wrap {
23
- padding: 5px 0;
24
- }
25
-
26
- #bp-activities {
27
- height: 120px;
28
- }
29
-
30
- #bp-replyhead {
31
- font-size: 1em;
32
- line-height: 1.4;
33
- margin: 0;
34
- }
35
-
36
- #bp-replysubmit {
37
- margin: 0;
38
- padding: 0 0 3px;
39
- text-align: center;
40
- }
41
-
42
- #bp-replysubmit .error {
43
- color: #f00;
44
- line-height: 21px;
45
- text-align: center;
46
- vertical-align: center;
47
- }
48
-
49
- #bp-replysubmit img.waiting {
50
- float: right;
51
- padding: 4px 10px 0;
52
- vertical-align: top;
53
- }
54
-
55
- #bp-activities-form .column-response img {
56
- float: left;
57
- margin-bottom: 5px;
58
- margin-right: 10px;
59
- margin-top: 1px;
60
- }
61
-
62
- .activity-errors {
63
- list-style-type: disc;
64
- margin-left: 2em;
65
- }
66
-
67
- #bp_activity_action div.inside,
68
- #bp_activity_content div.inside {
69
- line-height: 0;
70
- }
71
-
72
- #bp_activity_action h3,
73
- #bp_activity_content h3 {
74
- cursor: auto;
75
- }
76
-
77
- #bp_activity_action td.mceIframeContainer,
78
- #bp_activity_content td.mceIframeContainer {
79
- background-color: #fff;
80
- }
81
-
82
- #post-body #bp-activities-action_resize,
83
- #post-body #bp-activities-content_resize {
84
- position: inherit;
85
- margin-top: -2px;
86
- }
87
-
88
- #bp_activity_link input {
89
- width: 99%;
90
- }
91
-
92
- #bp-activities-primaryid {
93
- margin-bottom: 1em;
94
- }
95
-
96
- .column-action {
97
- width: 12%;
98
- }
99
-
100
- @media screen and (max-width: 782px) {
101
-
102
- body.toplevel_page_bp-activity .wp-list-table tr:not(.inline-edit-row):not(.no-items) td:not(.check-column) {
103
- display: table-cell;
104
- }
105
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/admin/css/admin.min.css DELETED
@@ -1 +0,0 @@
1
- .akismet-status{float:right}.akismet-status a{color:#aaa;font-style:italic}.akismet-history{margin:13px}.akismet-history div{margin-bottom:13px}.akismet-history span{color:#999}#wp-bp-activities-wrap{padding:5px 0}#bp-activities{height:120px}#bp-replyhead{font-size:1em;line-height:1.4;margin:0}#bp-replysubmit{margin:0;padding:0 0 3px;text-align:center}#bp-replysubmit .error{color:red;line-height:21px;text-align:center;vertical-align:center}#bp-replysubmit img.waiting{float:right;padding:4px 10px 0;vertical-align:top}#bp-activities-form .column-response img{float:left;margin-bottom:5px;margin-right:10px;margin-top:1px}.activity-errors{list-style-type:disc;margin-left:2em}#bp_activity_action div.inside,#bp_activity_content div.inside{line-height:0}#bp_activity_action h3,#bp_activity_content h3{cursor:auto}#bp_activity_action td.mceIframeContainer,#bp_activity_content td.mceIframeContainer{background-color:#fff}#post-body #bp-activities-action_resize,#post-body #bp-activities-content_resize{position:inherit;margin-top:-2px}#bp_activity_link input{width:99%}#bp-activities-primaryid{margin-bottom:1em}.column-action{width:12%}@media screen and (max-width:782px){body.toplevel_page_bp-activity .wp-list-table tr:not(.inline-edit-row):not(.no-items) td:not(.check-column){display:table-cell}}
 
bp-activity/admin/js/admin.js DELETED
@@ -1,175 +0,0 @@
1
- /* global bp_activity_admin_vars, postboxes, wpAjax */
2
- (function( $ ) {
3
-
4
- /**
5
- * Activity reply object for the activity index screen
6
- *
7
- * @since 1.6.0
8
- */
9
- var activityReply = {
10
-
11
- /**
12
- * Attach event handler functions to the relevant elements.
13
- *
14
- * @since 1.6.0
15
- */
16
- init : function() {
17
- $(document).on( 'click', '.row-actions a.reply', activityReply.open );
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();
25
- }
26
- });
27
- },
28
-
29
- /**
30
- * Reveals the entire row when "reply" is pressed.
31
- *
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
-
39
- // Fade the whole row in, and set focus on the text area.
40
- box.fadeIn( '300' );
41
- $( '#bp-activities' ).focus();
42
-
43
- return false;
44
- },
45
-
46
- /**
47
- * Hide and reset the entire row when "cancel", or escape, are pressed.
48
- *
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
- });
62
-
63
- return false;
64
- },
65
-
66
- /**
67
- * Submits "form" via AJAX back to WordPress.
68
- *
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
- });
96
-
97
- return false;
98
- },
99
-
100
- /**
101
- * send() error message handler
102
- *
103
- * @since 1.6.0
104
- */
105
- error : function( r ) {
106
- var er = r.statusText;
107
- $('#bp-replysubmit .waiting').hide();
108
-
109
- if ( r.responseText ) {
110
- er = r.responseText.replace( /<.[^<>]*?>/g, '' );
111
- }
112
-
113
- if ( er ) {
114
- $('#bp-replysubmit .error').html( er ).show();
115
- }
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;
130
- }
131
-
132
- response = wpAjax.parseAjaxResponse( xml );
133
- if ( response.errors ) {
134
- activityReply.error( { 'responseText': wpAjax.broken } );
135
- return false;
136
- }
137
- response = response.responses[0];
138
-
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 );
156
- });
157
- }
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
168
- // of activity administration page id so that metaboxes are still collapsible
169
- // in single Activity Administration screen.
170
- if ( typeof postboxes !== 'undefined' ) {
171
- postboxes.add_postbox_toggles( bp_activity_admin_vars.page );
172
- }
173
- });
174
-
175
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/admin/js/admin.min.js DELETED
@@ -1 +0,0 @@
1
- !function(i){var t={init:function(){i(document).on("click",".row-actions a.reply",t.open),i(document).on("click","#bp-activities-container a.cancel",t.close),i(document).on("click","#bp-activities-container a.save",t.send),i(document).on("keyup","#bp-activities:visible",function(i){27===i.which&&t.close()})},open:function(){var t=i("#bp-activities-container").hide();return i(this).parents("tr").after(t),t.fadeIn("300"),i("#bp-activities").focus(),!1},close:function(){return i("#bp-activities-container").fadeOut("200",function(){i("#bp-activities").val("").blur(),i("#bp-replysubmit .error").html("").hide(),i("#bp-replysubmit .waiting").hide()}),!1},send:function(){i("#bp-replysubmit .error").hide(),i("#bp-replysubmit .waiting").show();var e={};return e["_ajax_nonce-bp-activity-admin-reply"]=i('#bp-activities-container input[name="_ajax_nonce-bp-activity-admin-reply"]').val(),e.action="bp-activity-admin-reply",e.content=i("#bp-activities").val(),e.parent_id=i("#bp-activities-container").prev().data("parent_id"),e.root_id=i("#bp-activities-container").prev().data("root_id"),i.ajax({data:e,type:"POST",url:ajaxurl,error:function(i){t.error(i)},success:function(i){t.show(i)}}),!1},error:function(t){var e=t.statusText;i("#bp-replysubmit .waiting").hide(),t.responseText&&(e=t.responseText.replace(/<.[^<>]*?>/g,"")),e&&i("#bp-replysubmit .error").html(e).show()},show:function(e){var n,a,r;return"string"==typeof e?(t.error({responseText:e}),!1):(r=wpAjax.parseAjaxResponse(e)).errors?(t.error({responseText:wpAjax.broken}),!1):(r=r.responses[0],void i("#bp-activities-container").fadeOut("200",function(){i("#bp-activities").val("").blur(),i("#bp-replysubmit .error").html("").hide(),i("#bp-replysubmit .waiting").hide(),i("#bp-activities-container").before(r.data),a=i("#activity-"+r.id),n=a.closest(".widefat").css("backgroundColor"),a.animate({backgroundColor:"#CEB"},300).animate({backgroundColor:n},300)}))}};i(document).ready(function(){t.init(),i("#bp_activity_action h3, #bp_activity_content h3").unbind("click"),"undefined"!=typeof postboxes&&postboxes.add_postbox_toggles(bp_activity_admin_vars.page)})}(jQuery);
 
bp-activity/bp-activity-actions.php DELETED
@@ -1,854 +0,0 @@
1
- <?php
2
- /**
3
- * Action functions are exactly the same as screen functions, however they do
4
- * not have a template screen associated with them. Usually they will send the
5
- * user back to the default screen after execution.
6
- *
7
- * @package BuddyPress
8
- * @subpackage ActivityActions
9
- * @since 1.5.0
10
- */
11
-
12
- // Exit if accessed directly.
13
- defined( 'ABSPATH' ) || exit;
14
-
15
- /**
16
- * Allow core components and dependent plugins to register activity actions.
17
- *
18
- * @since 1.2.0
19
- *
20
- */
21
- function bp_register_activity_actions() {
22
-
23
- /**
24
- * Fires on bp_init to allow core components and dependent plugins to register activity actions.
25
- *
26
- * @since 1.2.0
27
- */
28
- do_action( 'bp_register_activity_actions' );
29
- }
30
- add_action( 'bp_init', 'bp_register_activity_actions', 8 );
31
-
32
- /**
33
- * Catch and route requests for single activity item permalinks.
34
- *
35
- * @since 1.2.0
36
- *
37
- * @return bool False on failure.
38
- */
39
- function bp_activity_action_permalink_router() {
40
-
41
- // Not viewing activity.
42
- if ( ! bp_is_activity_component() || ! bp_is_current_action( 'p' ) )
43
- return false;
44
-
45
- // No activity to display.
46
- if ( ! bp_action_variable( 0 ) || ! is_numeric( bp_action_variable( 0 ) ) )
47
- return false;
48
-
49
- // Get the activity details.
50
- $activity = bp_activity_get_specific( array( 'activity_ids' => bp_action_variable( 0 ), 'show_hidden' => true ) );
51
-
52
- // 404 if activity does not exist
53
- if ( empty( $activity['activities'][0] ) ) {
54
- bp_do_404();
55
- return;
56
- } else {
57
- $activity = $activity['activities'][0];
58
- }
59
-
60
- // Do not redirect at default.
61
- $redirect = false;
62
-
63
- // Redirect based on the type of activity.
64
- if ( bp_is_active( 'groups' ) && $activity->component == buddypress()->groups->id ) {
65
-
66
- // Activity is a user update.
67
- if ( ! empty( $activity->user_id ) ) {
68
- $redirect = bp_core_get_user_domain( $activity->user_id, $activity->user_nicename, $activity->user_login ) . bp_get_activity_slug() . '/' . $activity->id . '/';
69
-
70
- // Activity is something else.
71
- } else {
72
-
73
- // Set redirect to group activity stream.
74
- if ( $group = groups_get_group( $activity->item_id ) ) {
75
- $redirect = bp_get_group_permalink( $group ) . bp_get_activity_slug() . '/' . $activity->id . '/';
76
- }
77
- }
78
-
79
- // Set redirect to users' activity stream.
80
- } elseif ( ! empty( $activity->user_id ) ) {
81
- $redirect = bp_core_get_user_domain( $activity->user_id, $activity->user_nicename, $activity->user_login ) . bp_get_activity_slug() . '/' . $activity->id . '/';
82
- }
83
-
84
- // If set, add the original query string back onto the redirect URL.
85
- if ( ! empty( $_SERVER['QUERY_STRING'] ) ) {
86
- $query_frags = array();
87
- wp_parse_str( $_SERVER['QUERY_STRING'], $query_frags );
88
- $redirect = add_query_arg( urlencode_deep( $query_frags ), $redirect );
89
- }
90
-
91
- /**
92
- * Filter the intended redirect url before the redirect occurs for the single activity item.
93
- *
94
- * @since 1.2.2
95
- *
96
- * @param array $value Array with url to redirect to and activity related to the redirect.
97
- */
98
- if ( ! $redirect = apply_filters_ref_array( 'bp_activity_permalink_redirect_url', array( $redirect, &$activity ) ) ) {
99
- bp_core_redirect( bp_get_root_domain() );
100
- }
101
-
102
- // Redirect to the actual activity permalink page.
103
- bp_core_redirect( $redirect );
104
- }
105
- add_action( 'bp_actions', 'bp_activity_action_permalink_router' );
106
-
107
- /**
108
- * Delete specific activity item and redirect to previous page.
109
- *
110
- * @since 1.1.0
111
- *
112
- * @param int $activity_id Activity id to be deleted. Defaults to 0.
113
- * @return bool False on failure.
114
- */
115
- function bp_activity_action_delete_activity( $activity_id = 0 ) {
116
-
117
- // Not viewing activity or action is not delete.
118
- if ( !bp_is_activity_component() || !bp_is_current_action( 'delete' ) )
119
- return false;
120
-
121
- if ( empty( $activity_id ) && bp_action_variable( 0 ) )
122
- $activity_id = (int) bp_action_variable( 0 );
123
-
124
- // Not viewing a specific activity item.
125
- if ( empty( $activity_id ) )
126
- return false;
127
-
128
- // Check the nonce.
129
- check_admin_referer( 'bp_activity_delete_link' );
130
-
131
- // Load up the activity item.
132
- $activity = new BP_Activity_Activity( $activity_id );
133
-
134
- // Check access.
135
- if ( ! bp_activity_user_can_delete( $activity ) )
136
- return false;
137
-
138
- /**
139
- * Fires before the deletion so plugins can still fetch information about it.
140
- *
141
- * @since 1.5.0
142
- *
143
- * @param int $activity_id The activity ID.
144
- * @param int $user_id The user associated with the activity.
145
- */
146
- do_action( 'bp_activity_before_action_delete_activity', $activity_id, $activity->user_id );
147
-
148
- // Delete the activity item and provide user feedback.
149
- if ( bp_activity_delete( array( 'id' => $activity_id, 'user_id' => $activity->user_id ) ) )
150
- bp_core_add_message( __( 'Activity deleted successfully', 'buddypress' ) );
151
- else
152
- bp_core_add_message( __( 'There was an error when deleting that activity', 'buddypress' ), 'error' );
153
-
154
- /**
155
- * Fires after the deletion so plugins can act afterwards based on the activity.
156
- *
157
- * @since 1.1.0
158
- *
159
- * @param int $activity_id The activity ID.
160
- * @param int $user_id The user associated with the activity.
161
- */
162
- do_action( 'bp_activity_action_delete_activity', $activity_id, $activity->user_id );
163
-
164
- // Check for the redirect query arg, otherwise let WP handle things.
165
- if ( !empty( $_GET['redirect_to'] ) )
166
- bp_core_redirect( esc_url( $_GET['redirect_to'] ) );
167
- else
168
- bp_core_redirect( wp_get_referer() );
169
- }
170
- add_action( 'bp_actions', 'bp_activity_action_delete_activity' );
171
-
172
- /**
173
- * Mark specific activity item as spam and redirect to previous page.
174
- *
175
- * @since 1.6.0
176
- *
177
- * @param int $activity_id Activity id to be deleted. Defaults to 0.
178
- * @return bool False on failure.
179
- */
180
- function bp_activity_action_spam_activity( $activity_id = 0 ) {
181
- $bp = buddypress();
182
-
183
- // Not viewing activity, or action is not spam, or Akismet isn't present.
184
- if ( !bp_is_activity_component() || !bp_is_current_action( 'spam' ) || empty( $bp->activity->akismet ) )
185
- return false;
186
-
187
- if ( empty( $activity_id ) && bp_action_variable( 0 ) )
188
- $activity_id = (int) bp_action_variable( 0 );
189
-
190
- // Not viewing a specific activity item.
191
- if ( empty( $activity_id ) )
192
- return false;
193
-
194
- // Is the current user allowed to spam items?
195
- if ( !bp_activity_user_can_mark_spam() )
196
- return false;
197
-
198
- // Load up the activity item.
199
- $activity = new BP_Activity_Activity( $activity_id );
200
- if ( empty( $activity->id ) )
201
- return false;
202
-
203
- // Check nonce.
204
- check_admin_referer( 'bp_activity_akismet_spam_' . $activity->id );
205
-
206
- /**
207
- * Fires before the marking activity as spam so plugins can modify things if they want to.
208
- *
209
- * @since 1.6.0
210
- *
211
- * @param int $activity_id Activity ID to be marked as spam.
212
- * @param object $activity Activity object for the ID to be marked as spam.
213
- */
214
- do_action( 'bp_activity_before_action_spam_activity', $activity->id, $activity );
215
-
216
- // Mark as spam.
217
- bp_activity_mark_as_spam( $activity );
218
- $activity->save();
219
-
220
- // Tell the user the spamming has been successful.
221
- bp_core_add_message( __( 'The activity item has been marked as spam and is no longer visible.', 'buddypress' ) );
222
-
223
- /**
224
- * Fires after the marking activity as spam so plugins can act afterwards based on the activity.
225
- *
226
- * @since 1.6.0
227
- *
228
- * @param int $activity_id Activity ID that was marked as spam.
229
- * @param int $user_id User ID associated with activity.
230
- */
231
- do_action( 'bp_activity_action_spam_activity', $activity_id, $activity->user_id );
232
-
233
- // Check for the redirect query arg, otherwise let WP handle things.
234
- if ( !empty( $_GET['redirect_to'] ) )
235
- bp_core_redirect( esc_url( $_GET['redirect_to'] ) );
236
- else
237
- bp_core_redirect( wp_get_referer() );
238
- }
239
- add_action( 'bp_actions', 'bp_activity_action_spam_activity' );
240
-
241
- /**
242
- * Post user/group activity update.
243
- *
244
- * @since 1.2.0
245
- *
246
- * @return bool False on failure.
247
- */
248
- function bp_activity_action_post_update() {
249
-
250
- // Do not proceed if user is not logged in, not viewing activity, or not posting.
251
- if ( !is_user_logged_in() || !bp_is_activity_component() || !bp_is_current_action( 'post' ) )
252
- return false;
253
-
254
- // Check the nonce.
255
- check_admin_referer( 'post_update', '_wpnonce_post_update' );
256
-
257
- /**
258
- * Filters the content provided in the activity input field.
259
- *
260
- * @since 1.2.0
261
- *
262
- * @param string $value Activity message being posted.
263
- */
264
- $content = apply_filters( 'bp_activity_post_update_content', $_POST['whats-new'] );
265
-
266
- if ( ! empty( $_POST['whats-new-post-object'] ) ) {
267
-
268
- /**
269
- * Filters the item type that the activity update should be associated with.
270
- *
271
- * @since 1.2.0
272
- *
273
- * @param string $value Item type to associate with.
274
- */
275
- $object = apply_filters( 'bp_activity_post_update_object', $_POST['whats-new-post-object'] );
276
- }
277
-
278
- if ( ! empty( $_POST['whats-new-post-in'] ) ) {
279
-
280
- /**
281
- * Filters what component the activity is being to.
282
- *
283
- * @since 1.2.0
284
- *
285
- * @param string $value Chosen component to post activity to.
286
- */
287
- $item_id = apply_filters( 'bp_activity_post_update_item_id', $_POST['whats-new-post-in'] );
288
- }
289
-
290
- // No activity content so provide feedback and redirect.
291
- if ( empty( $content ) ) {
292
- bp_core_add_message( __( 'Please enter some content to post.', 'buddypress' ), 'error' );
293
- bp_core_redirect( wp_get_referer() );
294
- }
295
-
296
- // No existing item_id.
297
- if ( empty( $item_id ) ) {
298
- $activity_id = bp_activity_post_update( array( 'content' => $content ) );
299
-
300
- // Post to groups object.
301
- } elseif ( 'groups' == $object && bp_is_active( 'groups' ) ) {
302
- if ( (int) $item_id ) {
303
- $activity_id = groups_post_update( array( 'content' => $content, 'group_id' => $item_id ) );
304
- }
305
-
306
- } else {
307
-
308
- /**
309
- * Filters activity object for BuddyPress core and plugin authors before posting activity update.
310
- *
311
- * @since 1.2.0
312
- *
313
- * @param string $object Activity item being associated to.
314
- * @param string $item_id Component ID being posted to.
315
- * @param string $content Activity content being posted.
316
- */
317
- $activity_id = apply_filters( 'bp_activity_custom_update', $object, $item_id, $content );
318
- }
319
-
320
- // Provide user feedback.
321
- if ( !empty( $activity_id ) )
322
- bp_core_add_message( __( 'Update Posted!', 'buddypress' ) );
323
- else
324
- bp_core_add_message( __( 'There was an error when posting your update. Please try again.', 'buddypress' ), 'error' );
325
-
326
- // Redirect.
327
- bp_core_redirect( wp_get_referer() );
328
- }
329
- add_action( 'bp_actions', 'bp_activity_action_post_update' );
330
-
331
- /**
332
- * Post new activity comment.
333
- *
334
- * @since 1.2.0
335
- *
336
- * @return bool False on failure.
337
- */
338
- function bp_activity_action_post_comment() {
339
-
340
- if ( !is_user_logged_in() || !bp_is_activity_component() || !bp_is_current_action( 'reply' ) )
341
- return false;
342
-
343
- // Check the nonce.
344
- check_admin_referer( 'new_activity_comment', '_wpnonce_new_activity_comment' );
345
-
346
- /**
347
- * Filters the activity ID a comment will be in reply to.
348
- *
349
- * @since 1.2.0
350
- *
351
- * @param string $value ID of the activity being replied to.
352
- */
353
- $activity_id = apply_filters( 'bp_activity_post_comment_activity_id', $_POST['comment_form_id'] );
354
-
355
- /**
356
- * Filters the comment content for a comment reply.
357
- *
358
- * @since 1.2.0
359
- *
360
- * @param string $value Comment content being posted.
361
- */
362
- $content = apply_filters( 'bp_activity_post_comment_content', $_POST['ac_input_' . $activity_id] );
363
-
364
- if ( empty( $content ) ) {
365
- bp_core_add_message( __( 'Please do not leave the comment area blank.', 'buddypress' ), 'error' );
366
- bp_core_redirect( wp_get_referer() . '#ac-form-' . $activity_id );
367
- }
368
-
369
- $comment_id = bp_activity_new_comment( array(
370
- 'content' => $content,
371
- 'activity_id' => $activity_id,
372
- 'parent_id' => false
373
- ));
374
-
375
- if ( !empty( $comment_id ) )
376
- bp_core_add_message( __( 'Reply Posted!', 'buddypress' ) );
377
- else
378
- bp_core_add_message( __( 'There was an error posting that reply. Please try again.', 'buddypress' ), 'error' );
379
-
380
- bp_core_redirect( wp_get_referer() . '#ac-form-' . $activity_id );
381
- }
382
- add_action( 'bp_actions', 'bp_activity_action_post_comment' );
383
-
384
- /**
385
- * Mark activity as favorite.
386
- *
387
- * @since 1.2.0
388
- *
389
- * @return bool False on failure.
390
- */
391
- function bp_activity_action_mark_favorite() {
392
-
393
- if ( !is_user_logged_in() || !bp_is_activity_component() || !bp_is_current_action( 'favorite' ) )
394
- return false;
395
-
396
- // Check the nonce.
397
- check_admin_referer( 'mark_favorite' );
398
-
399
- if ( bp_activity_add_user_favorite( bp_action_variable( 0 ) ) )
400
- bp_core_add_message( __( 'Activity marked as favorite.', 'buddypress' ) );
401
- else
402
- bp_core_add_message( __( 'There was an error marking that activity as a favorite. Please try again.', 'buddypress' ), 'error' );
403
-
404
- bp_core_redirect( wp_get_referer() . '#activity-' . bp_action_variable( 0 ) );
405
- }
406
- add_action( 'bp_actions', 'bp_activity_action_mark_favorite' );
407
-
408
- /**
409
- * Remove activity from favorites.
410
- *
411
- * @since 1.2.0
412
- *
413
- * @return bool False on failure.
414
- */
415
- function bp_activity_action_remove_favorite() {
416
-
417
- if ( ! is_user_logged_in() || ! bp_is_activity_component() || ! bp_is_current_action( 'unfavorite' ) )
418
- return false;
419
-
420
- // Check the nonce.
421
- check_admin_referer( 'unmark_favorite' );
422
-
423
- if ( bp_activity_remove_user_favorite( bp_action_variable( 0 ) ) )
424
- bp_core_add_message( __( 'Activity removed as favorite.', 'buddypress' ) );
425
- else
426
- bp_core_add_message( __( 'There was an error removing that activity as a favorite. Please try again.', 'buddypress' ), 'error' );
427
-
428
- bp_core_redirect( wp_get_referer() . '#activity-' . bp_action_variable( 0 ) );
429
- }
430
- add_action( 'bp_actions', 'bp_activity_action_remove_favorite' );
431
-
432
- /**
433
- * Load the sitewide activity feed.
434
- *
435
- * @since 1.0.0
436
- *
437
- * @return bool False on failure.
438
- */
439
- function bp_activity_action_sitewide_feed() {
440
- $bp = buddypress();
441
-
442
- if ( ! bp_is_activity_component() || ! bp_is_current_action( 'feed' ) || bp_is_user() || ! empty( $bp->groups->current_group ) )
443
- return false;
444
-
445
- // Setup the feed.
446
- buddypress()->activity->feed = new BP_Activity_Feed( array(
447
- 'id' => 'sitewide',
448
-
449
- /* translators: Sitewide activity RSS title - "[Site Name] | Site Wide Activity" */
450
- 'title' => sprintf( __( '%s | Site-Wide Activity', 'buddypress' ), bp_get_site_name() ),
451
-
452
- 'link' => bp_get_activity_directory_permalink(),
453
- 'description' => __( 'Activity feed for the entire site.', 'buddypress' ),
454
- 'activity_args' => 'display_comments=threaded'
455
- ) );
456
- }
457
- add_action( 'bp_actions', 'bp_activity_action_sitewide_feed' );
458
-
459
- /**
460
- * Load a user's personal activity feed.
461
- *
462
- * @since 1.0.0
463
- *
464
- * @return bool False on failure.
465
- */
466
- function bp_activity_action_personal_feed() {
467
- if ( ! bp_is_user_activity() || ! bp_is_current_action( 'feed' ) ) {
468
- return false;
469
- }
470
-
471
- // Setup the feed.
472
- buddypress()->activity->feed = new BP_Activity_Feed( array(
473
- 'id' => 'personal',
474
-
475
- /* translators: Personal activity RSS title - "[Site Name] | [User Display Name] | Activity" */
476
- 'title' => sprintf( __( '%1$s | %2$s | Activity', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
477
-
478
- 'link' => trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() ),
479
- 'description' => sprintf( __( 'Activity feed for %s.', 'buddypress' ), bp_get_displayed_user_fullname() ),
480
- 'activity_args' => 'user_id=' . bp_displayed_user_id()
481
- ) );
482
- }
483
- add_action( 'bp_actions', 'bp_activity_action_personal_feed' );
484
-
485
- /**
486
- * Load a user's friends' activity feed.
487
- *
488
- * @since 1.0.0
489
- *
490
- * @return bool False on failure.
491
- */
492
- function bp_activity_action_friends_feed() {
493
- if ( ! bp_is_active( 'friends' ) || ! bp_is_user_activity() || ! bp_is_current_action( bp_get_friends_slug() ) || ! bp_is_action_variable( 'feed', 0 ) ) {
494
- return false;
495
- }
496
-
497
- // Setup the feed.
498
- buddypress()->activity->feed = new BP_Activity_Feed( array(
499
- 'id' => 'friends',
500
-
501
- /* translators: Friends activity RSS title - "[Site Name] | [User Display Name] | Friends Activity" */
502
- 'title' => sprintf( __( '%1$s | %2$s | Friends Activity', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
503
-
504
- 'link' => trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_friends_slug() ),
505
- 'description' => sprintf( __( "Activity feed for %s's friends.", 'buddypress' ), bp_get_displayed_user_fullname() ),
506
- 'activity_args' => 'scope=friends'
507
- ) );
508
- }
509
- add_action( 'bp_actions', 'bp_activity_action_friends_feed' );
510
-
511
- /**
512
- * Load the activity feed for a user's groups.
513
- *
514
- * @since 1.2.0
515
- *
516
- * @return bool False on failure.
517
- */
518
- function bp_activity_action_my_groups_feed() {
519
- if ( ! bp_is_active( 'groups' ) || ! bp_is_user_activity() || ! bp_is_current_action( bp_get_groups_slug() ) || ! bp_is_action_variable( 'feed', 0 ) ) {
520
- return false;
521
- }
522
-
523
- // Get displayed user's group IDs.
524
- $groups = groups_get_user_groups();
525
- $group_ids = implode( ',', $groups['groups'] );
526
-
527
- // Setup the feed.
528
- buddypress()->activity->feed = new BP_Activity_Feed( array(
529
- 'id' => 'mygroups',
530
-
531
- /* translators: Member groups activity RSS title - "[Site Name] | [User Display Name] | Groups Activity" */
532
- 'title' => sprintf( __( '%1$s | %2$s | Group Activity', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
533
-
534
- 'link' => trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_groups_slug() ),
535
- 'description' => sprintf( __( "Public group activity feed of which %s is a member.", 'buddypress' ), bp_get_displayed_user_fullname() ),
536
- 'activity_args' => array(
537
- 'object' => buddypress()->groups->id,
538
- 'primary_id' => $group_ids,
539
- 'display_comments' => 'threaded'
540
- )
541
- ) );
542
- }
543
- add_action( 'bp_actions', 'bp_activity_action_my_groups_feed' );
544
-
545
- /**
546
- * Load a user's @mentions feed.
547
- *
548
- * @since 1.2.0
549
- *
550
- * @return bool False on failure.
551
- */
552
- function bp_activity_action_mentions_feed() {
553
- if ( ! bp_activity_do_mentions() ) {
554
- return false;
555
- }
556
-
557
- if ( !bp_is_user_activity() || ! bp_is_current_action( 'mentions' ) || ! bp_is_action_variable( 'feed', 0 ) ) {
558
- return false;
559
- }
560
-
561
- // Setup the feed.
562
- buddypress()->activity->feed = new BP_Activity_Feed( array(
563
- 'id' => 'mentions',
564
-
565
- /* translators: User mentions activity RSS title - "[Site Name] | [User Display Name] | Mentions" */
566
- 'title' => sprintf( __( '%1$s | %2$s | Mentions', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
567
-
568
- 'link' => bp_displayed_user_domain() . bp_get_activity_slug() . '/mentions/',
569
- 'description' => sprintf( __( "Activity feed mentioning %s.", 'buddypress' ), bp_get_displayed_user_fullname() ),
570
- 'activity_args' => array(
571
- 'search_terms' => '@' . bp_core_get_username( bp_displayed_user_id() )
572
- )
573
- ) );
574
- }
575
- add_action( 'bp_actions', 'bp_activity_action_mentions_feed' );
576
-
577
- /**
578
- * Load a user's favorites feed.
579
- *
580
- * @since 1.2.0
581
- *
582
- * @return bool False on failure.
583
- */
584
- function bp_activity_action_favorites_feed() {
585
- if ( ! bp_is_user_activity() || ! bp_is_current_action( 'favorites' ) || ! bp_is_action_variable( 'feed', 0 ) ) {
586
- return false;
587
- }
588
-
589
- // Get displayed user's favorite activity IDs.
590
- $favs = bp_activity_get_user_favorites( bp_displayed_user_id() );
591
- $fav_ids = implode( ',', (array) $favs );
592
-
593
- // Setup the feed.
594
- buddypress()->activity->feed = new BP_Activity_Feed( array(
595
- 'id' => 'favorites',
596
-
597
- /* translators: User activity favorites RSS title - "[Site Name] | [User Display Name] | Favorites" */
598
- 'title' => sprintf( __( '%1$s | %2$s | Favorites', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
599
-
600
- 'link' => bp_displayed_user_domain() . bp_get_activity_slug() . '/favorites/',
601
- 'description' => sprintf( __( "Activity feed of %s's favorites.", 'buddypress' ), bp_get_displayed_user_fullname() ),
602
- 'activity_args' => 'include=' . $fav_ids
603
- ) );
604
- }
605
- add_action( 'bp_actions', 'bp_activity_action_favorites_feed' );
606
-
607
- /**
608
- * AJAX endpoint for Suggestions API lookups.
609
- *
610
- * @since 2.1.0
611
- */
612
- function bp_ajax_get_suggestions() {
613
- if ( ! bp_is_user_active() || empty( $_GET['term'] ) || empty( $_GET['type'] ) ) {
614
- wp_send_json_error( 'missing_parameter' );
615
- exit;
616
- }
617
-
618
- $args = array(
619
- 'term' => sanitize_text_field( $_GET['term'] ),
620
- 'type' => sanitize_text_field( $_GET['type'] ),
621
- );
622
-
623
- // Support per-Group suggestions.
624
- if ( ! empty( $_GET['group-id'] ) ) {
625
- $args['group_id'] = absint( $_GET['group-id'] );
626
- }
627
-
628
- $results = bp_core_get_suggestions( $args );
629
-
630
- if ( is_wp_error( $results ) ) {
631
- wp_send_json_error( $results->get_error_message() );
632
- exit;
633
- }
634
-
635
- wp_send_json_success( $results );
636
- }
637
- add_action( 'wp_ajax_bp_get_suggestions', 'bp_ajax_get_suggestions' );
638
-
639
- /**
640
- * Detect a change in post type status, and initiate an activity update if necessary.
641
- *
642
- * @since 2.2.0
643
- *
644
- * @todo Support untrashing better.
645
- *
646
- * @param string $new_status New status for the post.
647
- * @param string $old_status Old status for the post.
648
- * @param object $post Post data.
649
- */
650
- function bp_activity_catch_transition_post_type_status( $new_status, $old_status, $post ) {
651
- if ( ! post_type_supports( $post->post_type, 'buddypress-activity' ) ) {
652
- return;
653
- }
654
-
655
- // This is an edit.
656
- if ( $new_status === $old_status ) {
657
- // An edit of an existing post should update the existing activity item.
658
- if ( $new_status == 'publish' ) {
659
- $edit = bp_activity_post_type_update( $post );
660
-
661
- // Post was never recorded into activity stream, so record it now!
662
- if ( null === $edit ) {
663
- bp_activity_post_type_publish( $post->ID, $post );
664
- }
665
-
666
- // Allow plugins to eventually deal with other post statuses.
667
- } else {
668
- /**
669
- * Fires when editing the post and the new status is not 'publish'.
670
- *
671
- * This is a variable filter that is dependent on the post type
672
- * being untrashed.
673
- *
674
- * @since 2.5.0
675
- *
676
- * @param WP_Post $post Post data.
677
- * @param string $new_status New status for the post.
678
- * @param string $old_status Old status for the post.
679
- */
680
- do_action( 'bp_activity_post_type_edit_' . $post->post_type, $post, $new_status, $old_status );
681
- }
682
-
683
- return;
684
- }
685
-
686
- // Publishing a previously unpublished post.
687
- if ( 'publish' === $new_status ) {
688
- // Untrashing the post type - nothing here yet.
689
- if ( 'trash' == $old_status ) {
690
-
691
- /**
692
- * Fires if untrashing post in a post type.
693
- *
694
- * This is a variable filter that is dependent on the post type
695
- * being untrashed.
696
- *
697
- * @since 2.2.0
698
- *
699
- * @param WP_Post $post Post data.
700
- */
701
- do_action( 'bp_activity_post_type_untrash_' . $post->post_type, $post );
702
- } else {
703
- // Record the post.
704
- bp_activity_post_type_publish( $post->ID, $post );
705
- }
706
-
707
- // Unpublishing a previously published post.
708
- } elseif ( 'publish' === $old_status ) {
709
- // Some form of pending status - only remove the activity entry.
710
- bp_activity_post_type_unpublish( $post->ID, $post );
711
-
712
- // For any other cases, allow plugins to eventually deal with it.
713
- } else {
714
- /**
715
- * Fires when the old and the new post status are not 'publish'.
716
- *
717
- * This is a variable filter that is dependent on the post type
718
- * being untrashed.
719
- *
720
- * @since 2.5.0
721
- *
722
- * @param WP_Post $post Post data.
723
- * @param string $new_status New status for the post.
724
- * @param string $old_status Old status for the post.
725
- */
726
- do_action( 'bp_activity_post_type_transition_status_' . $post->post_type, $post, $new_status, $old_status );
727
- }
728
- }
729
- add_action( 'transition_post_status', 'bp_activity_catch_transition_post_type_status', 10, 3 );
730
-
731
- /**
732
- * When a post type comment status transition occurs, update the relevant activity's status.
733
- *
734
- * @since 2.5.0
735
- *
736
- * @param string $new_status New comment status.
737
- * @param string $old_status Previous comment status.
738
- * @param WP_Comment $comment Comment data.
739
- */
740
- function bp_activity_transition_post_type_comment_status( $new_status, $old_status, $comment ) {
741
- $post_type = get_post_type( $comment->comment_post_ID );
742
- if ( ! $post_type ) {
743
- return;
744
- }
745
-
746
- // Get the post type tracking args.
747
- $activity_post_object = bp_activity_get_post_type_tracking_args( $post_type );
748
-
749
- // Bail if the activity type does not exist
750
- if ( empty( $activity_post_object->comments_tracking->action_id ) ) {
751
- return false;
752
-
753
- // Set the $activity_comment_object
754
- } else {
755
- $activity_comment_object = $activity_post_object->comments_tracking;
756
- }
757
-
758
- // Init an empty activity ID
759
- $activity_id = 0;
760
-
761
- /**
762
- * Activity currently doesn't have any concept of a trash, or an unapproved/approved state.
763
- *
764
- * If a blog comment transitions to a "delete" or "hold" status, delete the activity item.
765
- * If a blog comment transitions to trashed, or spammed, mark the activity as spam.
766
- * If a blog comment transitions to approved (and the activity exists), mark the activity as ham.
767
- * If a blog comment transitions to unapproved (and the activity exists), mark the activity as spam.
768
- * Otherwise, record the comment into the activity stream.
769
- */
770
-
771
- // This clause handles delete/hold.
772
- if ( in_array( $new_status, array( 'delete', 'hold' ) ) ) {
773
- return bp_activity_post_type_remove_comment( $comment->comment_ID, $activity_post_object );
774
-
775
- // These clauses handle trash, spam, and un-spams.
776
- } elseif ( in_array( $new_status, array( 'trash', 'spam', 'unapproved' ) ) ) {
777
- $action = 'spam_activity';
778
- } elseif ( 'approved' == $new_status ) {
779
- $action = 'ham_activity';
780
- }
781
-
782
- // Get the activity
783
- if ( bp_disable_blogforum_comments() ) {
784
- $activity_id = bp_activity_get_activity_id( array(
785
- 'component' => $activity_comment_object->component_id,
786
- 'item_id' => get_current_blog_id(),
787
- 'secondary_item_id' => $comment->comment_ID,
788
- 'type' => $activity_comment_object->action_id,
789
- ) );
790
- } else {
791
- $activity_id = get_comment_meta( $comment->comment_ID, 'bp_activity_comment_id', true );
792
- }
793
-
794
- /**
795
- * Leave a chance to plugins to manage activity comments differently.
796
- *
797
- * @since 2.5.0
798
- *
799
- * @param bool $value True to override BuddyPress management.
800
- * @param string $post_type The post type name.
801
- * @param int $activity_id The post type activity (0 if not found).
802
- * @param string $new_status The new status of the post type comment.
803
- * @param string $old_status The old status of the post type comment.
804
- * @param WP_Comment $comment Comment data.
805
- */
806
- if ( true === apply_filters( 'bp_activity_pre_transition_post_type_comment_status', false, $post_type, $activity_id, $new_status, $old_status, $comment ) ) {
807
- return false;
808
- }
809
-
810
- // Check activity item exists
811
- if ( empty( $activity_id ) ) {
812
- // If no activity exists, but the comment has been approved, record it into the activity table.
813
- if ( 'approved' == $new_status ) {
814
- return bp_activity_post_type_comment( $comment->comment_ID, true, $activity_post_object );
815
- }
816
-
817
- return;
818
- }
819
-
820
- // Create an activity object
821
- $activity = new BP_Activity_Activity( $activity_id );
822
- if ( empty( $activity->component ) ) {
823
- return;
824
- }
825
-
826
- // Spam/ham the activity if it's not already in that state
827
- if ( 'spam_activity' === $action && ! $activity->is_spam ) {
828
- bp_activity_mark_as_spam( $activity );
829
- } elseif ( 'ham_activity' == $action) {
830
- bp_activity_mark_as_ham( $activity );
831
- }
832
-
833
- // Add "new_post_type_comment" to the whitelisted activity types, so that the activity's Akismet history is generated
834
- $post_type_comment_action = $activity_comment_object->action_id;
835
- $comment_akismet_history = function ( $activity_types ) use ( $post_type_comment_action ) {
836
- $activity_types[] = $post_type_comment_action;
837
-
838
- return $activity_types;
839
- };
840
- add_filter( 'bp_akismet_get_activity_types', $comment_akismet_history );
841
-
842
- // Make sure the activity change won't edit the comment if sync is on
843
- remove_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
844
-
845
- // Save the updated activity
846
- $activity->save();
847
-
848
- // Restore the action
849
- add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
850
-
851
- // Remove the "new_blog_comment" activity type whitelist so we don't break anything
852
- remove_filter( 'bp_akismet_get_activity_types', $comment_akismet_history );
853
- }
854
- add_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10, 3 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/bp-activity-admin.php DELETED
@@ -1,1066 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Activity component admin screen.
4
- *
5
- * Props to WordPress core for the Comments admin screen, and its contextual
6
- * help text, on which this implementation is heavily based.
7
- *
8
- * @package BuddyPress
9
- * @subpackage ActivityAdmin
10
- * @since 1.6.0
11
- */
12
-
13
- // Exit if accessed directly.
14
- defined( 'ABSPATH' ) || exit;
15
-
16
- // Include WP's list table class.
17
- if ( !class_exists( 'WP_List_Table' ) ) require( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
18
-
19
- // Per_page screen option. Has to be hooked in extremely early.
20
- if ( is_admin() && ! empty( $_REQUEST['page'] ) && 'bp-activity' == $_REQUEST['page'] )
21
- add_filter( 'set-screen-option', 'bp_activity_admin_screen_options', 10, 3 );
22
-
23
- /**
24
- * Register the Activity component admin screen.
25
- *
26
- * @since 1.6.0
27
- */
28
- 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',
37
- 'div'
38
- );
39
-
40
- // Hook into early actions to load custom CSS and our init handler.
41
- add_action( "load-$hook", 'bp_activity_admin_load' );
42
- }
43
- add_action( bp_core_admin_hook(), 'bp_activity_add_admin_menu' );
44
-
45
- /**
46
- * Add activity component to custom menus array.
47
- *
48
- * Several BuddyPress components have top-level menu items in the Dashboard,
49
- * which all appear together in the middle of the Dashboard menu. This function
50
- * adds the Activity page to the array of these menu items.
51
- *
52
- * @since 1.7.0
53
- *
54
- * @param array $custom_menus The list of top-level BP menu items.
55
- * @return array $custom_menus List of top-level BP menu items, with Activity added.
56
- */
57
- function bp_activity_admin_menu_order( $custom_menus = array() ) {
58
- array_push( $custom_menus, 'bp-activity' );
59
- return $custom_menus;
60
- }
61
- add_filter( 'bp_admin_menu_order', 'bp_activity_admin_menu_order' );
62
-
63
- /**
64
- * AJAX receiver for Activity replies via the admin screen.
65
- *
66
- * Processes requests to add new activity comments, and echoes HTML for a new
67
- * table row.
68
- *
69
- * @since 1.6.0
70
- */
71
- function bp_activity_admin_reply() {
72
- // Check nonce.
73
- check_ajax_referer( 'bp-activity-admin-reply', '_ajax_nonce-bp-activity-admin-reply' );
74
-
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
-
82
- // If $root_id not set (e.g. for root items), use $parent_id.
83
- if ( empty( $root_id ) )
84
- $root_id = $parent_id;
85
-
86
- // Check that a reply has been entered.
87
- if ( empty( $_REQUEST['content'] ) )
88
- die( __( 'ERROR: Please type a reply.', 'buddypress' ) );
89
-
90
- // Check parent activity exists.
91
- $parent_activity = new BP_Activity_Activity( $parent_id );
92
- if ( empty( $parent_activity->component ) )
93
- die( __( 'ERROR: The item you are trying to reply to cannot be found, or it has been deleted.', 'buddypress' ) );
94
-
95
- // @todo: Check if user is allowed to create new activity items
96
- // if ( ! current_user_can( 'bp_new_activity' ) )
97
- if ( ! current_user_can( 'bp_moderate' ) )
98
- die( '-1' );
99
-
100
- // Add new activity comment.
101
- $new_activity_id = bp_activity_new_comment( array(
102
- 'activity_id' => $root_id, // ID of the root activity item.
103
- 'content' => $_REQUEST['content'],
104
- 'parent_id' => $parent_id, // ID of a parent comment.
105
- ) );
106
-
107
- // Fetch the new activity item, as we need it to create table markup to return.
108
- $new_activity = new BP_Activity_Activity( $new_activity_id );
109
-
110
- // This needs to be set for the BP_Activity_List_Table constructor to work.
111
- set_current_screen( 'toplevel_page_bp-activity' );
112
-
113
- // Set up an output buffer.
114
- ob_start();
115
- $list_table = new BP_Activity_List_Table();
116
- $list_table->single_row( (array) $new_activity );
117
-
118
- // Get table markup.
119
- $response = array(
120
- 'data' => ob_get_contents(),
121
- 'id' => $new_activity_id,
122
- 'position' => -1,
123
- 'what' => 'bp_activity',
124
- );
125
- ob_end_clean();
126
-
127
- // Send response.
128
- $r = new WP_Ajax_Response();
129
- $r->add( $response );
130
- $r->send();
131
-
132
- exit();
133
- }
134
- add_action( 'wp_ajax_bp-activity-admin-reply', 'bp_activity_admin_reply' );
135
-
136
- /**
137
- * Handle save/update of screen options for the Activity component admin screen.
138
- *
139
- * @since 1.6.0
140
- *
141
- * @param string $value Will always be false unless another plugin filters it first.
142
- * @param string $option Screen option name.
143
- * @param string $new_value Screen option form value.
144
- * @return string|int Option value. False to abandon update.
145
- */
146
- function bp_activity_admin_screen_options( $value, $option, $new_value ) {
147
- if ( 'toplevel_page_bp_activity_per_page' != $option && 'toplevel_page_bp_activity_network_per_page' != $option )
148
- return $value;
149
-
150
- // Per page.
151
- $new_value = (int) $new_value;
152
- if ( $new_value < 1 || $new_value > 999 )
153
- return $value;
154
-
155
- return $new_value;
156
- }
157
-
158
- /**
159
- * Hide the advanced edit meta boxes by default, so we don't clutter the screen.
160
- *
161
- * @since 1.6.0
162
- *
163
- * @param array $hidden Array of items to hide.
164
- * @param WP_Screen $screen Screen identifier.
165
- * @return array Hidden Meta Boxes.
166
- */
167
- function bp_activity_admin_edit_hidden_metaboxes( $hidden, $screen ) {
168
- if ( empty( $screen->id ) || 'toplevel_page_bp-activity' !== $screen->id && 'toplevel_page_bp-activity-network' !== $screen->id ) {
169
- return $hidden;
170
- }
171
-
172
- // Hide the primary link meta box by default.
173
- $hidden = array_merge( (array) $hidden, array( 'bp_activity_itemids', 'bp_activity_link', 'bp_activity_type', 'bp_activity_userid', ) );
174
-
175
- /**
176
- * Filters default hidden metaboxes so plugins can alter list.
177
- *
178
- * @since 1.6.0
179
- *
180
- * @param array $hidden Default metaboxes to hide.
181
- * @param WP_Screen $screen Screen identifier.
182
- */
183
- return apply_filters( 'bp_hide_meta_boxes', array_unique( $hidden ), $screen );
184
- }
185
- add_filter( 'default_hidden_meta_boxes', 'bp_activity_admin_edit_hidden_metaboxes', 10, 2 );
186
-
187
- /**
188
- * Set up the Activity admin page.
189
- *
190
- * Does the following:
191
- * - Register contextual help and screen options for this admin page.
192
- * - Enqueues scripts and styles.
193
- * - Catches POST and GET requests related to Activity.
194
- *
195
- * @since 1.6.0
196
- *
197
- * @global object $bp BuddyPress global settings.
198
- * @global BP_Activity_List_Table $bp_activity_list_table Activity screen list table.
199
- */
200
- function bp_activity_admin_load() {
201
- global $bp_activity_list_table;
202
-
203
- $bp = buddypress();
204
- $doaction = bp_admin_list_table_current_bulk_action();
205
- $min = bp_core_get_minified_asset_suffix();
206
-
207
- /**
208
- * Fires at top of Activity admin page.
209
- *
210
- * @since 1.6.0
211
- *
212
- * @param string $doaction Current $_GET action being performed in admin screen.
213
- */
214
- do_action( 'bp_activity_admin_load', $doaction );
215
-
216
- // Edit screen.
217
- if ( 'edit' == $doaction && ! empty( $_GET['aid'] ) ) {
218
- // Columns screen option.
219
- add_screen_option( 'layout_columns', array( 'default' => 2, 'max' => 2, ) );
220
-
221
- get_current_screen()->add_help_tab( array(
222
- 'id' => 'bp-activity-edit-overview',
223
- 'title' => __( 'Overview', 'buddypress' ),
224
- 'content' =>
225
- '<p>' . __( 'You edit activities made on your site similar to the way you edit a comment. This is useful if you need to change which page the activity links to, or when you notice that the author has made a typographical error.', 'buddypress' ) . '</p>' .
226
- '<p>' . __( 'The two big editing areas for the activity title and content are fixed in place, but you can reposition all the other boxes using drag and drop, and can minimize or expand them by clicking the title bar of each box. Use the Screen Options tab to unhide more boxes (Primary Item/Secondary Item, Link, Type, Author ID) or to choose a 1- or 2-column layout for this screen.', 'buddypress' ) . '</p>' .
227
- '<p>' . __( 'You can also moderate the activity from this screen using the Status box, where you can also change the timestamp of the activity.', 'buddypress' ) . '</p>'
228
- ) );
229
-
230
- get_current_screen()->add_help_tab( array(
231
- 'id' => 'bp-activity-edit-advanced',
232
- 'title' => __( 'Item, Link, Type', 'buddypress' ),
233
- 'content' =>
234
- '<p>' . __( '<strong>Primary Item/Secondary Item</strong> - These identify the object that created the activity. For example, the fields could reference a comment left on a specific site. Some types of activity may only use one, or none, of these fields.', 'buddypress' ) . '</p>' .
235
- '<p>' . __( '<strong>Link</strong> - Used by some types of activity (e.g blog posts and comments, and forum topics and replies) to store a link back to the original content.', 'buddypress' ) . '</p>' .
236
- '<p>' . __( '<strong>Type</strong> - Each distinct kind of activity has its own type. For example, <code>created_group</code> is used when a group is created and <code>joined_group</code> is used when a user joins a group.', 'buddypress' ) . '</p>' .
237
- '<p>' . __( 'For information about when and how BuddyPress uses all of these settings, see the Managing Activity link in the panel to the side.', 'buddypress' ) . '</p>'
238
- ) );
239
-
240
- // Help panel - sidebar links.
241
- get_current_screen()->set_help_sidebar(
242
- '<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
243
- '<p>' . __( '<a href="https://codex.buddypress.org/administrator-guide/activity-stream-management-panels/">Managing Activity</a>', 'buddypress' ) . '</p>' .
244
- '<p>' . __( '<a href="https://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
245
- );
246
-
247
- // Register metaboxes for the edit screen.
248
- add_meta_box( 'submitdiv', _x( 'Status', 'activity admin edit screen', 'buddypress' ), 'bp_activity_admin_edit_metabox_status', get_current_screen()->id, 'side', 'core' );
249
- add_meta_box( 'bp_activity_itemids', _x( 'Primary Item/Secondary Item', 'activity admin edit screen', 'buddypress' ), 'bp_activity_admin_edit_metabox_itemids', get_current_screen()->id, 'normal', 'core' );
250
- add_meta_box( 'bp_activity_link', _x( 'Link', 'activity admin edit screen', 'buddypress' ), 'bp_activity_admin_edit_metabox_link', get_current_screen()->id, 'normal', 'core' );
251
- add_meta_box( 'bp_activity_type', _x( 'Type', 'activity admin edit screen', 'buddypress' ), 'bp_activity_admin_edit_metabox_type', get_current_screen()->id, 'normal', 'core' );
252
- add_meta_box( 'bp_activity_userid', _x( 'Author ID', 'activity admin edit screen', 'buddypress' ), 'bp_activity_admin_edit_metabox_userid', get_current_screen()->id, 'normal', 'core' );
253
-
254
- /**
255
- * Fires after the registration of all of the default activity meta boxes.
256
- *
257
- * @since 2.4.0
258
- */
259
- do_action( 'bp_activity_admin_meta_boxes' );
260
-
261
- // Enqueue JavaScript files.
262
- wp_enqueue_script( 'postbox' );
263
- wp_enqueue_script( 'dashboard' );
264
- wp_enqueue_script( 'comment' );
265
-
266
- // Index screen.
267
- } else {
268
- // Create the Activity screen list table.
269
- $bp_activity_list_table = new BP_Activity_List_Table();
270
-
271
- // The per_page screen option.
272
- add_screen_option( 'per_page', array( 'label' => _x( 'Activity', 'Activity items per page (screen options)', 'buddypress' )) );
273
-
274
- // Help panel - overview text.
275
- get_current_screen()->add_help_tab( array(
276
- 'id' => 'bp-activity-overview',
277
- 'title' => __( 'Overview', 'buddypress' ),
278
- 'content' =>
279
- '<p>' . __( 'You can manage activities made on your site similar to the way you manage comments and other content. This screen is customizable in the same ways as other management screens, and you can act on activities using the on-hover action links or the Bulk Actions.', 'buddypress' ) . '</p>' .
280
- '<p>' . __( 'There are many different types of activities. Some are generated automatically by BuddyPress and other plugins, and some are entered directly by a user in the form of status update. To help manage the different activity types, use the filter dropdown box to switch between them.', 'buddypress' ) . '</p>'
281
- ) );
282
-
283
- // Help panel - moderation text.
284
- get_current_screen()->add_help_tab( array(
285
- 'id' => 'bp-activity-moderating',
286
- 'title' => __( 'Moderating Activity', 'buddypress' ),
287
- 'content' =>
288
- '<p>' . __( 'In the <strong>Activity</strong> column, above each activity it says &#8220;Submitted on,&#8221; followed by the date and time the activity item was generated on your site. Clicking on the date/time link will take you to that activity on your live site. Hovering over any activity gives you options to reply, edit, spam mark, or delete that activity.', 'buddypress' ) . '</p>' .
289
- '<p>' . __( "In the <strong>In Response To</strong> column, if the activity was in reply to another activity, it shows that activity's author's picture and name, and a link to that activity on your live site. If there is a small bubble, the number in it shows how many other activities are related to this one; these are usually comments. Clicking the bubble will filter the activity screen to show only related activity items.", 'buddypress' ) . '</p>'
290
- ) );
291
-
292
- // Help panel - sidebar links.
293
- get_current_screen()->set_help_sidebar(
294
- '<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
295
- '<p>' . __( '<a href="https://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
296
- );
297
-
298
- // Add accessible hidden heading and text for Activity screen pagination.
299
- if ( bp_get_major_wp_version() >= 4.4 ) {
300
- get_current_screen()->set_screen_reader_content( array(
301
- /* translators: accessibility text */
302
- 'heading_pagination' => __( 'Activity list navigation', 'buddypress' ),
303
- ) );
304
- }
305
- }
306
-
307
- // Enqueue CSS and JavaScript.
308
- wp_enqueue_script( 'bp_activity_admin_js', $bp->plugin_url . "bp-activity/admin/js/admin{$min}.js", array( 'jquery', 'wp-ajax-response' ), bp_get_version(), true );
309
- wp_localize_script( 'bp_activity_admin_js', 'bp_activity_admin_vars', array(
310
- 'page' => get_current_screen()->id
311
- ) );
312
- wp_enqueue_style( 'bp_activity_admin_css', $bp->plugin_url . "bp-activity/admin/css/admin{$min}.css", array(), bp_get_version() );
313
-
314
- wp_style_add_data( 'bp_activity_admin_css', 'rtl', true );
315
- if ( $min ) {
316
- wp_style_add_data( 'bp_activity_admin_css', 'suffix', $min );
317
- }
318
-
319
- /**
320
- * Fires after the activity js and style has been enqueued.
321
- *
322
- * @since 2.4.0
323
- */
324
- do_action( 'bp_activity_admin_enqueue_scripts' );
325
-
326
- // Handle spam/un-spam/delete of activities.
327
- if ( !empty( $doaction ) && ! in_array( $doaction, array( '-1', 'edit', 'save', ) ) ) {
328
-
329
- // Build redirection URL.
330
- $redirect_to = remove_query_arg( array( 'aid', 'deleted', 'error', 'spammed', 'unspammed', ), wp_get_referer() );
331
- $redirect_to = add_query_arg( 'paged', $bp_activity_list_table->get_pagenum(), $redirect_to );
332
-
333
- // Get activity IDs.
334
- $activity_ids = array_map( 'absint', (array) $_REQUEST['aid'] );
335
-
336
- /**
337
- * Filters list of IDs being spammed/un-spammed/deleted.
338
- *
339
- * @since 1.6.0
340
- *
341
- * @param array $activity_ids Activity IDs to spam/un-spam/delete.
342
- */
343
- $activity_ids = apply_filters( 'bp_activity_admin_action_activity_ids', $activity_ids );
344
-
345
- // Is this a bulk request?
346
- if ( 'bulk_' == substr( $doaction, 0, 5 ) && ! empty( $_REQUEST['aid'] ) ) {
347
- // Check this is a valid form submission.
348
- check_admin_referer( 'bulk-activities' );
349
-
350
- // Trim 'bulk_' off the action name to avoid duplicating a ton of code.
351
- $doaction = substr( $doaction, 5 );
352
-
353
- // This is a request to delete, spam, or un-spam, a single item.
354
- } elseif ( !empty( $_REQUEST['aid'] ) ) {
355
-
356
- // Check this is a valid form submission.
357
- check_admin_referer( 'spam-activity_' . $activity_ids[0] );
358
- }
359
-
360
- // Initialise counters for how many of each type of item we perform an action on.
361
- $deleted = $spammed = $unspammed = 0;
362
-
363
- // Store any errors that occurs when updating the database items.
364
- $errors = array();
365
-
366
- // "We'd like to shoot the monster, could you move, please?"
367
- foreach ( $activity_ids as $activity_id ) {
368
- // @todo: Check the permissions on each
369
- // if ( ! current_user_can( 'bp_edit_activity', $activity_id ) )
370
- // continue;
371
- // Get the activity from the database.
372
- $activity = new BP_Activity_Activity( $activity_id );
373
- if ( empty( $activity->component ) ) {
374
- $errors[] = $activity_id;
375
- continue;
376
- }
377
-
378
- switch ( $doaction ) {
379
- case 'delete' :
380
- if ( 'activity_comment' == $activity->type )
381
- bp_activity_delete_comment( $activity->item_id, $activity->id );
382
- else
383
- bp_activity_delete( array( 'id' => $activity->id ) );
384
-
385
- $deleted++;
386
- break;
387
-
388
- case 'ham' :
389
- /**
390
- * Remove moderation and blacklist checks in case we want to ham an activity
391
- * which contains one of these listed keys.
392
- */
393
- remove_action( 'bp_activity_before_save', 'bp_activity_check_moderation_keys', 2 );
394
- remove_action( 'bp_activity_before_save', 'bp_activity_check_blacklist_keys', 2 );
395
-
396
- bp_activity_mark_as_ham( $activity );
397
- $result = $activity->save();
398
-
399
- // Check for any error during activity save.
400
- if ( ! $result )
401
- $errors[] = $activity->id;
402
- else
403
- $unspammed++;
404
- break;
405
-
406
- case 'spam' :
407
- bp_activity_mark_as_spam( $activity );
408
- $result = $activity->save();
409
-
410
- // Check for any error during activity save.
411
- if ( ! $result )
412
- $errors[] = $activity->id;
413
- else
414
- $spammed++;
415
- break;
416
-
417
- default:
418
- break;
419
- }
420
-
421
- // Release memory.
422
- unset( $activity );
423
- }
424
-
425
- /**
426
- * Fires before redirect for plugins to do something with activity.
427
- *
428
- * Passes an activity array counts how many were spam, not spam, deleted, and IDs that were errors.
429
- *
430
- * @since 1.6.0
431
- *
432
- * @param array $value Array holding spam, not spam, deleted counts, error IDs.
433
- * @param string $redirect_to URL to redirect to.
434
- * @param array $activity_ids Original array of activity IDs.
435
- */
436
- do_action( 'bp_activity_admin_action_after', array( $spammed, $unspammed, $deleted, $errors ), $redirect_to, $activity_ids );
437
-
438
- // Add arguments to the redirect URL so that on page reload, we can easily display what we've just done.
439
- if ( $spammed )
440
- $redirect_to = add_query_arg( 'spammed', $spammed, $redirect_to );
441
-
442
- if ( $unspammed )
443
- $redirect_to = add_query_arg( 'unspammed', $unspammed, $redirect_to );
444
-
445
- if ( $deleted )
446
- $redirect_to = add_query_arg( 'deleted', $deleted, $redirect_to );
447
-
448
- // If an error occurred, pass back the activity ID that failed.
449
- if ( ! empty( $errors ) )
450
- $redirect_to = add_query_arg( 'error', implode ( ',', array_map( 'absint', $errors ) ), $redirect_to );
451
-
452
- /**
453
- * Filters redirect URL after activity spamming/un-spamming/deletion occurs.
454
- *
455
- * @since 1.6.0
456
- *
457
- * @param string $redirect_to URL to redirect to.
458
- */
459
- wp_redirect( apply_filters( 'bp_activity_admin_action_redirect', $redirect_to ) );
460
- exit;
461
-
462
-
463
- // Save the edit.
464
- } elseif ( $doaction && 'save' == $doaction ) {
465
- // Build redirection URL.
466
- $redirect_to = remove_query_arg( array( 'action', 'aid', 'deleted', 'error', 'spammed', 'unspammed', ), $_SERVER['REQUEST_URI'] );
467
-
468
- // Get activity ID.
469
- $activity_id = (int) $_REQUEST['aid'];
470
-
471
- // Check this is a valid form submission.
472
- check_admin_referer( 'edit-activity_' . $activity_id );
473
-
474
- // Get the activity from the database.
475
- $activity = new BP_Activity_Activity( $activity_id );
476
-
477
- // If the activity doesn't exist, just redirect back to the index.
478
- if ( empty( $activity->component ) ) {
479
- wp_redirect( $redirect_to );
480
- exit;
481
- }
482
-
483
- // Check the form for the updated properties.
484
- // Store any error that occurs when updating the database item.
485
- $error = 0;
486
-
487
- // Activity spam status.
488
- $prev_spam_status = $new_spam_status = false;
489
- if ( ! empty( $_POST['activity_status'] ) ) {
490
- $prev_spam_status = $activity->is_spam;
491
- $new_spam_status = ( 'spam' == $_POST['activity_status'] ) ? true : false;
492
- }
493
-
494
- // Activity action.
495
- if ( isset( $_POST['bp-activities-action'] ) )
496
- $activity->action = $_POST['bp-activities-action'];
497
-
498
- // Activity content.
499
- if ( isset( $_POST['bp-activities-content'] ) )
500
- $activity->content = $_POST['bp-activities-content'];
501
-
502
- // Activity primary link.
503
- if ( ! empty( $_POST['bp-activities-link'] ) )
504
- $activity->primary_link = $_POST['bp-activities-link'];
505
-
506
- // Activity user ID.
507
- if ( ! empty( $_POST['bp-activities-userid'] ) )
508
- $activity->user_id = (int) $_POST['bp-activities-userid'];
509
-
510
- // Activity item primary ID.
511
- if ( isset( $_POST['bp-activities-primaryid'] ) )
512
- $activity->item_id = (int) $_POST['bp-activities-primaryid'];
513
-
514
- // Activity item secondary ID.
515
- if ( isset( $_POST['bp-activities-secondaryid'] ) )
516
- $activity->secondary_item_id = (int) $_POST['bp-activities-secondaryid'];
517
-
518
- // Activity type.
519
- if ( ! empty( $_POST['bp-activities-type'] ) ) {
520
- $actions = bp_activity_admin_get_activity_actions();
521
-
522
- // Check that the new type is a registered activity type.
523
- if ( in_array( $_POST['bp-activities-type'], $actions ) ) {
524
- $activity->type = $_POST['bp-activities-type'];
525
- }
526
- }
527
-
528
- // Activity timestamp.
529
- if ( ! empty( $_POST['aa'] ) && ! empty( $_POST['mm'] ) && ! empty( $_POST['jj'] ) && ! empty( $_POST['hh'] ) && ! empty( $_POST['mn'] ) && ! empty( $_POST['ss'] ) ) {
530
- $aa = $_POST['aa'];
531
- $mm = $_POST['mm'];
532
- $jj = $_POST['jj'];
533
- $hh = $_POST['hh'];
534
- $mn = $_POST['mn'];
535
- $ss = $_POST['ss'];
536
- $aa = ( $aa <= 0 ) ? date( 'Y' ) : $aa;
537
- $mm = ( $mm <= 0 ) ? date( 'n' ) : $mm;
538
- $jj = ( $jj > 31 ) ? 31 : $jj;
539
- $jj = ( $jj <= 0 ) ? date( 'j' ) : $jj;
540
- $hh = ( $hh > 23 ) ? $hh -24 : $hh;
541
- $mn = ( $mn > 59 ) ? $mn -60 : $mn;
542
- $ss = ( $ss > 59 ) ? $ss -60 : $ss;
543
-
544
- // Reconstruct the date into a timestamp.
545
- $gmt_date = sprintf( "%04d-%02d-%02d %02d:%02d:%02d", $aa, $mm, $jj, $hh, $mn, $ss );
546
-
547
- $activity->date_recorded = $gmt_date;
548
- }
549
-
550
- // Has the spam status has changed?
551
- if ( $new_spam_status != $prev_spam_status ) {
552
- if ( $new_spam_status )
553
- bp_activity_mark_as_spam( $activity );
554
- else
555
- bp_activity_mark_as_ham( $activity );
556
- }
557
-
558
- // Save.
559
- $result = $activity->save();
560
-
561
- // Clear the activity stream first page cache, in case this activity's timestamp was changed.
562
- wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
563
-
564
- // Check for any error during activity save.
565
- if ( false === $result )
566
- $error = $activity->id;
567
-
568
- /**
569
- * Fires before redirect so plugins can do something first on save action.
570
- *
571
- * @since 1.6.0
572
- *
573
- * @param array $value Array holding activity object and ID that holds error.
574
- */
575
- do_action_ref_array( 'bp_activity_admin_edit_after', array( &$activity, $error ) );
576
-
577
- // If an error occurred, pass back the activity ID that failed.
578
- if ( $error )
579
- $redirect_to = add_query_arg( 'error', $error, $redirect_to );
580
- else
581
- $redirect_to = add_query_arg( 'updated', $activity->id, $redirect_to );
582
-
583
- /**
584
- * Filters URL to redirect to after saving.
585
- *
586
- * @since 1.6.0
587
- *
588
- * @param string $redirect_to URL to redirect to.
589
- */
590
- wp_redirect( apply_filters( 'bp_activity_admin_edit_redirect', $redirect_to ) );
591
- exit;
592
-
593
-
594
- // If a referrer and a nonce is supplied, but no action, redirect back.
595
- } elseif ( ! empty( $_GET['_wp_http_referer'] ) ) {
596
- wp_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), stripslashes( $_SERVER['REQUEST_URI'] ) ) );
597
- exit;
598
- }
599
- }
600
-
601
- /**
602
- * Output the Activity component admin screens.
603
- *
604
- * @since 1.6.0
605
- */
606
- function bp_activity_admin() {
607
- // Decide whether to load the index or edit screen.
608
- $doaction = ! empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';
609
-
610
- // Display the single activity edit screen.
611
- if ( 'edit' == $doaction && ! empty( $_GET['aid'] ) )
612
- bp_activity_admin_edit();
613
-
614
- // Otherwise, display the Activity index screen.
615
- else
616
- bp_activity_admin_index();
617
- }
618
-
619
- /**
620
- * Display the single activity edit screen.
621
- *
622
- * @since 1.6.0
623
- */
624
- function bp_activity_admin_edit() {
625
-
626
- // @todo: Check if user is allowed to edit activity items
627
- // if ( ! current_user_can( 'bp_edit_activity' ) )
628
- if ( ! is_super_admin() )
629
- die( '-1' );
630
-
631
- // Get the activity from the database.
632
- $activity = bp_activity_get( array(
633
- 'in' => ! empty( $_REQUEST['aid'] ) ? (int) $_REQUEST['aid'] : 0,
634
- 'max' => 1,
635
- 'show_hidden' => true,
636
- 'spam' => 'all',
637
- 'display_comments' => 0
638
- ) );
639
-
640
- if ( ! empty( $activity['activities'][0] ) ) {
641
- $activity = $activity['activities'][0];
642
-
643
- // Workaround to use WP's touch_time() without duplicating that function.
644
- $GLOBALS['comment'] = new stdClass;
645
- $GLOBALS['comment']->comment_date = $activity->date_recorded;
646
- } else {
647
- $activity = '';
648
- }
649
-
650
- // Construct URL for form.
651
- $form_url = remove_query_arg( array( 'action', 'deleted', 'error', 'spammed', 'unspammed', ), $_SERVER['REQUEST_URI'] );
652
- $form_url = add_query_arg( 'action', 'save', $form_url );
653
-
654
- /**
655
- * Fires before activity edit form is displays so plugins can modify the activity.
656
- *
657
- * @since 1.6.0
658
- *
659
- * @param array $value Array holding single activity object that was passed by reference.
660
- */
661
- do_action_ref_array( 'bp_activity_admin_edit', array( &$activity ) ); ?>
662
-
663
- <div class="wrap">
664
- <h1><?php printf( __( 'Editing Activity (ID #%s)', 'buddypress' ), number_format_i18n( (int) $_REQUEST['aid'] ) ); ?></h1>
665
-
666
- <?php if ( ! empty( $activity ) ) : ?>
667
-
668
- <form action="<?php echo esc_url( $form_url ); ?>" id="bp-activities-edit-form" method="post">
669
- <div id="poststuff">
670
-
671
- <div id="post-body" class="metabox-holder columns-<?php echo 1 == get_current_screen()->get_columns() ? '1' : '2'; ?>">
672
- <div id="post-body-content">
673
- <div id="postdiv">
674
- <div id="bp_activity_action" class="postbox">
675
- <h2><?php _e( 'Action', 'buddypress' ); ?></h2>
676
- <div class="inside">
677
- <label for="bp-activities-action" class="screen-reader-text"><?php
678
- /* translators: accessibility text */
679
- _e( 'Edit activity action', 'buddypress' );
680
- ?></label>
681
- <?php wp_editor( stripslashes( $activity->action ), 'bp-activities-action', array( 'media_buttons' => false, 'textarea_rows' => 7, 'teeny' => true, 'quicktags' => array( 'buttons' => 'strong,em,link,block,del,ins,img,code,spell,close' ) ) ); ?>
682
- </div>
683
- </div>
684
-
685
- <div id="bp_activity_content" class="postbox">
686
- <h2><?php _e( 'Content', 'buddypress' ); ?></h2>
687
- <div class="inside">
688
- <label for="bp-activities-content" class="screen-reader-text"><?php
689
- /* translators: accessibility text */
690
- _e( 'Edit activity content', 'buddypress' );
691
- ?></label>
692
- <?php wp_editor( stripslashes( $activity->content ), 'bp-activities-content', array( 'media_buttons' => false, 'teeny' => true, 'quicktags' => array( 'buttons' => 'strong,em,link,block,del,ins,img,code,spell,close' ) ) ); ?>
693
- </div>
694
- </div>
695
- </div>
696
- </div><!-- #post-body-content -->
697
-
698
- <div id="postbox-container-1" class="postbox-container">
699
- <?php do_meta_boxes( get_current_screen()->id, 'side', $activity ); ?>
700
- </div>
701
-
702
- <div id="postbox-container-2" class="postbox-container">
703
- <?php do_meta_boxes( get_current_screen()->id, 'normal', $activity ); ?>
704
- <?php do_meta_boxes( get_current_screen()->id, 'advanced', $activity ); ?>
705
- </div>
706
- </div><!-- #post-body -->
707
-
708
- </div><!-- #poststuff -->
709
- <?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?>
710
- <?php wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?>
711
- <?php wp_nonce_field( 'edit-activity_' . $activity->id ); ?>
712
- </form>
713
-
714
- <?php else : ?>
715
-
716
- <p><?php
717
- printf(
718
- '%1$s <a href="%2$s">%3$s</a>',
719
- __( 'No activity found with this ID.', 'buddypress' ),
720
- esc_url( bp_get_admin_url( 'admin.php?page=bp-activity' ) ),
721
- __( 'Go back and try again.', 'buddypress' )
722
- );
723
- ?></p>
724
-
725
- <?php endif; ?>
726
-
727
- </div><!-- .wrap -->
728
-
729
- <?php
730
- }
731
-
732
- /**
733
- * Status metabox for the Activity admin edit screen.
734
- *
735
- * @since 1.6.0
736
- *
737
- * @param object $item Activity item.
738
- */
739
- function bp_activity_admin_edit_metabox_status( $item ) {
740
- ?>
741
-
742
- <div class="submitbox" id="submitcomment">
743
-
744
- <div id="minor-publishing">
745
- <div id="minor-publishing-actions">
746
- <div id="preview-action">
747
- <a class="button preview" href="<?php echo esc_attr( bp_activity_get_permalink( $item->id, $item ) ); ?>" target="_blank"><?php _e( 'View Activity', 'buddypress' ); ?></a>
748
- </div>
749
-
750
- <div class="clear"></div>
751
- </div><!-- #minor-publishing-actions -->
752
-
753
- <div id="misc-publishing-actions">
754
- <div class="misc-pub-section" id="comment-status-radio">
755
- <label class="approved" for="activity-status-approved"><input type="radio" name="activity_status" id="activity-status-approved" value="ham" <?php checked( $item->is_spam, 0 ); ?>><?php _e( 'Approved', 'buddypress' ); ?></label><br />
756
- <label class="spam" for="activity-status-spam"><input type="radio" name="activity_status" id="activity-status-spam" value="spam" <?php checked( $item->is_spam, 1 ); ?>><?php _e( 'Spam', 'buddypress' ); ?></label>
757
- </div>
758
-
759
- <div class="misc-pub-section curtime misc-pub-section-last">
760
- <?php
761
- // Translators: Publish box date format, see http://php.net/date.
762
- $datef = __( 'M j, Y @ G:i', 'buddypress' );
763
- $date = date_i18n( $datef, strtotime( $item->date_recorded ) );
764
- ?>
765
- <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>
766
-
767
- <div id='timestampdiv' class='hide-if-js'>
768
- <?php touch_time( 1, 0, 5 ); ?>
769
- </div><!-- #timestampdiv -->
770
- </div>
771
- </div> <!-- #misc-publishing-actions -->
772
-
773
- <div class="clear"></div>
774
- </div><!-- #minor-publishing -->
775
-
776
- <div id="major-publishing-actions">
777
- <div id="publishing-action">
778
- <?php submit_button( __( 'Update', 'buddypress' ), 'primary', 'save', false ); ?>
779
- </div>
780
- <div class="clear"></div>
781
- </div><!-- #major-publishing-actions -->
782
-
783
- </div><!-- #submitcomment -->
784
-
785
- <?php
786
- }
787
-
788
- /**
789
- * Primary link metabox for the Activity admin edit screen.
790
- *
791
- * @since 1.6.0
792
- *
793
- * @param object $item Activity item.
794
- */
795
- function bp_activity_admin_edit_metabox_link( $item ) {
796
- ?>
797
-
798
- <label class="screen-reader-text" for="bp-activities-link"><?php
799
- /* translators: accessibility text */
800
- _e( 'Link', 'buddypress' );
801
- ?></label>
802
- <input type="url" name="bp-activities-link" id="bp-activities-link" value="<?php echo esc_url( $item->primary_link ); ?>" aria-describedby="bp-activities-link-description" />
803
- <p id="bp-activities-link-description"><?php _e( 'Activity generated by posts and comments, forum topics and replies, and some plugins, uses the link field for a permalink back to the content item.', 'buddypress' ); ?></p>
804
-
805
- <?php
806
- }
807
-
808
- /**
809
- * User ID metabox for the Activity admin edit screen.
810
- *
811
- * @since 1.6.0
812
- *
813
- * @param object $item Activity item.
814
- */
815
- function bp_activity_admin_edit_metabox_userid( $item ) {
816
- ?>
817
-
818
- <label class="screen-reader-text" for="bp-activities-userid"><?php
819
- /* translators: accessibility text */
820
- _e( 'Author ID', 'buddypress' );
821
- ?></label>
822
- <input type="number" name="bp-activities-userid" id="bp-activities-userid" value="<?php echo esc_attr( $item->user_id ); ?>" min="1" />
823
-
824
- <?php
825
- }
826
-
827
- /**
828
- * Get flattened array of all registered activity actions.
829
- *
830
- * Format is [activity_type] => Pretty name for activity type.
831
- *
832
- * @since 2.0.0
833
- *
834
- * @return array $actions
835
- */
836
- function bp_activity_admin_get_activity_actions() {
837
- $actions = array();
838
-
839
- // Walk through the registered actions, and build an array of actions/values.
840
- foreach ( bp_activity_get_actions() as $action ) {
841
- $action = array_values( (array) $action );
842
-
843
- for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ ) {
844
- $actions[ $action[$i]['key'] ] = $action[$i]['value'];
845
- }
846
- }
847
-
848
- // This was a mis-named activity type from before BP 1.6.
849
- unset( $actions['friends_register_activity_action'] );
850
-
851
- // Sort array by the human-readable value.
852
- natsort( $actions );
853
-
854
- return $actions;
855
- }
856
-
857
- /**
858
- * Activity type metabox for the Activity admin edit screen.
859
- *
860
- * @since 1.6.0
861
- *
862
- * @param object $item Activity item.
863
- */
864
- function bp_activity_admin_edit_metabox_type( $item ) {
865
- $bp = buddypress();
866
-
867
- $actions = array();
868
- $selected = $item->type;
869
-
870
- // Walk through the registered actions, and build an array of actions/values.
871
- foreach ( bp_activity_get_actions() as $action ) {
872
- $action = array_values( (array) $action );
873
-
874
- for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ )
875
- $actions[ $action[$i]['key'] ] = $action[$i]['value'];
876
- }
877
-
878
- // This was a mis-named activity type from before BP 1.6.
879
- unset( $actions['friends_register_activity_action'] );
880
-
881
- // Sort array by the human-readable value.
882
- natsort( $actions );
883
-
884
- /*
885
- * If the activity type is not registered properly (eg, a plugin has
886
- * not called bp_activity_set_action()), add the raw type to the end
887
- * of the list.
888
- */
889
- if ( ! isset( $actions[ $selected ] ) ) {
890
- _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' );
891
- $actions[ $selected ] = $selected;
892
- }
893
-
894
- ?>
895
-
896
- <label for="bp-activities-type" class="screen-reader-text"><?php
897
- /* translators: accessibility text */
898
- esc_html_e( 'Select activity type', 'buddypress' );
899
- ?></label>
900
- <select name="bp-activities-type" id="bp-activities-type">
901
- <?php foreach ( $actions as $k => $v ) : ?>
902
- <option value="<?php echo esc_attr( $k ); ?>" <?php selected( $k, $selected ); ?>><?php echo esc_html( $v ); ?></option>
903
- <?php endforeach; ?>
904
- </select>
905
-
906
- <?php
907
- }
908
-
909
- /**
910
- * Primary item ID/Secondary item ID metabox for the Activity admin edit screen.
911
- *
912
- * @since 1.6.0
913
- *
914
- * @param object $item Activity item.
915
- */
916
- function bp_activity_admin_edit_metabox_itemids( $item ) {
917
- ?>
918
-
919
- <label for="bp-activities-primaryid"><?php _e( 'Primary Item ID', 'buddypress' ); ?></label>
920
- <input type="number" name="bp-activities-primaryid" id="bp-activities-primaryid" value="<?php echo esc_attr( $item->item_id ); ?>" min="0" />
921
- <br />
922
-
923
- <label for="bp-activities-secondaryid"><?php _e( 'Secondary Item ID', 'buddypress' ); ?></label>
924
- <input type="number" name="bp-activities-secondaryid" id="bp-activities-secondaryid" value="<?php echo esc_attr( $item->secondary_item_id ); ?>" min="0" />
925
-
926
- <p><?php _e( 'These identify the object that created this activity. For example, the fields could reference a pair of site and comment IDs.', 'buddypress' ); ?></p>
927
-
928
- <?php
929
- }
930
-
931
- /**
932
- * Display the Activity admin index screen, which contains a list of all the activities.
933
- *
934
- * @since 1.6.0
935
- *
936
- * @global BP_Activity_List_Table $bp_activity_list_table Activity screen list table.
937
- * @global string $plugin_page The current plugin page.
938
- */
939
- function bp_activity_admin_index() {
940
- global $bp_activity_list_table, $plugin_page;
941
-
942
- $messages = array();
943
-
944
- // If the user has just made a change to an activity item, build status messages.
945
- if ( ! empty( $_REQUEST['deleted'] ) || ! empty( $_REQUEST['spammed'] ) || ! empty( $_REQUEST['unspammed'] ) || ! empty( $_REQUEST['error'] ) || ! empty( $_REQUEST['updated'] ) ) {
946
- $deleted = ! empty( $_REQUEST['deleted'] ) ? (int) $_REQUEST['deleted'] : 0;
947
- $errors = ! empty( $_REQUEST['error'] ) ? $_REQUEST['error'] : '';
948
- $spammed = ! empty( $_REQUEST['spammed'] ) ? (int) $_REQUEST['spammed'] : 0;
949
- $unspammed = ! empty( $_REQUEST['unspammed'] ) ? (int) $_REQUEST['unspammed'] : 0;
950
- $updated = ! empty( $_REQUEST['updated'] ) ? (int) $_REQUEST['updated'] : 0;
951
-
952
- $errors = array_map( 'absint', explode( ',', $errors ) );
953
-
954
- // Make sure we don't get any empty values in $errors.
955
- for ( $i = 0, $errors_count = count( $errors ); $i < $errors_count; $i++ ) {
956
- if ( 0 === $errors[$i] ) {
957
- unset( $errors[$i] );
958
- }
959
- }
960
-
961
- // Reindex array.
962
- $errors = array_values( $errors );
963
-
964
- if ( $deleted > 0 )
965
- $messages[] = sprintf( _n( '%s activity item has been permanently deleted.', '%s activity items have been permanently deleted.', $deleted, 'buddypress' ), number_format_i18n( $deleted ) );
966
-
967
- if ( ! empty( $errors ) ) {
968
- if ( 1 == count( $errors ) ) {
969
- $messages[] = sprintf( __( 'An error occurred when trying to update activity ID #%s.', 'buddypress' ), number_format_i18n( $errors[0] ) );
970
-
971
- } else {
972
- $error_msg = __( 'Errors occurred when trying to update these activity items:', 'buddypress' );
973
- $error_msg .= '<ul class="activity-errors">';
974
-
975
- // Display each error as a list item.
976
- foreach ( $errors as $error ) {
977
- // Translators: This is a bulleted list of item IDs.
978
- $error_msg .= '<li>' . sprintf( __( '#%s', 'buddypress' ), number_format_i18n( $error ) ) . '</li>';
979
- }
980
-
981
- $error_msg .= '</ul>';
982
- $messages[] = $error_msg;
983
- }
984
- }
985
-
986
- if ( $spammed > 0 )
987
- $messages[] = sprintf( _n( '%s activity item has been successfully spammed.', '%s activity items have been successfully spammed.', $spammed, 'buddypress' ), number_format_i18n( $spammed ) );
988
-
989
- if ( $unspammed > 0 )
990
- $messages[] = sprintf( _n( '%s activity item has been successfully unspammed.', '%s activity items have been successfully unspammed.', $unspammed, 'buddypress' ), number_format_i18n( $unspammed ) );
991
-
992
- if ( $updated > 0 )
993
- $messages[] = __( 'The activity item has been updated successfully.', 'buddypress' );
994
- }
995
-
996
- // Prepare the activity items for display.
997
- $bp_activity_list_table->prepare_items();
998
-
999
- /**
1000
- * Fires before edit form is displayed so plugins can modify the activity messages.
1001
- *
1002
- * @since 1.6.0
1003
- *
1004
- * @param array $messages Array of messages to display at top of page.
1005
- */
1006
- do_action( 'bp_activity_admin_index', $messages ); ?>
1007
-
1008
- <div class="wrap">
1009
- <h1>
1010
- <?php if ( !empty( $_REQUEST['aid'] ) ) : ?>
1011
- <?php printf( __( 'Activity related to ID #%s', 'buddypress' ), number_format_i18n( (int) $_REQUEST['aid'] ) ); ?>
1012
- <?php else : ?>
1013
- <?php _ex( 'Activity', 'Admin SWA page', 'buddypress' ); ?>
1014
- <?php endif; ?>
1015
-
1016
- <?php if ( !empty( $_REQUEST['s'] ) ) : ?>
1017
- <span class="subtitle"><?php printf( __( 'Search results for &#8220;%s&#8221;', 'buddypress' ), wp_html_excerpt( esc_html( stripslashes( $_REQUEST['s'] ) ), 50 ) ); ?></span>
1018
- <?php endif; ?>
1019
- </h1>
1020
-
1021
- <?php // If the user has just made a change to an activity item, display the status messages. ?>
1022
- <?php if ( !empty( $messages ) ) : ?>
1023
- <div id="moderated" class="<?php echo ( ! empty( $_REQUEST['error'] ) ) ? 'error' : 'updated'; ?>"><p><?php echo implode( "<br/>\n", $messages ); ?></p></div>
1024
- <?php endif; ?>
1025
-
1026
- <?php // Display each activity on its own row. ?>
1027
- <?php $bp_activity_list_table->views(); ?>
1028
-
1029
- <form id="bp-activities-form" action="" method="get">
1030
- <?php $bp_activity_list_table->search_box( __( 'Search all Activity', 'buddypress' ), 'bp-activity' ); ?>
1031
- <input type="hidden" name="page" value="<?php echo esc_attr( $plugin_page ); ?>" />
1032
- <?php $bp_activity_list_table->display(); ?>
1033
- </form>
1034
-
1035
- <?php // This markup is used for the reply form. ?>
1036
- <table style="display: none;">
1037
- <tr id="bp-activities-container" style="display: none;">
1038
- <td colspan="4">
1039
- <form method="get" action="">
1040
-
1041
- <h3 id="bp-replyhead"><?php _e( 'Reply to Activity', 'buddypress' ); ?></h3>
1042
- <label for="bp-activities" class="screen-reader-text"><?php
1043
- /* translators: accessibility text */
1044
- _e( 'Reply', 'buddypress' );
1045
- ?></label>
1046
- <?php wp_editor( '', 'bp-activities', array( 'dfw' => false, 'media_buttons' => false, 'quicktags' => array( 'buttons' => 'strong,em,link,block,del,ins,img,code,spell,close' ), 'tinymce' => false, ) ); ?>
1047
-
1048
- <p id="bp-replysubmit" class="submit">
1049
- <a href="#" class="cancel button-secondary alignleft"><?php _e( 'Cancel', 'buddypress' ); ?></a>
1050
- <a href="#" class="save button-primary alignright"><?php _e( 'Reply', 'buddypress' ); ?></a>
1051
-
1052
- <img class="waiting" style="display:none;" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
1053
- <span class="error" style="display:none;"></span>
1054
- <br class="clear" />
1055
- </p>
1056
-
1057
- <?php wp_nonce_field( 'bp-activity-admin-reply', '_ajax_nonce-bp-activity-admin-reply', false ); ?>
1058
-
1059
- </form>
1060
- </td>
1061
- </tr>
1062
- </table>
1063
- </div>
1064
-
1065
- <?php
1066
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/bp-activity-adminbar.php DELETED
@@ -1,47 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Activity Toolbar.
4
- *
5
- * Handles the activity functions related to the WordPress Toolbar.
6
- *
7
- * @package BuddyPress
8
- * @subpackage Activity
9
- */
10
-
11
- // Exit if accessed directly.
12
- defined( 'ABSPATH' ) || exit;
13
-
14
- /**
15
- * Add the Activity top-level menu link when viewing single activity item.
16
- *
17
- * @since 2.6.0
18
- *
19
- * @return null Null if user does not have access to editing functionality.
20
- */
21
- function bp_activity_admin_menu() {
22
- global $wp_admin_bar;
23
-
24
- // Only show if viewing a single activity item.
25
- if ( ! bp_is_single_activity() ) {
26
- return;
27
- }
28
-
29
- // Only show this menu to super admins
30
- if ( ! bp_current_user_can( 'bp_moderate' ) ) {
31
- return;
32
- }
33
-
34
- $activity_edit_link = add_query_arg( array(
35
- 'page' => 'bp-activity',
36
- 'aid' => bp_current_action(),
37
- 'action' => 'edit'
38
- ), bp_get_admin_url( 'admin.php' ) );
39
-
40
- // Add the top-level Edit Activity button.
41
- $wp_admin_bar->add_menu( array(
42
- 'id' => 'activity-admin',
43
- 'title' => __( 'Edit Activity', 'buddypress' ),
44
- 'href' => esc_url( $activity_edit_link ),
45
- ) );
46
- }
47
- add_action( 'admin_bar_menu', 'bp_activity_admin_menu', 99 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/bp-activity-akismet.php DELETED
@@ -1,72 +0,0 @@
1
- <?php
2
- /**
3
- * Akismet support for BuddyPress' Activity Stream.
4
- *
5
- * @package BuddyPress
6
- * @subpackage ActivityAkismet
7
- * @since 1.6.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Loads Akismet filtering for activity.
15
- *
16
- * @since 1.6.0
17
- * @since 2.3.0 We only support Akismet 3+.
18
- */
19
- function bp_activity_setup_akismet() {
20
- /**
21
- * Filters if BuddyPress Activity Akismet support has been disabled by another plugin.
22
- *
23
- * @since 1.6.0
24
- *
25
- * @param bool $value Return value of bp_is_akismet_active boolean function.
26
- */
27
- if ( ! apply_filters( 'bp_activity_use_akismet', bp_is_akismet_active() ) ) {
28
- return;
29
- }
30
-
31
- // Instantiate Akismet for BuddyPress.
32
- buddypress()->activity->akismet = new BP_Akismet();
33
- }
34
- add_action( 'bp_activity_setup_globals', 'bp_activity_setup_akismet' );
35
-
36
- /**
37
- * Delete old spam activity meta data.
38
- *
39
- * This is done as a clean-up mechanism, as _bp_akismet_submission meta can
40
- * grow to be quite large.
41
- *
42
- * @since 1.6.0
43
- *
44
- * @global wpdb $wpdb WordPress database object.
45
- */
46
- function bp_activity_akismet_delete_old_metadata() {
47
- global $wpdb;
48
-
49
- $bp = buddypress();
50
-
51
- /**
52
- * Filters the threshold for how many days old Akismet metadata needs to be before being automatically deleted.
53
- *
54
- * @since 1.6.0
55
- *
56
- * @param integer 15 How many days old metadata needs to be.
57
- */
58
- $interval = apply_filters( 'bp_activity_akismet_delete_meta_interval', 15 );
59
-
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
-
67
- if ( ! empty( $activity_ids ) ) {
68
- foreach ( $activity_ids as $activity_id )
69
- bp_activity_delete_meta( $activity_id, '_bp_akismet_submission' );
70
- }
71
- }
72
- add_action( 'bp_activity_akismet_delete_old_metadata', 'bp_activity_akismet_delete_old_metadata' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/bp-activity-cache.php DELETED
@@ -1,86 +0,0 @@
1
- <?php
2
- /**
3
- * Functions related to the BuddyPress Activity component and the WP Cache.
4
- *
5
- * @package BuddyPress
6
- * @subpackage ActivityCache
7
- * @since 1.6.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Slurp up activitymeta for a specified set of activity items.
15
- *
16
- * It grabs all activitymeta associated with all of the activity items passed
17
- * in $activity_ids and adds it to the WP cache. This improves efficiency when
18
- * using querying activitymeta inline.
19
- *
20
- * @since 1.6.0
21
- *
22
- * @param int|string|array|bool $activity_ids Accepts a single activity ID, or a comma-
23
- * separated list or array of activity ids.
24
- */
25
- function bp_activity_update_meta_cache( $activity_ids = false ) {
26
- $bp = buddypress();
27
-
28
- $cache_args = array(
29
- 'object_ids' => $activity_ids,
30
- 'object_type' => $bp->activity->id,
31
- 'object_column' => 'activity_id',
32
- 'cache_group' => 'activity_meta',
33
- 'meta_table' => $bp->activity->table_name_meta,
34
- 'cache_key_prefix' => 'bp_activity_meta'
35
- );
36
-
37
- bp_update_meta_cache( $cache_args );
38
- }
39
-
40
- /**
41
- * Clear a cached activity item when that item is updated.
42
- *
43
- * @since 2.0.0
44
- *
45
- * @param BP_Activity_Activity $activity Activity object.
46
- */
47
- function bp_activity_clear_cache_for_activity( $activity ) {
48
- wp_cache_delete( $activity->id, 'bp_activity' );
49
- wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
50
- }
51
- add_action( 'bp_activity_after_save', 'bp_activity_clear_cache_for_activity' );
52
-
53
- /**
54
- * Clear cached data for deleted activity items.
55
- *
56
- * @since 2.0.0
57
- *
58
- * @param array $deleted_ids IDs of deleted activity items.
59
- */
60
- function bp_activity_clear_cache_for_deleted_activity( $deleted_ids ) {
61
- foreach ( (array) $deleted_ids as $deleted_id ) {
62
- wp_cache_delete( $deleted_id, 'bp_activity' );
63
- }
64
- }
65
- add_action( 'bp_activity_deleted_activities', 'bp_activity_clear_cache_for_deleted_activity' );
66
-
67
- /**
68
- * Reset cache incrementor for the Activity component.
69
- *
70
- * Called whenever an activity item is created, updated, or deleted, this
71
- * function effectively invalidates all cached results of activity queries.
72
- *
73
- * @since 2.7.0
74
- *
75
- * @return bool True on success, false on failure.
76
- */
77
- function bp_activity_reset_cache_incrementor() {
78
- $without_last_activity = bp_core_reset_incrementor( 'bp_activity' );
79
- $with_last_activity = bp_core_reset_incrementor( 'bp_activity_with_last_activity' );
80
- return $without_last_activity && $with_last_activity;
81
- }
82
- add_action( 'bp_activity_delete', 'bp_activity_reset_cache_incrementor' );
83
- add_action( 'bp_activity_add', 'bp_activity_reset_cache_incrementor' );
84
- add_action( 'added_activity_meta', 'bp_activity_reset_cache_incrementor' );
85
- add_action( 'updated_activity_meta', 'bp_activity_reset_cache_incrementor' );
86
- add_action( 'deleted_activity_meta', 'bp_activity_reset_cache_incrementor' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/bp-activity-classes.php ADDED
@@ -0,0 +1,553 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ Class BP_Activity_Activity {
4
+ var $id;
5
+ var $item_id;
6
+ var $secondary_item_id;
7
+ var $user_id;
8
+ var $primary_link;
9
+ var $component;
10
+ var $type;
11
+ var $action;
12
+ var $content;
13
+ var $date_recorded;
14
+ var $hide_sitewide = false;
15
+
16
+ function bp_activity_activity( $id = false ) {
17
+ global $bp;
18
+
19
+ if ( $id ) {
20
+ $this->id = $id;
21
+ $this->populate();
22
+ }
23
+ }
24
+
25
+ function populate() {
26
+ global $wpdb, $bp;
27
+
28
+ $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE id = %d", $this->id ) );
29
+ if ( $row ) {
30
+ $this->id = $row->id;
31
+ $this->item_id = $row->item_id;
32
+ $this->secondary_item_id = $row->secondary_item_id;
33
+ $this->user_id = $row->user_id;
34
+ $this->primary_link = $row->primary_link;
35
+ $this->component = $row->component;
36
+ $this->type = $row->type;
37
+ $this->action = $row->action;
38
+ $this->content = $row->content;
39
+ $this->date_recorded = $row->date_recorded;
40
+ $this->hide_sitewide = $row->hide_sitewide;
41
+ $this->mptt_left = $row->mptt_left;
42
+ $this->mptt_right = $row->mptt_right;
43
+ }
44
+ }
45
+
46
+ function save() {
47
+ global $wpdb, $bp, $current_user;
48
+
49
+ do_action( 'bp_activity_before_save', &$this );
50
+
51
+ $this->id = apply_filters( 'bp_activity_id_before_save', $this->id, &$this );
52
+ $this->item_id = apply_filters( 'bp_activity_item_id_before_save', $this->item_id, &$this );
53
+ $this->secondary_item_id = apply_filters( 'bp_activity_secondary_item_id_before_save', $this->secondary_item_id, &$this );
54
+ $this->user_id = apply_filters( 'bp_activity_user_id_before_save', $this->user_id, &$this );
55
+ $this->primary_link = apply_filters( 'bp_activity_primary_link_before_save', $this->primary_link, &$this );
56
+ $this->component = apply_filters( 'bp_activity_component_before_save', $this->component, &$this );
57
+ $this->type = apply_filters( 'bp_activity_type_before_save', $this->type, &$this );
58
+ $this->action = apply_filters( 'bp_activity_action_before_save', $this->action, &$this );
59
+ $this->content = apply_filters( 'bp_activity_content_before_save', $this->content, &$this );
60
+ $this->date_recorded = apply_filters( 'bp_activity_date_recorded_before_save', $this->date_recorded, &$this );
61
+ $this->hide_sitewide = apply_filters( 'bp_activity_hide_sitewide_before_save', $this->hide_sitewide, &$this );
62
+ $this->mptt_left = apply_filters( 'bp_activity_mptt_left_before_save', $this->mptt_left, &$this );
63
+ $this->mptt_right = apply_filters( 'bp_activity_mptt_right_before_save', $this->mptt_right, &$this );
64
+
65
+ if ( !$this->component || !$this->type )
66
+ return false;
67
+
68
+ if ( !$this->primary_link )
69
+ $this->primary_link = $bp->loggedin_user->domain;
70
+
71
+ /* If we have an existing ID, update the activity item, otherwise insert it. */
72
+ if ( $this->id )
73
+ $q = $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET user_id = %d, component = %s, type = %s, action = %s, content = %s, primary_link = %s, date_recorded = %s, item_id = %s, secondary_item_id = %s, hide_sitewide = %d WHERE id = %d", $this->user_id, $this->component, $this->type, $this->action, $this->content, $this->primary_link, $this->date_recorded, $this->item_id, $this->secondary_item_id, $this->hide_sitewide, $this->id );
74
+ else
75
+ $q = $wpdb->prepare( "INSERT INTO {$bp->activity->table_name} ( user_id, component, type, action, content, primary_link, date_recorded, item_id, secondary_item_id, hide_sitewide ) VALUES ( %d, %s, %s, %s, %s, %s, %s, %s, %s, %d )", $this->user_id, $this->component, $this->type, $this->action, $this->content, $this->primary_link, $this->date_recorded, $this->item_id, $this->secondary_item_id, $this->hide_sitewide );
76
+
77
+ if ( !$wpdb->query( $q ) )
78
+ return false;
79
+
80
+ if ( empty( $this->id ) )
81
+ $this->id = $wpdb->insert_id;
82
+
83
+ do_action( 'bp_activity_after_save', &$this );
84
+ return true;
85
+ }
86
+
87
+ /* Static Functions */
88
+
89
+ function get( $max = false, $page = 1, $per_page = 25, $sort = 'DESC', $search_terms = false, $filter = false, $display_comments = false, $show_hidden = false ) {
90
+ global $wpdb, $bp;
91
+
92
+ /* Select conditions */
93
+ $select_sql = "SELECT a.*, u.user_email, u.user_nicename, u.user_login, u.display_name";
94
+
95
+ $from_sql = " FROM {$bp->activity->table_name} a LEFT JOIN {$wpdb->users} u ON a.user_id = u.ID";
96
+
97
+ /* Where conditions */
98
+ $where_conditions = array();
99
+
100
+ /* Searching */
101
+ if ( $search_terms ) {
102
+ $search_terms = $wpdb->escape( $search_terms );
103
+ $where_conditions['search_sql'] = "a.content LIKE '%%" . like_escape( $search_terms ) . "%%'";
104
+ }
105
+
106
+ /* Filtering */
107
+ if ( $filter && $filter_sql = BP_Activity_Activity::get_filter_sql( $filter ) )
108
+ $where_conditions['filter_sql'] = $filter_sql;
109
+
110
+ /* Sorting */
111
+ if ( $sort != 'ASC' && $sort != 'DESC' )
112
+ $sort = 'DESC';
113
+
114
+ /* Hide Hidden Items? */
115
+ if ( !$show_hidden )
116
+ $where_conditions['hidden_sql'] = "a.hide_sitewide = 0";
117
+
118
+ /* Alter the query based on whether we want to show activity item comments in the stream like normal comments or threaded below the activity */
119
+ if ( !$display_comments || 'threaded' == $display_comments ) {
120
+ $where_conditions[] = "a.type != 'activity_comment'";
121
+ }
122
+
123
+ $where_sql = 'WHERE ' . join( ' AND ', $where_conditions );
124
+
125
+ if ( $per_page && $page ) {
126
+ $pag_sql = $wpdb->prepare( "LIMIT %d, %d", intval( ( $page - 1 ) * $per_page ), intval( $per_page ) );
127
+ $activities = $wpdb->get_results( $wpdb->prepare( "{$select_sql} {$from_sql} {$where_sql} ORDER BY a.date_recorded {$sort} {$pag_sql}" ) );
128
+ } else
129
+ $activities = $wpdb->get_results( $wpdb->prepare( "{$select_sql} {$from_sql} {$where_sql} ORDER BY a.date_recorded {$sort} {$pag_sql}" ) );
130
+
131
+ $total_activities = $wpdb->get_var( $wpdb->prepare( "SELECT count(a.id) FROM {$bp->activity->table_name} a {$where_sql} ORDER BY a.date_recorded {$sort}" ) );
132
+
133
+ /* Get the fullnames of users so we don't have to query in the loop */
134
+ if ( function_exists( 'xprofile_install' ) && $activities ) {
135
+ foreach ( (array)$activities as $activity ) {
136
+ if ( (int)$activity->user_id )
137
+ $activity_user_ids[] = $activity->user_id;
138
+ }
139
+
140
+ $activity_user_ids = implode( ',', array_unique( (array)$activity_user_ids ) );
141
+ if ( !empty( $activity_user_ids ) ) {
142
+ if ( $names = $wpdb->get_results( $wpdb->prepare( "SELECT user_id, value AS user_fullname FROM {$bp->profile->table_name_data} WHERE field_id = 1 AND user_id IN ({$activity_user_ids})" ) ) ) {
143
+ foreach ( (array)$names as $name )
144
+ $tmp_names[$name->user_id] = $name->user_fullname;
145
+
146
+ foreach ( (array)$activities as $i => $activity ) {
147
+ if ( !empty( $tmp_names[$activity->user_id] ) )
148
+ $activities[$i]->user_fullname = $tmp_names[$activity->user_id];
149
+ }
150
+
151
+ unset( $names );
152
+ unset( $tmp_names );
153
+ }
154
+ }
155
+ }
156
+
157
+ if ( $activities && $display_comments )
158
+ $activities = BP_Activity_Activity::append_comments( &$activities );
159
+
160
+ /* If $max is set, only return up to the max results */
161
+ if ( !empty( $max ) ) {
162
+ if ( (int)$total_activities > (int)$max )
163
+ $total_activities = $max;
164
+ }
165
+
166
+ return array( 'activities' => $activities, 'total' => (int)$total_activities );
167
+ }
168
+
169
+ function get_specific( $activity_ids, $max = false, $page = 1, $per_page = 25, $sort = 'DESC', $display_comments = false ) {
170
+ global $wpdb, $bp;
171
+
172
+ if ( is_array( $activity_ids ) )
173
+ $activity_ids = implode( ',', $activity_ids );
174
+
175
+ $activity_ids = $wpdb->escape( $activity_ids );
176
+
177
+ if ( empty( $activity_ids ) )
178
+ return false;
179
+
180
+ if ( $per_page && $page )
181
+ $pag_sql = $wpdb->prepare( "LIMIT %d, %d", intval( ( $page - 1 ) * $per_page ), intval( $per_page ) );
182
+
183
+ if ( $sort != 'ASC' && $sort != 'DESC' )
184
+ $sort = 'DESC';
185
+
186
+ $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE id IN ({$activity_ids}) ORDER BY date_recorded {$sort} $pag_sql" ) );
187
+ $total_activities = $wpdb->get_var( $wpdb->prepare( "SELECT count(id) FROM {$bp->activity->table_name} WHERE id IN ({$activity_ids})" ) );
188
+
189
+ if ( $display_comments )
190
+ $activities = BP_Activity_Activity::append_comments( $activities );
191
+
192
+ /* If $max is set, only return up to the max results */
193
+ if ( !empty( $max ) ) {
194
+ if ( (int)$total_activities > (int)$max )
195
+ $total_activities = $max;
196
+ }
197
+
198
+ return array( 'activities' => $activities, 'total' => (int)$total_activities );
199
+ }
200
+
201
+ function get_id( $user_id, $component, $type, $item_id, $secondary_item_id, $action, $content, $date_recorded ) {
202
+ global $bp, $wpdb;
203
+
204
+ $where_args = false;
205
+
206
+ if ( !empty( $user_id ) )
207
+ $where_args[] = $wpdb->prepare( "user_id = %d", $user_id );
208
+
209
+ if ( !empty( $component ) )
210
+ $where_args[] = $wpdb->prepare( "component = %s", $component );
211
+
212
+ if ( !empty( $type ) )
213
+ $where_args[] = $wpdb->prepare( "type = %s", $type );
214
+
215
+ if ( !empty( $item_id ) )
216
+ $where_args[] = $wpdb->prepare( "item_id = %s", $item_id );
217
+
218
+ if ( !empty( $secondary_item_id ) )
219
+ $where_args[] = $wpdb->prepare( "secondary_item_id = %s", $secondary_item_id );
220
+
221
+ if ( !empty( $action ) )
222
+ $where_args[] = $wpdb->prepare( "action = %s", $action );
223
+
224
+ if ( !empty( $content ) )
225
+ $where_args[] = $wpdb->prepare( "content = %s", $content );
226
+
227
+ if ( !empty( $date_recorded ) )
228
+ $where_args[] = $wpdb->prepare( "date_recorded = %s", $date_recorded );
229
+
230
+ if ( !empty( $where_args ) )
231
+ $where_sql = 'WHERE ' . join( ' AND ', $where_args );
232
+ else
233
+ return false;
234
+
235
+ return $wpdb->get_var( "SELECT id FROM {$bp->activity->table_name} {$where_sql}" );
236
+ }
237
+
238
+ function delete( $args ) {
239
+ global $wpdb, $bp;
240
+
241
+ extract( $args );
242
+
243
+ $defaults = array(
244
+ 'id' => false,
245
+ 'action' => false,
246
+ 'content' => false,
247
+ 'component' => false,
248
+ 'type' => false,
249
+ 'primary_link' => false,
250
+ 'user_id' => false,
251
+ 'item_id' => false,
252
+ 'secondary_item_id' => false,
253
+ 'date_recorded' => false,
254
+ 'hide_sitewide' => false
255
+ );
256
+
257
+ $where_args = false;
258
+
259
+ if ( !empty( $id ) )
260
+ $where_args[] = $wpdb->prepare( "id = %d", $id );
261
+
262
+ if ( !empty( $user_id ) )
263
+ $where_args[] = $wpdb->prepare( "user_id = %d", $user_id );
264
+
265
+ if ( !empty( $action ) )
266
+ $where_args[] = $wpdb->prepare( "action = %s", $action );
267
+
268
+ if ( !empty( $content ) )
269
+ $where_args[] = $wpdb->prepare( "content = %s", $content );
270
+
271
+ if ( !empty( $component ) )
272
+ $where_args[] = $wpdb->prepare( "component = %s", $component );
273
+
274
+ if ( !empty( $type ) )
275
+ $where_args[] = $wpdb->prepare( "type = %s", $type );
276
+
277
+ if ( !empty( $primary_link ) )
278
+ $where_args[] = $wpdb->prepare( "primary_link = %s", $primary_link );
279
+
280
+ if ( !empty( $item_id ) )
281
+ $where_args[] = $wpdb->prepare( "item_id = %s", $item_id );
282
+
283
+ if ( !empty( $secondary_item_id ) )
284
+ $where_args[] = $wpdb->prepare( "secondary_item_id = %s", $secondary_item_id );
285
+
286
+ if ( !empty( $date_recorded ) )
287
+ $where_args[] = $wpdb->prepare( "date_recorded = %s", $date_recorded );
288
+
289
+ if ( !empty( $hide_sitewide ) )
290
+ $where_args[] = $wpdb->prepare( "hide_sitewide = %d", $hide_sitewide );
291
+
292
+ if ( !empty( $where_args ) )
293
+ $where_sql = 'WHERE ' . join( ' AND ', $where_args );
294
+ else
295
+ return false;
296
+
297
+ /* Fetch the activity IDs so we can delete any comments for this activity item */
298
+ $activity_ids = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} {$where_sql}" ) );
299
+
300
+ if ( !$wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name} {$where_sql}" ) ) )
301
+ return false;
302
+
303
+ if ( $activity_ids ) {
304
+ BP_Activity_Activity::delete_activity_item_comments( $activity_ids );
305
+ BP_Activity_Activity::delete_activity_meta_entries( $activity_ids );
306
+
307
+ return $activity_ids;
308
+ }
309
+
310
+ return $activity_ids;
311
+ }
312
+
313
+ function delete_activity_item_comments( $activity_ids ) {
314
+ global $bp, $wpdb;
315
+
316
+ if ( is_array($activity_ids) )
317
+ $activity_ids = implode( ',', $activity_ids );
318
+
319
+ $activity_ids = $wpdb->escape( $activity_ids );
320
+
321
+ return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name} WHERE type = 'activity_comment' AND item_id IN ({$activity_ids})" ) );
322
+ }
323
+
324
+ function delete_activity_meta_entries( $activity_ids ) {
325
+ global $bp, $wpdb;
326
+
327
+ if ( is_array($activity_ids) )
328
+ $activity_ids = implode( ',', $activity_ids );
329
+
330
+ $activity_ids = $wpdb->escape( $activity_ids );
331
+
332
+ return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id IN ({$activity_ids})" ) );
333
+ }
334
+
335
+ function append_comments( $activities ) {
336
+ global $bp, $wpdb;
337
+
338
+ /* Now fetch the activity comments and parse them into the correct position in the activities array. */
339
+ foreach( (array)$activities as $activity ) {
340
+ if ( 'activity_comment' != $activity->type && $activity->mptt_left && $activity->mptt_right )
341
+ $activity_comments[$activity->id] = BP_Activity_Activity::get_activity_comments( $activity->id, $activity->mptt_left, $activity->mptt_right );
342
+ }
343
+
344
+ /* Merge the comments with the activity items */
345
+ foreach( (array)$activities as $key => $activity )
346
+ $activities[$key]->children = $activity_comments[$activity->id];
347
+
348
+ return $activities;
349
+ }
350
+
351
+ function get_activity_comments( $activity_id, $left, $right ) {
352
+ global $wpdb, $bp;
353
+
354
+ if ( !$comments = wp_cache_get( 'bp_activity_comments_' . $activity_id ) ) {
355
+ /* Select the user's fullname with the query so we don't have to fetch it for each comment */
356
+ if ( function_exists( 'xprofile_install' ) ) {
357
+ $fullname_select = ", pd.value as user_fullname";
358
+ $fullname_from = ", {$bp->profile->table_name_data} pd ";
359
+ $fullname_where = "AND pd.user_id = a.user_id AND pd.field_id = 1";
360
+ }
361
+
362
+ /* Retrieve all descendants of the $root node */
363
+ $descendants = $wpdb->get_results( $wpdb->prepare( "SELECT a.*, u.user_email, u.user_nicename, u.user_login, u.display_name{$fullname_select} FROM {$bp->activity->table_name} a, {$wpdb->users} u{$fullname_from} WHERE u.ID = a.user_id {$fullname_where} AND a.type = 'activity_comment' AND a.item_id = %d AND a.mptt_left BETWEEN %d AND %d ORDER BY a.date_recorded ASC", $activity_id, $left, $right ) );
364
+
365
+ /* Loop descendants and build an assoc array */
366
+ foreach ( (array)$descendants as $d ) {
367
+ $d->children = array();
368
+
369
+ /* If we have a reference on the parent */
370
+ if ( isset( $ref[ $d->secondary_item_id ] ) ) {
371
+ $ref[ $d->secondary_item_id ]->children[ $d->id ] = $d;
372
+ $ref[ $d->id ] =& $ref[ $d->secondary_item_id ]->children[ $d->id ];
373
+
374
+ /* If we don't have a reference on the parent, put in the root level */
375
+ } else {
376
+ $comments[ $d->id ] = $d;
377
+ $ref[ $d->id ] =& $comments[ $d->id ];
378
+ }
379
+ }
380
+ wp_cache_set( 'bp_activity_comments_' . $activity_id, $comments, 'bp' );
381
+ }
382
+
383
+ return $comments;
384
+ }
385
+
386
+ function rebuild_activity_comment_tree( $parent_id, $left = 1 ) {
387
+ global $wpdb, $bp;
388
+
389
+ /* The right value of this node is the left value + 1 */
390
+ $right = $left + 1;
391
+
392
+ /* Get all descendants of this node */
393
+ $descendants = BP_Activity_Activity::get_child_comments( $parent_id );
394
+
395
+ /* Loop the descendants and recalculate the left and right values */
396
+ foreach ( (array)$descendants as $descendant )
397
+ $right = BP_Activity_Activity::rebuild_activity_comment_tree( $descendant->id, $right );
398
+
399
+ /* We've got the left value, and now that we've processed the children of this node we also know the right value */
400
+ if ( 1 == $left )
401
+ $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET mptt_left = %d, mptt_right = %d WHERE id = %d", $left, $right, $parent_id ) );
402
+ else
403
+ $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET mptt_left = %d, mptt_right = %d WHERE type = 'activity_comment' AND id = %d", $left, $right, $parent_id ) );
404
+
405
+ /* Return the right value of this node + 1 */
406
+ return $right + 1;
407
+ }
408
+
409
+ function get_child_comments( $parent_id ) {
410
+ global $bp, $wpdb;
411
+
412
+ return $wpdb->get_results( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE type = 'activity_comment' AND secondary_item_id = %d", $parent_id ) );
413
+ }
414
+
415
+ function get_recorded_components() {
416
+ global $wpdb, $bp;
417
+
418
+ return $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT component FROM {$bp->activity->table_name} ORDER BY component ASC" ) );
419
+ }
420
+
421
+ function get_sitewide_items_for_feed( $limit = 35 ) {
422
+ global $wpdb, $bp;
423
+
424
+ $activities = bp_activity_get_sitewide( array( 'max' => $limit ) );
425
+
426
+ for ( $i = 0; $i < count($activities); $i++ ) {
427
+ $title = explode( '<span', $activities[$i]['content'] );
428
+
429
+ $activity_feed[$i]['title'] = trim( strip_tags( $title[0] ) );
430
+ $activity_feed[$i]['link'] = $activities[$i]['primary_link'];
431
+ $activity_feed[$i]['description'] = @sprintf( $activities[$i]['content'], '' );
432
+ $activity_feed[$i]['pubdate'] = $activities[$i]['date_recorded'];
433
+ }
434
+
435
+ return $activity_feed;
436
+ }
437
+
438
+ function get_filter_sql( $filter_array ) {
439
+ global $wpdb;
440
+
441
+ if ( !empty( $filter_array['user_id'] ) ) {
442
+ $user_filter = explode( ',', $filter_array['user_id'] );
443
+ $user_sql = ' ( a.user_id IN ( ' . $filter_array['user_id'] . ' ) )';
444
+ $filter_sql[] = $user_sql;
445
+ }
446
+
447
+ if ( !empty( $filter_array['object'] ) ) {
448
+ $object_filter = explode( ',', $filter_array['object'] );
449
+ $object_sql = ' ( ';
450
+
451
+ $counter = 1;
452
+ foreach( (array) $object_filter as $object ) {
453
+ $object_sql .= $wpdb->prepare( "a.component = %s", trim( $object ) );
454
+
455
+ if ( $counter != count( $object_filter ) )
456
+ $object_sql .= ' || ';
457
+
458
+ $counter++;
459
+ }
460
+
461
+ $object_sql .= ' )';
462
+ $filter_sql[] = $object_sql;
463
+ }
464
+
465
+ if ( !empty( $filter_array['action'] ) ) {
466
+ $action_filter = explode( ',', $filter_array['action'] );
467
+ $action_sql = ' ( ';
468
+
469
+ $counter = 1;
470
+ foreach( (array) $action_filter as $action ) {
471
+ $action_sql .= $wpdb->prepare( "a.type = %s", trim( $action ) );
472
+
473
+ if ( $counter != count( $action_filter ) )
474
+ $action_sql .= ' || ';
475
+
476
+ $counter++;
477
+ }
478
+
479
+ $action_sql .= ' )';
480
+ $filter_sql[] = $action_sql;
481
+ }
482
+
483
+ if ( !empty( $filter_array['primary_id'] ) ) {
484
+ $pid_filter = explode( ',', $filter_array['primary_id'] );
485
+ $pid_sql = ' ( ';
486
+
487
+ $counter = 1;
488
+ foreach( (array) $pid_filter as $pid ) {
489
+ $pid_sql .= $wpdb->prepare( "a.item_id = %s", trim( $pid ) );
490
+
491
+ if ( $counter != count( $pid_filter ) )
492
+ $pid_sql .= ' || ';
493
+
494
+ $counter++;
495
+ }
496
+
497
+ $pid_sql .= ' )';
498
+ $filter_sql[] = $pid_sql;
499
+ }
500
+
501
+ if ( !empty( $filter_array['secondary_id'] ) ) {
502
+ $sid_filter = explode( ',', $filter_array['secondary_id'] );
503
+ $sid_sql = ' ( ';
504
+
505
+ $counter = 1;
506
+ foreach( (array) $sid_filter as $sid ) {
507
+ $sid_sql .= $wpdb->prepare( "a.secondary_item_id = %s", trim( $sid ) );
508
+
509
+ if ( $counter != count( $sid_filter ) )
510
+ $sid_sql .= ' || ';
511
+
512
+ $counter++;
513
+ }
514
+
515
+ $sid_sql .= ' )';
516
+ $filter_sql[] = $sid_sql;
517
+ }
518
+
519
+ if ( empty($filter_sql) )
520
+ return false;
521
+
522
+ return join( ' AND ', $filter_sql );
523
+ }
524
+
525
+ function get_last_updated() {
526
+ global $bp, $wpdb;
527
+
528
+ return $wpdb->get_var( $wpdb->prepare( "SELECT date_recorded FROM {$bp->activity->table_name} ORDER BY date_recorded DESC LIMIT 1" ) );
529
+ }
530
+
531
+ function total_favorite_count( $user_id ) {
532
+ global $bp;
533
+
534
+ if ( !$favorite_activity_entries = get_user_meta( $user_id, 'bp_favorite_activities', true ) )
535
+ return 0;
536
+
537
+ return count( maybe_unserialize( $favorite_activity_entries ) );
538
+ }
539
+
540
+ function check_exists_by_content( $content ) {
541
+ global $wpdb, $bp;
542
+
543
+ return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE content = %s", $content ) );
544
+ }
545
+
546
+ function hide_all_for_user( $user_id ) {
547
+ global $wpdb, $bp;
548
+
549
+ return $wpdb->get_var( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET hide_sitewide = 1 WHERE user_id = %d", $user_id ) );
550
+ }
551
+ }
552
+
553
+ ?>
bp-activity/bp-activity-cssjs.php DELETED
@@ -1,76 +0,0 @@
1
- <?php
2
- /**
3
- * Activity component CSS/JS
4
- *
5
- * @package BuddyPress
6
- * @subpackage ActivityScripts
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Enqueue @mentions JS.
15
- *
16
- * @since 2.1.0
17
- */
18
- function bp_activity_mentions_script() {
19
- if ( ! bp_activity_maybe_load_mentions_scripts() ) {
20
- return;
21
- }
22
-
23
- // Special handling for New/Edit screens in wp-admin.
24
- if ( is_admin() ) {
25
- if (
26
- ! get_current_screen() ||
27
- ! in_array( get_current_screen()->base, array( 'page', 'post' ) ) ||
28
- ! post_type_supports( get_current_screen()->post_type, 'editor' ) ) {
29
- return;
30
- }
31
- }
32
-
33
-
34
- $min = bp_core_get_minified_asset_suffix();
35
-
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
- }
43
-
44
- // If the script has been enqueued, let's attach our mentions TinyMCE init callback.
45
- add_filter( 'tiny_mce_before_init', 'bp_add_mentions_on_tinymce_init', 10, 2 );
46
-
47
- /**
48
- * Fires at the end of the Activity Mentions script.
49
- *
50
- * This is the hook where BP components can add their own prefetched results
51
- * friends to the page for quicker @mentions lookups.
52
- *
53
- * @since 2.1.0
54
- */
55
- do_action( 'bp_activity_mentions_prime_results' );
56
- }
57
- add_action( 'bp_enqueue_scripts', 'bp_activity_mentions_script' );
58
- add_action( 'bp_admin_enqueue_scripts', 'bp_activity_mentions_script' );
59
-
60
- /**
61
- * Bind the mentions listener to a wp_editor instance when TinyMCE initializes.
62
- *
63
- * @since 2.3.3
64
- *
65
- * @param array $settings An array with TinyMCE config.
66
- * @param string $editor_id Unique editor identifier, e.g. 'content'.
67
- * @return array $mceInit An array with TinyMCE config.
68
- */
69
- function bp_add_mentions_on_tinymce_init( $settings, $editor_id ) {
70
- // We only apply the mentions init to the visual post editor in the WP dashboard.
71
- if ( 'content' === $editor_id ) {
72
- $settings['init_instance_callback'] = 'window.bp.mentions.tinyMCEinit';
73
- }
74
-
75
- return $settings;
76
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/bp-activity-embeds.php DELETED
@@ -1,352 +0,0 @@
1
- <?php
2
- /**
3
- * Functions related to embedding single activity items externally.
4
- *
5
- * Relies on WordPress 4.5.
6
- *
7
- * @since 2.6.0
8
- *
9
- * @package BuddyPress
10
- * @subpackage ActivityEmbeds
11
- */
12
-
13
- // Exit if accessed directly.
14
- defined( 'ABSPATH' ) || exit;
15
-
16
- /**
17
- * Loads our activity oEmbed component.
18
- *
19
- * @since 2.6.0
20
- */
21
- function bp_activity_setup_oembed() {
22
- if ( version_compare( $GLOBALS['wp_version'], '4.5', '>=' ) && bp_is_active( 'activity', 'embeds' ) ) {
23
- buddypress()->activity->oembed = new BP_Activity_oEmbed_Extension;
24
- }
25
- }
26
- add_action( 'bp_loaded', 'bp_activity_setup_oembed' );
27
-
28
- /**
29
- * Catch links in embed excerpt so top.location.href can be added.
30
- *
31
- * Due to <iframe sandbox="allow-top-navigation">, links in embeds can only be
32
- * clicked if invoked with top.location.href via JS.
33
- *
34
- * @since 2.6.0
35
- *
36
- * @param string $text Embed excerpt
37
- * @return string
38
- */
39
- function bp_activity_embed_excerpt_onclick_location_filter( $text ) {
40
- return preg_replace_callback( '/<a\s+[^>]*href=\"([^\"]*)\"/iU', 'bp_activity_embed_excerpt_onclick_location_filter_callback', $text );
41
- }
42
- /**
43
- * Add onclick="top.location.href" to a link.
44
- *
45
- * @since 2.6.0
46
- *
47
- * @param array $matches Items matched by bp_activity_embed_excerpt_onclick_location_filter().
48
- * @return string
49
- */
50
- function bp_activity_embed_excerpt_onclick_location_filter_callback( $matches ) {
51
- return sprintf( '<a href="%1$s" onclick="top.location.href=\'%1$s\'"', $matches[1] );
52
- }
53
-
54
- /**
55
- * Add inline styles for BP activity embeds.
56
- *
57
- * @since 2.6.0
58
- */
59
- function bp_activity_embed_add_inline_styles() {
60
- if ( false === bp_is_single_activity() ) {
61
- return;
62
- }
63
-
64
- $min = bp_core_get_minified_asset_suffix();
65
-
66
- if ( is_rtl() ) {
67
- $css = bp_locate_template_asset( "css/embeds-activity-rtl{$min}.css" );
68
- } else {
69
- $css = bp_locate_template_asset( "css/embeds-activity{$min}.css" );
70
- }
71
-
72
- // Bail if file wasn't found.
73
- if ( false === $css ) {
74
- return;
75
- }
76
-
77
- // Grab contents of CSS file and do some rudimentary CSS protection.
78
- $css = file_get_contents( $css['file'] );
79
- $css = wp_kses( $css, array( "\'", '\"' ) );
80
-
81
- printf( '<style type="text/css">%s</style>', $css );
82
- }
83
- add_action( 'embed_head', 'bp_activity_embed_add_inline_styles', 20 );
84
-
85
- /**
86
- * Query for the activity item on the activity embed template.
87
- *
88
- * Basically a wrapper for {@link bp_has_activities()}, but allows us to
89
- * use the activity loop without requerying for it again.
90
- *
91
- * @since 2.6.0
92
- *
93
- * @param int $activity_id The activity ID.
94
- * @return bool
95
- */
96
- function bp_activity_embed_has_activity( $activity_id = 0 ) {
97
- global $activities_template;
98
-
99
- if ( empty( $activity_id ) ) {
100
- return false;
101
- }
102
-
103
- if ( ! empty( $activities_template->activities ) ) {
104
- $activity = (array) $activities_template->activities;
105
- $activity = reset( $activity );
106
-
107
- // No need to requery if we already got the embed activity
108
- if ( (int) $activity_id === $activity->id ) {
109
- return $activities_template->has_activities();
110
- }
111
- }
112
-
113
- return bp_has_activities( array(
114
- 'display_comments' => 'threaded',
115
- 'show_hidden' => true,
116
- 'include' => (int) $activity_id,
117
- ) );
118
- }
119
-
120
- /**
121
- * Outputs excerpt for an activity embed item.
122
- *
123
- * @since 2.6.0
124
- */
125
- function bp_activity_embed_excerpt( $content = '' ) {
126
- echo bp_activity_get_embed_excerpt( $content );
127
- }
128
-
129
- /**
130
- * Generates excerpt for an activity embed item.
131
- *
132
- * @since 2.6.0
133
- *
134
- * @param string $content The content to generate an excerpt for.
135
- * @return string
136
- */
137
- function bp_activity_get_embed_excerpt( $content = '' ) {
138
- if ( empty( $content ) && ! empty( $GLOBALS['activities_template']->in_the_loop ) ) {
139
- $content = $GLOBALS['activities_template']->activity->content;
140
- }
141
-
142
- /*
143
- * bp_activity_truncate_entry() includes the 'Read More' link, which is why
144
- * we're using this instead of bp_create_excerpt().
145
- */
146
- $content = html_entity_decode( $content );
147
- $content = bp_activity_truncate_entry( $content, array(
148
- 'html' => false,
149
- 'filter_shortcodes' => true,
150
- 'strip_tags' => true,
151
- 'force_truncate' => true
152
- ) );
153
-
154
- /**
155
- * Filter the activity embed excerpt.
156
- *
157
- * @since 2.6.0
158
- *
159
- * @var string $content Embed Excerpt.
160
- * @var string $unmodified_content Unmodified activity content.
161
- */
162
- return apply_filters( 'bp_activity_get_embed_excerpt', $content, $GLOBALS['activities_template']->activity->content );
163
- }
164
-
165
- /**
166
- * Outputs the first embedded item in the activity oEmbed template.
167
- *
168
- * @since 2.6.0
169
- */
170
- function bp_activity_embed_media() {
171
- // Bail if oEmbed request explicitly hides media.
172
- if ( isset( $_GET['hide_media'] ) && true == wp_validate_boolean( $_GET['hide_media'] ) ) {
173
- /**
174
- * Do something after media is rendered for an activity oEmbed item.
175
- *
176
- * @since 2.6.0
177
- */
178
- do_action( 'bp_activity_embed_after_media' );
179
-
180
- return;
181
- }
182
-
183
- /**
184
- * Should we display media in the oEmbed template?
185
- *
186
- * @since 2.6.0
187
- *
188
- * @param bool $retval Defaults to true.
189
- */
190
- $allow_media = apply_filters( 'bp_activity_embed_display_media', true );
191
-
192
- // Find oEmbeds from only WP registered providers.
193
- bp_remove_all_filters( 'oembed_providers' );
194
- $media = bp_core_extract_media_from_content( $GLOBALS['activities_template']->activity->content, 'embeds' );
195
- bp_restore_all_filters( 'oembed_providers' );
196
-
197
- // oEmbeds have precedence over inline video / audio.
198
- if ( isset( $media['embeds'] ) && true === $allow_media ) {
199
- // Autoembed first URL.
200
- $oembed_defaults = wp_embed_defaults();
201
- $oembed_args = array(
202
- 'width' => $oembed_defaults['width'],
203
- 'height' => $oembed_defaults['height'],
204
- 'discover' => true
205
- );
206
- $url = $media['embeds'][0]['url'];
207
- $cachekey = '_oembed_response_' . md5( $url . serialize( $oembed_args ) );
208
-
209
- // Try to fetch oEmbed response from meta.
210
- $oembed = bp_activity_get_meta( bp_get_activity_id(), $cachekey );
211
-
212
- // No cache, so fetch full oEmbed response now!
213
- if ( '' === $oembed ) {
214
- $o = _wp_oembed_get_object();
215
- $oembed = $o->fetch( $o->get_provider( $url, $oembed_args ), $url, $oembed_args );
216
-
217
- // Cache oEmbed response.
218
- bp_activity_update_meta( bp_get_activity_id(), $cachekey, $oembed );
219
- }
220
-
221
- $content = '';
222
-
223
- /**
224
- * Filters the default embed display max width.
225
- *
226
- * This is used if the oEmbed response does not return a thumbnail width.
227
- *
228
- * @since 2.6.0
229
- *
230
- * @param int $width.
231
- */
232
- $width = (int) apply_filters( 'bp_activity_embed_display_media_width', 550 );
233
-
234
- // Set thumbnail.
235
- if ( 'photo' === $oembed->type ) {
236
- $thumbnail = $oembed->url;
237
- } elseif ( isset( $oembed->thumbnail_url ) ) {
238
- $thumbnail = $oembed->thumbnail_url;
239
-
240
- /* Non-oEmbed standard attributes */
241
- // Mixcloud
242
- } elseif ( isset( $oembed->image ) ) {
243
- $thumbnail = $oembed->image;
244
- // ReverbNation
245
- } elseif ( isset( $oembed->{'thumbnail-url'} ) ) {
246
- $thumbnail = $oembed->{'thumbnail-url'};
247
- }
248
-
249
- // Display thumb and related oEmbed meta.
250
- if ( true === isset ( $thumbnail ) ) {
251
- $play_icon = $caption = '';
252
-
253
- // Add play icon for non-photos.
254
- if ( 'photo' !== $oembed->type ) {
255
- /**
256
- * ion-play icon from Ionicons.
257
- *
258
- * @link http://ionicons.com/
259
- * @license MIT
260
- */
261
- $play_icon = <<<EOD
262
- <svg id="Layer_1" style="enable-background:new 0 0 512 512;" version="1.1" viewBox="0 0 512 512" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M405.2,232.9L126.8,67.2c-3.4-2-6.9-3.2-10.9-3.2c-10.9,0-19.8,9-19.8,20H96v344h0.1c0,11,8.9,20,19.8,20 c4.1,0,7.5-1.4,11.2-3.4l278.1-165.5c6.6-5.5,10.8-13.8,10.8-23.1C416,246.7,411.8,238.5,405.2,232.9z"/></svg>
263
- EOD;
264
-
265
- $play_icon = sprintf( '<a rel="nofollow" class="play-btn" href="%1$s" onclick="top.location.href=\'%1$s\'">%2$s</a>', esc_url( $url ), $play_icon );
266
- }
267
-
268
- // Thumb width
269
- $thumb_width = isset( $oembed->thumbnail_width ) && 'photo' !== $oembed->type && (int) $oembed->thumbnail_width < 550 ? (int) $oembed->thumbnail_width : $width;
270
-
271
- $float_width = 350;
272
-
273
- // Set up thumb.
274
- $content = sprintf( '<div class="thumb" style="max-width:%1$spx">%2$s<a href="%3$s" rel="nofollow" onclick="top.location.href=\'%3$s\'"><img src="%4$s" /></a></div>', $thumb_width, $play_icon, esc_url( $url ), esc_url( $thumbnail ) );
275
-
276
- // Show title.
277
- if ( isset( $oembed->title ) ) {
278
- $caption .= sprintf( '<p class="caption-title"><strong>%s</strong></p>', apply_filters( 'single_post_title', $oembed->title ) );
279
- }
280
-
281
- // Show description (non-oEmbed standard)
282
- if ( isset( $oembed->description ) ) {
283
- $caption .= sprintf( '<div class="caption-description">%s</div>', apply_filters( 'bp_activity_get_embed_excerpt', $oembed->description ) );
284
- }
285
-
286
- // Show author info.
287
- if ( isset( $oembed->provider_name ) && isset( $oembed->author_name ) ) {
288
- /* translators: By [oEmbed author] on [oEmbed provider]. eg. By BuddyPress on YouTube. */
289
- $anchor_text = sprintf( __( 'By %1$s on %2$s', 'buddypress' ), $oembed->author_name, $oembed->provider_name );
290
-
291
- } elseif ( isset( $oembed->provider_name ) ) {
292
- $anchor_text = sprintf( __( 'View on %s', 'buddypress' ), $oembed->provider_name );
293
- }
294
-
295
- if ( true === isset( $anchor_text ) ) {
296
- $caption .= sprintf( '<a rel="nofollow" href="%1$s" onclick="top.location.href=\'%1$s\'">%2$s</a>', esc_url( $url ), apply_filters( 'the_title', $anchor_text ) );
297
- }
298
-
299
- // Set up caption.
300
- if ( '' !== $caption ) {
301
- $css_class = isset( $oembed->provider_name ) ? sprintf( ' provider-%s', sanitize_html_class( strtolower( $oembed->provider_name ) ) ) : '';
302
- $caption = sprintf( '<div class="caption%1$s" style="width:%2$s">%3$s</div>',
303
- $css_class,
304
- $thumb_width > $float_width ? 100 . '%' : round( ( $width - (int) $thumb_width ) / $width * 100 ) . '%',
305
- $caption
306
- );
307
-
308
- $content .= $caption;
309
- }
310
- }
311
-
312
- // Print rich content.
313
- if ( '' !== $content ) {
314
- printf( '<div class="bp-activity-embed-display-media %s" style="max-width:%spx">%s</div>',
315
- $thumb_width < $float_width ? 'two-col' : 'one-col',
316
- $thumb_width < $float_width ? $width : $thumb_width,
317
- $content
318
- );
319
- }
320
-
321
- // Video / audio.
322
- } elseif ( true === $allow_media ) {
323
- // Call BP_Embed if it hasn't already loaded.
324
- bp_embed_init();
325
-
326
- // Run shortcode and embed routine.
327
- $content = buddypress()->embed->run_shortcode( $GLOBALS['activities_template']->activity->content );
328
- $content = buddypress()->embed->autoembed( $content );
329
-
330
- // Try to find inline video / audio.
331
- $media = bp_core_extract_media_from_content( $content, 96 );
332
-
333
- // Video takes precedence. HTML5-only.
334
- if ( isset( $media['videos'] ) && 'shortcodes' === $media['videos'][0]['source'] ) {
335
- printf( '<video controls preload="metadata"><source src="%1$s"><p>%2$s</p></video>',
336
- esc_url( $media['videos'][0]['url'] ),
337
- esc_html__( 'Your browser does not support HTML5 video', 'buddypress' )
338
- );
339
-
340
- // No video? Try audio. HTML5-only.
341
- } elseif ( isset( $media['audio'] ) && 'shortcodes' === $media['audio'][0]['source'] ) {
342
- printf( '<audio controls preload="metadata"><source src="%1$s"><p>%2$s</p></audio>',
343
- esc_url( $media['audio'][0]['url'] ),
344
- esc_html__( 'Your browser does not support HTML5 audio', 'buddypress' )
345
- );
346
- }
347
-
348
- }
349
-
350
- /** This hook is documented in /bp-activity/bp-activity-embeds.php */
351
- do_action( 'bp_activity_embed_after_media' );
352
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/bp-activity-filters.php CHANGED
@@ -1,18 +1,6 @@
1
  <?php
2
- /**
3
- * Filters related to the Activity component.
4
- *
5
- * @package BuddyPress
6
- * @subpackage ActivityFilters
7
- * @since 1.0.0
8
- */
9
 
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /* Filters *******************************************************************/
14
-
15
- // Apply WordPress defined filters.
16
  add_filter( 'bp_get_activity_action', 'bp_activity_filter_kses', 1 );
17
  add_filter( 'bp_get_activity_content_body', 'bp_activity_filter_kses', 1 );
18
  add_filter( 'bp_get_activity_content', 'bp_activity_filter_kses', 1 );
@@ -22,7 +10,6 @@ add_filter( 'bp_get_activity_latest_update_excerpt', 'bp_activity_filter_kses',
22
  add_filter( 'bp_get_activity_feed_item_description', 'bp_activity_filter_kses', 1 );
23
  add_filter( 'bp_activity_content_before_save', 'bp_activity_filter_kses', 1 );
24
  add_filter( 'bp_activity_action_before_save', 'bp_activity_filter_kses', 1 );
25
- add_filter( 'bp_activity_latest_update_content', 'bp_activity_filter_kses', 1 );
26
 
27
  add_filter( 'bp_get_activity_action', 'force_balance_tags' );
28
  add_filter( 'bp_get_activity_content_body', 'force_balance_tags' );
@@ -33,17 +20,12 @@ add_filter( 'bp_get_activity_feed_item_description', 'force_balance_tags' );
33
  add_filter( 'bp_activity_content_before_save', 'force_balance_tags' );
34
  add_filter( 'bp_activity_action_before_save', 'force_balance_tags' );
35
 
36
- if ( function_exists( 'wp_encode_emoji' ) ) {
37
- add_filter( 'bp_activity_content_before_save', 'wp_encode_emoji' );
38
- }
39
-
40
  add_filter( 'bp_get_activity_action', 'wptexturize' );
41
  add_filter( 'bp_get_activity_content_body', 'wptexturize' );
42
  add_filter( 'bp_get_activity_content', 'wptexturize' );
43
  add_filter( 'bp_get_activity_parent_content', 'wptexturize' );
44
  add_filter( 'bp_get_activity_latest_update', 'wptexturize' );
45
  add_filter( 'bp_get_activity_latest_update_excerpt', 'wptexturize' );
46
- add_filter( 'bp_activity_get_embed_excerpt', 'wptexturize' );
47
 
48
  add_filter( 'bp_get_activity_action', 'convert_smilies' );
49
  add_filter( 'bp_get_activity_content_body', 'convert_smilies' );
@@ -51,7 +33,6 @@ add_filter( 'bp_get_activity_content', 'convert_smilies' );
51
  add_filter( 'bp_get_activity_parent_content', 'convert_smilies' );
52
  add_filter( 'bp_get_activity_latest_update', 'convert_smilies' );
53
  add_filter( 'bp_get_activity_latest_update_excerpt', 'convert_smilies' );
54
- add_filter( 'bp_activity_get_embed_excerpt', 'convert_smilies' );
55
 
56
  add_filter( 'bp_get_activity_action', 'convert_chars' );
57
  add_filter( 'bp_get_activity_content_body', 'convert_chars' );
@@ -59,35 +40,30 @@ add_filter( 'bp_get_activity_content', 'convert_chars' );
59
  add_filter( 'bp_get_activity_parent_content', 'convert_chars' );
60
  add_filter( 'bp_get_activity_latest_update', 'convert_chars' );
61
  add_filter( 'bp_get_activity_latest_update_excerpt', 'convert_chars' );
62
- add_filter( 'bp_activity_get_embed_excerpt', 'convert_chars' );
63
 
64
  add_filter( 'bp_get_activity_action', 'wpautop' );
65
  add_filter( 'bp_get_activity_content_body', 'wpautop' );
66
  add_filter( 'bp_get_activity_content', 'wpautop' );
67
  add_filter( 'bp_get_activity_feed_item_description', 'wpautop' );
68
- add_filter( 'bp_activity_get_embed_excerpt', 'wpautop' );
69
-
70
- add_filter( 'bp_get_activity_action', 'make_clickable', 9 );
71
- add_filter( 'bp_get_activity_content_body', 'make_clickable', 9 );
72
- add_filter( 'bp_get_activity_content', 'make_clickable', 9 );
73
- add_filter( 'bp_get_activity_parent_content', 'make_clickable', 9 );
74
- add_filter( 'bp_get_activity_latest_update', 'make_clickable', 9 );
75
- add_filter( 'bp_get_activity_latest_update_excerpt', 'make_clickable', 9 );
76
- add_filter( 'bp_get_activity_feed_item_description', 'make_clickable', 9 );
77
- add_filter( 'bp_activity_get_embed_excerpt', 'make_clickable', 9 );
78
 
79
- add_filter( 'bp_acomment_name', 'stripslashes_deep', 5 );
80
- add_filter( 'bp_get_activity_action', 'stripslashes_deep', 5 );
81
- add_filter( 'bp_get_activity_content', 'stripslashes_deep', 5 );
82
- add_filter( 'bp_get_activity_content_body', 'stripslashes_deep', 5 );
83
- add_filter( 'bp_get_activity_parent_content', 'stripslashes_deep', 5 );
84
- add_filter( 'bp_get_activity_latest_update', 'stripslashes_deep', 5 );
85
- add_filter( 'bp_get_activity_latest_update_excerpt', 'stripslashes_deep', 5 );
86
- add_filter( 'bp_get_activity_feed_item_description', 'stripslashes_deep', 5 );
87
-
88
- add_filter( 'bp_activity_primary_link_before_save', 'esc_url_raw' );
89
-
90
- // Apply BuddyPress-defined filters.
 
 
 
 
 
 
91
  add_filter( 'bp_get_activity_content', 'bp_activity_make_nofollow_filter' );
92
  add_filter( 'bp_get_activity_content_body', 'bp_activity_make_nofollow_filter' );
93
  add_filter( 'bp_get_activity_parent_content', 'bp_activity_make_nofollow_filter' );
@@ -95,742 +71,74 @@ add_filter( 'bp_get_activity_latest_update', 'bp_activity_make_nofollow_
95
  add_filter( 'bp_get_activity_latest_update_excerpt', 'bp_activity_make_nofollow_filter' );
96
  add_filter( 'bp_get_activity_feed_item_description', 'bp_activity_make_nofollow_filter' );
97
 
98
- add_filter( 'pre_comment_content', 'bp_activity_at_name_filter' );
99
- add_filter( 'group_forum_topic_text_before_save', 'bp_activity_at_name_filter' );
100
- add_filter( 'group_forum_post_text_before_save', 'bp_activity_at_name_filter' );
101
- add_filter( 'the_content', 'bp_activity_at_name_filter' );
102
- add_filter( 'bp_activity_get_embed_excerpt', 'bp_activity_at_name_filter' );
103
-
104
- add_filter( 'bp_get_activity_parent_content', 'bp_create_excerpt' );
105
-
106
- add_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
107
- add_filter( 'bp_get_activity_content', 'bp_activity_truncate_entry', 5 );
108
-
109
- add_filter( 'bp_get_total_favorite_count_for_user', 'bp_core_number_format' );
110
- add_filter( 'bp_get_total_mention_count_for_user', 'bp_core_number_format' );
111
 
112
- add_filter( 'bp_activity_get_embed_excerpt', 'bp_activity_embed_excerpt_onclick_location_filter', 9 );
113
-
114
- /* Actions *******************************************************************/
115
-
116
- // At-name filter.
117
- add_action( 'bp_activity_before_save', 'bp_activity_at_name_filter_updates' );
118
-
119
- // Activity stream moderation.
120
- add_action( 'bp_activity_before_save', 'bp_activity_check_moderation_keys', 2, 1 );
121
- add_action( 'bp_activity_before_save', 'bp_activity_check_blacklist_keys', 2, 1 );
122
-
123
- /** Functions *****************************************************************/
124
-
125
- /**
126
- * Types of activity stream items to moderate.
127
- *
128
- * @since 1.6.0
129
- *
130
- * @return array $types List of the activity types to moderate.
131
- */
132
- function bp_activity_get_moderated_activity_types() {
133
- $types = array(
134
- 'activity_comment',
135
- 'activity_update'
136
- );
137
-
138
- /**
139
- * Filters the default activity types that BuddyPress should moderate.
140
- *
141
- * @since 1.6.0
142
- *
143
- * @param array $types Default activity types to moderate.
144
- */
145
- return apply_filters( 'bp_activity_check_activity_types', $types );
146
- }
147
-
148
- /**
149
- * Moderate the posted activity item, if it contains moderate keywords.
150
- *
151
- * @since 1.6.0
152
- *
153
- * @param BP_Activity_Activity $activity The activity object to check.
154
- */
155
- function bp_activity_check_moderation_keys( $activity ) {
156
-
157
- // Only check specific types of activity updates.
158
- if ( ! in_array( $activity->type, bp_activity_get_moderated_activity_types() ) ) {
159
- return;
160
- }
161
 
162
- // Send back the error so activity update fails.
163
- // @todo This is temporary until some kind of moderation is built.
164
- $moderate = bp_core_check_for_moderation( $activity->user_id, '', $activity->content, 'wp_error' );
165
- if ( is_wp_error( $moderate ) ) {
166
- $activity->errors = $moderate;
167
-
168
- // Backpat.
169
- $activity->component = false;
170
- }
171
- }
172
-
173
- /**
174
- * Mark the posted activity as spam, if it contains blacklist keywords.
175
- *
176
- * @since 1.6.0
177
- *
178
- * @param BP_Activity_Activity $activity The activity object to check.
179
- */
180
- function bp_activity_check_blacklist_keys( $activity ) {
181
-
182
- // Only check specific types of activity updates.
183
- if ( ! in_array( $activity->type, bp_activity_get_moderated_activity_types() ) ) {
184
- return;
185
- }
186
-
187
- // Send back the error so activity update fails.
188
- // @todo This is temporary until some kind of trash status is built.
189
- $blacklist = bp_core_check_for_blacklist( $activity->user_id, '', $activity->content, 'wp_error' );
190
- if ( is_wp_error( $blacklist ) ) {
191
- $activity->errors = $blacklist;
192
-
193
- // Backpat.
194
- $activity->component = false;
195
- }
196
- }
197
-
198
- /**
199
- * Custom kses filtering for activity content.
200
- *
201
- * @since 1.1.0
202
- *
203
- * @param string $content The activity content.
204
- * @return string $content Filtered activity content.
205
- */
206
  function bp_activity_filter_kses( $content ) {
207
  global $allowedtags;
208
 
209
  $activity_allowedtags = $allowedtags;
210
- $activity_allowedtags['a']['aria-label'] = array();
211
- $activity_allowedtags['a']['class'] = array();
212
- $activity_allowedtags['a']['data-bp-tooltip'] = array();
213
- $activity_allowedtags['a']['id'] = array();
214
- $activity_allowedtags['a']['rel'] = array();
215
- $activity_allowedtags['a']['title'] = array();
216
-
217
- $activity_allowedtags['b'] = array();
218
- $activity_allowedtags['code'] = array();
219
- $activity_allowedtags['i'] = array();
220
-
221
  $activity_allowedtags['img'] = array();
222
  $activity_allowedtags['img']['src'] = array();
223
  $activity_allowedtags['img']['alt'] = array();
 
224
  $activity_allowedtags['img']['width'] = array();
225
  $activity_allowedtags['img']['height'] = array();
226
  $activity_allowedtags['img']['class'] = array();
227
  $activity_allowedtags['img']['id'] = array();
 
 
228
 
229
- $activity_allowedtags['span'] = array();
230
- $activity_allowedtags['span']['class'] = array();
231
- $activity_allowedtags['span']['data-livestamp'] = array();
232
-
233
- $activity_allowedtags['ul'] = array();
234
- $activity_allowedtags['ol'] = array();
235
- $activity_allowedtags['li'] = array();
236
-
237
- /**
238
- * Filters the allowed HTML tags for BuddyPress Activity content.
239
- *
240
- * @since 1.2.0
241
- *
242
- * @param array $value Array of allowed HTML tags and attributes.
243
- */
244
  $activity_allowedtags = apply_filters( 'bp_activity_allowed_tags', $activity_allowedtags );
245
  return wp_kses( $content, $activity_allowedtags );
246
  }
247
 
248
- /**
249
- * Find and link @-mentioned users in the contents of a given item.
250
- *
251
- * @since 1.2.0
252
- *
253
- * @param string $content The contents of a given item.
254
- * @param int $activity_id The activity id. Deprecated.
255
- * @return string $content Content filtered for mentions.
256
- */
257
- function bp_activity_at_name_filter( $content, $activity_id = 0 ) {
258
-
259
- // Are mentions disabled?
260
- if ( ! bp_activity_do_mentions() ) {
261
- return $content;
262
- }
263
 
264
- // Try to find mentions.
265
- $usernames = bp_activity_find_mentions( $content );
266
 
267
- // No mentions? Stop now!
268
- if ( empty( $usernames ) )
269
  return $content;
270
 
271
- // We don't want to link @mentions that are inside of links, so we
272
- // temporarily remove them.
273
- $replace_count = 0;
274
- $replacements = array();
275
- foreach ( $usernames as $username ) {
276
- // Prevent @ name linking inside <a> tags.
277
- preg_match_all( '/(<a.*?(?!<\/a>)@' . $username . '.*?<\/a>)/', $content, $content_matches );
278
- if ( ! empty( $content_matches[1] ) ) {
279
- foreach ( $content_matches[1] as $replacement ) {
280
- $replacements[ '#BPAN' . $replace_count ] = $replacement;
281
- $content = str_replace( $replacement, '#BPAN' . $replace_count, $content );
282
- $replace_count++;
283
- }
284
- }
285
- }
286
 
287
- // Linkify the mentions with the username.
288
- foreach ( (array) $usernames as $user_id => $username ) {
289
- $content = preg_replace( '/(@' . $username . '\b)/', "<a class='bp-suggestions-mention' href='" . bp_core_get_user_domain( $user_id ) . "' rel='nofollow'>@$username</a>", $content );
290
- }
291
 
292
- // Put everything back.
293
- if ( ! empty( $replacements ) ) {
294
- foreach ( $replacements as $placeholder => $original ) {
295
- $content = str_replace( $placeholder, $original, $content );
296
- }
297
  }
298
 
299
- // Return the content.
300
  return $content;
301
  }
 
 
 
 
 
 
302
 
303
- /**
304
- * Catch mentions in an activity item before it is saved into the database.
305
- *
306
- * If mentions are found, replace @mention text with user links and add our
307
- * hook to send mention notifications after the activity item is saved.
308
- *
309
- * @since 1.5.0
310
- *
311
- * @param BP_Activity_Activity $activity Activity Object.
312
- */
313
- function bp_activity_at_name_filter_updates( $activity ) {
314
- // Are mentions disabled?
315
- if ( ! bp_activity_do_mentions() ) {
316
- return;
317
- }
318
-
319
- // If activity was marked as spam, stop the rest of this function.
320
- if ( ! empty( $activity->is_spam ) )
321
- return;
322
-
323
- // Try to find mentions.
324
- $usernames = bp_activity_find_mentions( $activity->content );
325
-
326
- // We have mentions!
327
- if ( ! empty( $usernames ) ) {
328
- // Replace @mention text with userlinks.
329
- foreach( (array) $usernames as $user_id => $username ) {
330
- $activity->content = preg_replace( '/(@' . $username . '\b)/', "<a class='bp-suggestions-mention' href='" . bp_core_get_user_domain( $user_id ) . "' rel='nofollow'>@$username</a>", $activity->content );
331
- }
332
-
333
- // Add our hook to send @mention emails after the activity item is saved.
334
- add_action( 'bp_activity_after_save', 'bp_activity_at_name_send_emails' );
335
-
336
- // Temporary variable to avoid having to run bp_activity_find_mentions() again.
337
- buddypress()->activity->mentioned_users = $usernames;
338
- }
339
- }
340
-
341
- /**
342
- * Sends emails and BP notifications for users @-mentioned in an activity item.
343
- *
344
- * @since 1.7.0
345
- *
346
- * @param BP_Activity_Activity $activity The BP_Activity_Activity object.
347
- */
348
- function bp_activity_at_name_send_emails( $activity ) {
349
- // Are mentions disabled?
350
- if ( ! bp_activity_do_mentions() ) {
351
- return;
352
- }
353
-
354
- // If our temporary variable doesn't exist, stop now.
355
- if ( empty( buddypress()->activity->mentioned_users ) )
356
- return;
357
-
358
- // Grab our temporary variable from bp_activity_at_name_filter_updates().
359
- $usernames = buddypress()->activity->mentioned_users;
360
-
361
- // Get rid of temporary variable.
362
- unset( buddypress()->activity->mentioned_users );
363
-
364
- // Send @mentions and setup BP notifications.
365
- foreach( (array) $usernames as $user_id => $username ) {
366
-
367
- /**
368
- * Filters BuddyPress' ability to send email notifications for @mentions.
369
- *
370
- * @since 1.6.0
371
- * @since 2.5.0 Introduced `$user_id` and `$activity` parameters.
372
- *
373
- * @param bool $value Whether or not BuddyPress should send a notification to the mentioned users.
374
- * @param array $usernames Array of users potentially notified.
375
- * @param int $user_id ID of the current user being notified.
376
- * @param BP_Activity_Activity $activity Activity object.
377
- */
378
- if ( apply_filters( 'bp_activity_at_name_do_notifications', true, $usernames, $user_id, $activity ) ) {
379
- bp_activity_at_message_notification( $activity->id, $user_id );
380
- }
381
-
382
- // Updates mention count for the user.
383
- bp_activity_update_mention_count_for_user( $user_id, $activity->id );
384
- }
385
- }
386
-
387
- /**
388
- * Catch links in activity text so rel=nofollow can be added.
389
- *
390
- * @since 1.2.0
391
- *
392
- * @param string $text Activity text.
393
- * @return string $text Text with rel=nofollow added to any links.
394
- */
395
  function bp_activity_make_nofollow_filter( $text ) {
396
  return preg_replace_callback( '|<a (.+?)>|i', 'bp_activity_make_nofollow_filter_callback', $text );
397
  }
398
-
399
- /**
400
- * Add rel=nofollow to a link.
401
- *
402
- * @since 1.2.0
403
- *
404
- * @param array $matches Items matched by preg_replace_callback() in bp_activity_make_nofollow_filter().
405
- * @return string $text Link with rel=nofollow added.
406
- */
407
  function bp_activity_make_nofollow_filter_callback( $matches ) {
408
  $text = $matches[1];
409
  $text = str_replace( array( ' rel="nofollow"', " rel='nofollow'"), '', $text );
410
  return "<a $text rel=\"nofollow\">";
411
  }
412
 
413
- /**
414
- * Truncate long activity entries when viewed in activity streams.
415
- *
416
- * This method can only be used inside the Activity loop.
417
- *
418
- * @since 1.5.0
419
- * @since 2.6.0 Added $args parameter.
420
- *
421
- * @param string $text The original activity entry text.
422
- * @param array $args {
423
- * Optional parameters. See $options argument of {@link bp_create_excerpt()}
424
- * for all available parameters.
425
- * }
426
- * @return string $excerpt The truncated text.
427
- */
428
- function bp_activity_truncate_entry( $text, $args = array() ) {
429
- global $activities_template;
430
-
431
- /**
432
- * Provides a filter that lets you choose whether to skip this filter on a per-activity basis.
433
- *
434
- * @since 2.3.0
435
- *
436
- * @param bool $value If true, text should be checked to see if it needs truncating.
437
- */
438
- $maybe_truncate_text = apply_filters(
439
- 'bp_activity_maybe_truncate_entry',
440
- isset( $activities_template->activity->type ) && ! in_array( $activities_template->activity->type, array( 'new_blog_post', ), true )
441
- );
442
-
443
- // The full text of the activity update should always show on the single activity screen.
444
- if ( empty( $args['force_truncate'] ) && ( ! $maybe_truncate_text || bp_is_single_activity() ) ) {
445
- return $text;
446
- }
447
-
448
- /**
449
- * Filters the appended text for the activity excerpt.
450
- *
451
- * @since 1.5.0
452
- *
453
- * @param string $value Internationalized "Read more" text.
454
- */
455
- $append_text = apply_filters( 'bp_activity_excerpt_append_text', __( '[Read more]', 'buddypress' ) );
456
-
457
- $excerpt_length = bp_activity_get_excerpt_length();
458
-
459
- $args = wp_parse_args( $args, array( 'ending' => __( '&hellip;', 'buddypress' ) ) );
460
-
461
- // Run the text through the excerpt function. If it's too short, the original text will be returned.
462
- $excerpt = bp_create_excerpt( $text, $excerpt_length, $args );
463
-
464
- /*
465
- * If the text returned by bp_create_excerpt() is different from the original text (ie it's
466
- * been truncated), add the "Read More" link. Note that bp_create_excerpt() is stripping
467
- * shortcodes, so we have strip them from the $text before the comparison.
468
- */
469
- if ( strlen( $excerpt ) < strlen( strip_shortcodes( $text ) ) ) {
470
- $id = !empty( $activities_template->activity->current_comment->id ) ? 'acomment-read-more-' . $activities_template->activity->current_comment->id : 'activity-read-more-' . bp_get_activity_id();
471
-
472
- $excerpt = sprintf( '%1$s<span class="activity-read-more" id="%2$s"><a href="%3$s" rel="nofollow">%4$s</a></span>', $excerpt, $id, bp_get_activity_thread_permalink(), $append_text );
473
- }
474
-
475
- /**
476
- * Filters the composite activity excerpt entry.
477
- *
478
- * @since 1.5.0
479
- *
480
- * @param string $excerpt Excerpt text and markup to be displayed.
481
- * @param string $text The original activity entry text.
482
- * @param string $append_text The final append text applied.
483
- */
484
- return apply_filters( 'bp_activity_truncate_entry', $excerpt, $text, $append_text );
485
- }
486
-
487
- /**
488
- * Include extra JavaScript dependencies for activity component.
489
- *
490
- * @since 2.0.0
491
- *
492
- * @param array $js_handles The original dependencies.
493
- * @return array $js_handles The new dependencies.
494
- */
495
- function bp_activity_get_js_dependencies( $js_handles = array() ) {
496
- if ( bp_activity_do_heartbeat() ) {
497
- $js_handles[] = 'heartbeat';
498
- }
499
-
500
- return $js_handles;
501
- }
502
- add_filter( 'bp_core_get_js_dependencies', 'bp_activity_get_js_dependencies', 10, 1 );
503
-
504
- /**
505
- * Add a just-posted classes to the most recent activity item.
506
- *
507
- * We use these classes to avoid pagination issues when items are loaded
508
- * dynamically into the activity stream.
509
- *
510
- * @since 2.0.0
511
- *
512
- * @param string $classes Array of classes for most recent activity item.
513
- * @return string $classes
514
- */
515
- function bp_activity_newest_class( $classes = '' ) {
516
- $bp = buddypress();
517
-
518
- if ( ! empty( $bp->activity->last_recorded ) && $bp->activity->last_recorded == bp_get_activity_date_recorded() ) {
519
- $classes .= ' new-update';
520
- }
521
-
522
- $classes .= ' just-posted';
523
- return $classes;
524
- }
525
-
526
- /**
527
- * Check if Activity Heartbeat feature i on to add a timestamp class.
528
- *
529
- * @since 2.0.0
530
- *
531
- * @param string $classes Array of classes for timestamp.
532
- * @return string $classes
533
- */
534
- function bp_activity_timestamp_class( $classes = '' ) {
535
-
536
- if ( ! bp_activity_do_heartbeat() ) {
537
- return $classes;
538
- }
539
-
540
- $activity_date = bp_get_activity_date_recorded();
541
-
542
- if ( empty( $activity_date ) ) {
543
- return $classes;
544
- }
545
-
546
- $classes .= ' date-recorded-' . strtotime( $activity_date );
547
-
548
- return $classes;
549
- }
550
- add_filter( 'bp_get_activity_css_class', 'bp_activity_timestamp_class', 9, 1 );
551
-
552
- /**
553
- * Use WordPress Heartbeat API to check for latest activity update.
554
- *
555
- * @since 2.0.0
556
- *
557
- * @param array $response Array containing Heartbeat API response.
558
- * @param array $data Array containing data for Heartbeat API response.
559
- * @return array $response
560
- */
561
- function bp_activity_heartbeat_last_recorded( $response = array(), $data = array() ) {
562
- if ( empty( $data['bp_activity_last_recorded'] ) ) {
563
- return $response;
564
- }
565
-
566
- // Use the querystring argument stored in the cookie (to preserve
567
- // filters), but force the offset to get only new items.
568
- $activity_latest_args = bp_parse_args(
569
- bp_ajax_querystring( 'activity' ),
570
- array( 'since' => date( 'Y-m-d H:i:s', $data['bp_activity_last_recorded'] ) ),
571
- 'activity_latest_args'
572
- );
573
-
574
- if ( ! empty( $data['bp_activity_last_recorded_search_terms'] ) && empty( $activity_latest_args['search_terms'] ) ) {
575
- $activity_latest_args['search_terms'] = addslashes( $data['bp_activity_last_recorded_search_terms'] );
576
- }
577
-
578
- $newest_activities = array();
579
- $last_activity_recorded = 0;
580
-
581
- // Temporarily add a just-posted class for new activity items.
582
- add_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
583
-
584
- ob_start();
585
- if ( bp_has_activities( $activity_latest_args ) ) {
586
- while ( bp_activities() ) {
587
- bp_the_activity();
588
-
589
- $atime = strtotime( bp_get_activity_date_recorded() );
590
- if ( $last_activity_recorded < $atime ) {
591
- $last_activity_recorded = $atime;
592
- }
593
-
594
- bp_get_template_part( 'activity/entry' );
595
- }
596
- }
597
-
598
- $newest_activities['activities'] = ob_get_contents();
599
- $newest_activities['last_recorded'] = $last_activity_recorded;
600
- ob_end_clean();
601
-
602
- // Remove the temporary filter.
603
- remove_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10 );
604
-
605
- if ( ! empty( $newest_activities['last_recorded'] ) ) {
606
- $response['bp_activity_newest_activities'] = $newest_activities;
607
- }
608
-
609
- return $response;
610
- }
611
- add_filter( 'heartbeat_received', 'bp_activity_heartbeat_last_recorded', 10, 2 );
612
- add_filter( 'heartbeat_nopriv_received', 'bp_activity_heartbeat_last_recorded', 10, 2 );
613
-
614
- /**
615
- * Set the strings for WP HeartBeat API where needed.
616
- *
617
- * @since 2.0.0
618
- *
619
- * @param array $strings Localized strings.
620
- * @return array $strings
621
- */
622
- function bp_activity_heartbeat_strings( $strings = array() ) {
623
-
624
- if ( ! bp_activity_do_heartbeat() ) {
625
- return $strings;
626
- }
627
-
628
- $global_pulse = 0;
629
-
630
- /**
631
- * Filter that checks whether the global heartbeat settings already exist.
632
- *
633
- * @since 2.0.0
634
- *
635
- * @param array $value Heartbeat settings array.
636
- */
637
- $heartbeat_settings = apply_filters( 'heartbeat_settings', array() );
638
- if ( ! empty( $heartbeat_settings['interval'] ) ) {
639
- // 'Fast' is 5
640
- $global_pulse = is_numeric( $heartbeat_settings['interval'] ) ? absint( $heartbeat_settings['interval'] ) : 5;
641
- }
642
-
643
- /**
644
- * Filters the pulse frequency to be used for the BuddyPress Activity heartbeat.
645
- *
646
- * @since 2.0.0
647
- *
648
- * @param int $value The frequency in seconds between pulses.
649
- */
650
- $bp_activity_pulse = apply_filters( 'bp_activity_heartbeat_pulse', 15 );
651
-
652
- /**
653
- * Use the global pulse value unless:
654
- * a. the BP-specific value has been specifically filtered, or
655
- * b. it doesn't exist (ie, BP will be the only one using the heartbeat,
656
- * so we're responsible for enabling it)
657
- */
658
- if ( has_filter( 'bp_activity_heartbeat_pulse' ) || empty( $global_pulse ) ) {
659
- $pulse = $bp_activity_pulse;
660
- } else {
661
- $pulse = $global_pulse;
662
- }
663
-
664
- $strings = array_merge( $strings, array(
665
- 'newest' => __( 'Load Newest', 'buddypress' ),
666
- 'pulse' => absint( $pulse ),
667
- ) );
668
-
669
- return $strings;
670
- }
671
- add_filter( 'bp_core_get_js_strings', 'bp_activity_heartbeat_strings', 10, 1 );
672
-
673
- /** Scopes ********************************************************************/
674
-
675
- /**
676
- * Set up activity arguments for use with the 'just-me' scope.
677
- *
678
- * @since 2.2.0
679
- *
680
- * @param array $retval Empty array by default.
681
- * @param array $filter Current activity arguments.
682
- * @return array $retval
683
- */
684
- function bp_activity_filter_just_me_scope( $retval = array(), $filter = array() ) {
685
-
686
- // Determine the user_id.
687
- if ( ! empty( $filter['user_id'] ) ) {
688
- $user_id = $filter['user_id'];
689
- } else {
690
- $user_id = bp_displayed_user_id()
691
- ? bp_displayed_user_id()
692
- : bp_loggedin_user_id();
693
- }
694
-
695
- // Should we show all items regardless of sitewide visibility?
696
- $show_hidden = array();
697
- if ( ! empty( $user_id ) && $user_id !== bp_loggedin_user_id() ) {
698
- $show_hidden = array(
699
- 'column' => 'hide_sitewide',
700
- 'value' => 0
701
- );
702
- }
703
-
704
- $retval = array(
705
- 'relation' => 'AND',
706
- array(
707
- 'column' => 'user_id',
708
- 'value' => $user_id
709
- ),
710
- $show_hidden,
711
-
712
- // Overrides.
713
- 'override' => array(
714
- 'display_comments' => 'stream',
715
- 'filter' => array( 'user_id' => 0 ),
716
- 'show_hidden' => true
717
- ),
718
- );
719
-
720
- return $retval;
721
- }
722
- add_filter( 'bp_activity_set_just-me_scope_args', 'bp_activity_filter_just_me_scope', 10, 2 );
723
-
724
- /**
725
- * Set up activity arguments for use with the 'favorites' scope.
726
- *
727
- * @since 2.2.0
728
- *
729
- * @param array $retval Empty array by default.
730
- * @param array $filter Current activity arguments.
731
- * @return array $retval
732
- */
733
- function bp_activity_filter_favorites_scope( $retval = array(), $filter = array() ) {
734
-
735
- // Determine the user_id.
736
- if ( ! empty( $filter['user_id'] ) ) {
737
- $user_id = $filter['user_id'];
738
- } else {
739
- $user_id = bp_displayed_user_id()
740
- ? bp_displayed_user_id()
741
- : bp_loggedin_user_id();
742
- }
743
-
744
- // Determine the favorites.
745
- $favs = bp_activity_get_user_favorites( $user_id );
746
- if ( empty( $favs ) ) {
747
- $favs = array( 0 );
748
- }
749
-
750
- // Should we show all items regardless of sitewide visibility?
751
- $show_hidden = array();
752
- if ( ! empty( $user_id ) && ( $user_id !== bp_loggedin_user_id() ) ) {
753
- $show_hidden = array(
754
- 'column' => 'hide_sitewide',
755
- 'value' => 0
756
- );
757
- }
758
-
759
- $retval = array(
760
- 'relation' => 'AND',
761
- array(
762
- 'column' => 'id',
763
- 'compare' => 'IN',
764
- 'value' => (array) $favs
765
- ),
766
- $show_hidden,
767
-
768
- // Overrides.
769
- 'override' => array(
770
- 'display_comments' => true,
771
- 'filter' => array( 'user_id' => 0 ),
772
- 'show_hidden' => true
773
- ),
774
- );
775
-
776
- return $retval;
777
- }
778
- add_filter( 'bp_activity_set_favorites_scope_args', 'bp_activity_filter_favorites_scope', 10, 2 );
779
-
780
-
781
- /**
782
- * Set up activity arguments for use with the 'favorites' scope.
783
- *
784
- * @since 2.2.0
785
- *
786
- * @param array $retval Empty array by default.
787
- * @param array $filter Current activity arguments.
788
- * @return array $retval
789
- */
790
- function bp_activity_filter_mentions_scope( $retval = array(), $filter = array() ) {
791
-
792
- // Are mentions disabled?
793
- if ( ! bp_activity_do_mentions() ) {
794
- return $retval;
795
- }
796
-
797
- // Determine the user_id.
798
- if ( ! empty( $filter['user_id'] ) ) {
799
- $user_id = $filter['user_id'];
800
- } else {
801
- $user_id = bp_displayed_user_id()
802
- ? bp_displayed_user_id()
803
- : bp_loggedin_user_id();
804
- }
805
-
806
- // Should we show all items regardless of sitewide visibility?
807
- $show_hidden = array();
808
- if ( ! empty( $user_id ) && $user_id !== bp_loggedin_user_id() ) {
809
- $show_hidden = array(
810
- 'column' => 'hide_sitewide',
811
- 'value' => 0
812
- );
813
- }
814
-
815
- $retval = array(
816
- 'relation' => 'AND',
817
- array(
818
- 'column' => 'content',
819
- 'compare' => 'LIKE',
820
-
821
- // Start search at @ symbol and stop search at closing tag delimiter.
822
- 'value' => '@' . bp_activity_get_user_mentionname( $user_id ) . '<'
823
- ),
824
- $show_hidden,
825
-
826
- // Overrides.
827
- 'override' => array(
828
- 'display_comments' => 'stream',
829
- 'filter' => array( 'user_id' => 0 ),
830
- 'show_hidden' => true
831
- ),
832
- );
833
-
834
- return $retval;
835
- }
836
- add_filter( 'bp_activity_set_mentions_scope_args', 'bp_activity_filter_mentions_scope', 10, 2 );
1
  <?php
 
 
 
 
 
 
 
2
 
3
+ /* Apply WordPress defined filters */
 
 
 
 
 
4
  add_filter( 'bp_get_activity_action', 'bp_activity_filter_kses', 1 );
5
  add_filter( 'bp_get_activity_content_body', 'bp_activity_filter_kses', 1 );
6
  add_filter( 'bp_get_activity_content', 'bp_activity_filter_kses', 1 );
10
  add_filter( 'bp_get_activity_feed_item_description', 'bp_activity_filter_kses', 1 );
11
  add_filter( 'bp_activity_content_before_save', 'bp_activity_filter_kses', 1 );
12
  add_filter( 'bp_activity_action_before_save', 'bp_activity_filter_kses', 1 );
 
13
 
14
  add_filter( 'bp_get_activity_action', 'force_balance_tags' );
15
  add_filter( 'bp_get_activity_content_body', 'force_balance_tags' );
20
  add_filter( 'bp_activity_content_before_save', 'force_balance_tags' );
21
  add_filter( 'bp_activity_action_before_save', 'force_balance_tags' );
22
 
 
 
 
 
23
  add_filter( 'bp_get_activity_action', 'wptexturize' );
24
  add_filter( 'bp_get_activity_content_body', 'wptexturize' );
25
  add_filter( 'bp_get_activity_content', 'wptexturize' );
26
  add_filter( 'bp_get_activity_parent_content', 'wptexturize' );
27
  add_filter( 'bp_get_activity_latest_update', 'wptexturize' );
28
  add_filter( 'bp_get_activity_latest_update_excerpt', 'wptexturize' );
 
29
 
30
  add_filter( 'bp_get_activity_action', 'convert_smilies' );
31
  add_filter( 'bp_get_activity_content_body', 'convert_smilies' );
33
  add_filter( 'bp_get_activity_parent_content', 'convert_smilies' );
34
  add_filter( 'bp_get_activity_latest_update', 'convert_smilies' );
35
  add_filter( 'bp_get_activity_latest_update_excerpt', 'convert_smilies' );
 
36
 
37
  add_filter( 'bp_get_activity_action', 'convert_chars' );
38
  add_filter( 'bp_get_activity_content_body', 'convert_chars' );
40
  add_filter( 'bp_get_activity_parent_content', 'convert_chars' );
41
  add_filter( 'bp_get_activity_latest_update', 'convert_chars' );
42
  add_filter( 'bp_get_activity_latest_update_excerpt', 'convert_chars' );
 
43
 
44
  add_filter( 'bp_get_activity_action', 'wpautop' );
45
  add_filter( 'bp_get_activity_content_body', 'wpautop' );
46
  add_filter( 'bp_get_activity_content', 'wpautop' );
47
  add_filter( 'bp_get_activity_feed_item_description', 'wpautop' );
 
 
 
 
 
 
 
 
 
 
48
 
49
+ add_filter( 'bp_get_activity_action', 'make_clickable' );
50
+ add_filter( 'bp_get_activity_content_body', 'make_clickable' );
51
+ add_filter( 'bp_get_activity_content', 'make_clickable' );
52
+ add_filter( 'bp_get_activity_parent_content', 'make_clickable' );
53
+ add_filter( 'bp_get_activity_latest_update', 'make_clickable' );
54
+ add_filter( 'bp_get_activity_latest_update_excerpt', 'make_clickable' );
55
+ add_filter( 'bp_get_activity_feed_item_description', 'make_clickable' );
56
+
57
+ add_filter( 'bp_acomment_name', 'stripslashes_deep' );
58
+ add_filter( 'bp_get_activity_action', 'stripslashes_deep' );
59
+ add_filter( 'bp_get_activity_content', 'stripslashes_deep' );
60
+ add_filter( 'bp_get_activity_content_body', 'stripslashes_deep' );
61
+ add_filter( 'bp_get_activity_parent_content', 'stripslashes_deep' );
62
+ add_filter( 'bp_get_activity_latest_update', 'stripslashes_deep' );
63
+ add_filter( 'bp_get_activity_latest_update_excerpt', 'stripslashes_deep' );
64
+ add_filter( 'bp_get_activity_feed_item_description', 'stripslashes_deep' );
65
+
66
+ /* Apply BuddyPress defined filters */
67
  add_filter( 'bp_get_activity_content', 'bp_activity_make_nofollow_filter' );
68
  add_filter( 'bp_get_activity_content_body', 'bp_activity_make_nofollow_filter' );
69
  add_filter( 'bp_get_activity_parent_content', 'bp_activity_make_nofollow_filter' );
71
  add_filter( 'bp_get_activity_latest_update_excerpt', 'bp_activity_make_nofollow_filter' );
72
  add_filter( 'bp_get_activity_feed_item_description', 'bp_activity_make_nofollow_filter' );
73
 
74
+ add_filter( 'bp_get_activity_parent_content', 'bp_create_excerpt' );
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
+ /* Allow shortcodes in activity posts */
77
+ add_filter( 'bp_get_activity_content', 'do_shortcode' );
78
+ add_filter( 'bp_get_activity_content_body', 'do_shortcode' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  function bp_activity_filter_kses( $content ) {
81
  global $allowedtags;
82
 
83
  $activity_allowedtags = $allowedtags;
84
+ $activity_allowedtags['span'] = array();
85
+ $activity_allowedtags['span']['class'] = array();
86
+ $activity_allowedtags['div'] = array();
87
+ $activity_allowedtags['div']['class'] = array();
88
+ $activity_allowedtags['div']['id'] = array();
89
+ $activity_allowedtags['a']['class'] = array();
 
 
 
 
 
90
  $activity_allowedtags['img'] = array();
91
  $activity_allowedtags['img']['src'] = array();
92
  $activity_allowedtags['img']['alt'] = array();
93
+ $activity_allowedtags['img']['class'] = array();
94
  $activity_allowedtags['img']['width'] = array();
95
  $activity_allowedtags['img']['height'] = array();
96
  $activity_allowedtags['img']['class'] = array();
97
  $activity_allowedtags['img']['id'] = array();
98
+ $activity_allowedtags['img']['title'] = array();
99
+ $activity_allowedtags['code'] = array();
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  $activity_allowedtags = apply_filters( 'bp_activity_allowed_tags', $activity_allowedtags );
102
  return wp_kses( $content, $activity_allowedtags );
103
  }
104
 
105
+ function bp_activity_at_name_filter( $content ) {
106
+ include_once( ABSPATH . WPINC . '/registration.php' );
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
+ $pattern = '/[@]+([A-Za-z0-9-_\.]+)/';
109
+ preg_match_all( $pattern, $content, $usernames );
110
 
111
+ // Make sure there's only one instance of each username
112
+ if ( !$usernames = array_unique( $usernames[1] ) )
113
  return $content;
114
 
115
+ foreach( (array)$usernames as $username ) {
116
+ if ( !$user_id = username_exists( $username ) )
117
+ continue;
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
+ // Increase the number of new @ mentions for the user
120
+ $new_mention_count = (int)get_user_meta( $user_id, 'bp_new_mention_count', true );
121
+ update_user_meta( $user_id, 'bp_new_mention_count', $new_mention_count + 1 );
 
122
 
123
+ $content = str_replace( "@$username", "<a href='" . bp_core_get_user_domain( bp_core_get_userid( $username ) ) . "' rel='nofollow'>@$username</a>", $content );
 
 
 
 
124
  }
125
 
 
126
  return $content;
127
  }
128
+ add_filter( 'bp_activity_new_update_content', 'bp_activity_at_name_filter' );
129
+ add_filter( 'groups_activity_new_update_content', 'bp_activity_at_name_filter' );
130
+ add_filter( 'pre_comment_content', 'bp_activity_at_name_filter' );
131
+ add_filter( 'group_forum_topic_text_before_save', 'bp_activity_at_name_filter' );
132
+ add_filter( 'group_forum_post_text_before_save', 'bp_activity_at_name_filter' );
133
+ add_filter( 'bp_activity_comment_content', 'bp_activity_at_name_filter' );
134
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  function bp_activity_make_nofollow_filter( $text ) {
136
  return preg_replace_callback( '|<a (.+?)>|i', 'bp_activity_make_nofollow_filter_callback', $text );
137
  }
 
 
 
 
 
 
 
 
 
138
  function bp_activity_make_nofollow_filter_callback( $matches ) {
139
  $text = $matches[1];
140
  $text = str_replace( array( ' rel="nofollow"', " rel='nofollow'"), '', $text );
141
  return "<a $text rel=\"nofollow\">";
142
  }
143
 
144
+ ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/bp-activity-functions.php DELETED
@@ -1,3851 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Activity Functions.
4
- *
5
- * Functions for the Activity Streams component.
6
- *
7
- * @package BuddyPress
8
- * @subpackage ActivityFunctions
9
- * @since 1.5.0
10
- */
11
-
12
- // Exit if accessed directly.
13
- defined( 'ABSPATH' ) || exit;
14
-
15
- /**
16
- * Check whether the $bp global lists an activity directory page.
17
- *
18
- * @since 1.5.0
19
- *
20
- * @return bool True if activity directory page is found, otherwise false.
21
- */
22
- function bp_activity_has_directory() {
23
- return (bool) !empty( buddypress()->pages->activity->id );
24
- }
25
-
26
- /**
27
- * Are mentions enabled or disabled?
28
- *
29
- * The Mentions feature does a number of things, all of which will be turned
30
- * off if you disable mentions:
31
- * - Detecting and auto-linking @username in all BP/WP content.
32
- * - Sending BP notifications and emails to users when they are mentioned
33
- * using the @username syntax.
34
- * - The Public Message button on user profiles.
35
- *
36
- * Mentions are enabled by default. To disable, put the following line in
37
- * bp-custom.php or your theme's functions.php file:
38
- *
39
- * add_filter( 'bp_activity_do_mentions', '__return_false' );
40
- *
41
- * @since 1.8.0
42
- *
43
- * @return bool $retval True to enable mentions, false to disable.
44
- */
45
- function bp_activity_do_mentions() {
46
-
47
- /**
48
- * Filters whether or not mentions are enabled.
49
- *
50
- * @since 1.8.0
51
- *
52
- * @param bool $enabled True to enable mentions, false to disable.
53
- */
54
- return (bool) apply_filters( 'bp_activity_do_mentions', true );
55
- }
56
-
57
- /**
58
- * Should BuddyPress load the mentions scripts and related assets, including results to prime the
59
- * mentions suggestions?
60
- *
61
- * @since 2.1.0
62
- *
63
- * @return bool True if mentions scripts should be loaded.
64
- */
65
- function bp_activity_maybe_load_mentions_scripts() {
66
- $mentions_enabled = bp_activity_do_mentions() && bp_is_user_active();
67
- $load_mentions = $mentions_enabled && ( bp_is_activity_component() || is_admin() );
68
-
69
- /**
70
- * Filters whether or not BuddyPress should load mentions scripts and assets.
71
- *
72
- * @since 2.1.0
73
- *
74
- * @param bool $load_mentions True to load mentions assets, false otherwise.
75
- * @param bool $mentions_enabled True if mentions are enabled.
76
- */
77
- return (bool) apply_filters( 'bp_activity_maybe_load_mentions_scripts', $load_mentions, $mentions_enabled );
78
- }
79
-
80
- /**
81
- * Locate usernames in an activity content string, as designated by an @ sign.
82
- *
83
- * @since 1.5.0
84
- *
85
- * @param string $content The content of the activity, usually found in
86
- * $activity->content.
87
- * @return array|bool Associative array with user ID as key and username as
88
- * value. Boolean false if no mentions found.
89
- */
90
- function bp_activity_find_mentions( $content ) {
91
-
92
- $pattern = '/[@]+([A-Za-z0-9-_\.@]+)\b/';
93
- preg_match_all( $pattern, $content, $usernames );
94
-
95
- // Make sure there's only one instance of each username.
96
- $usernames = array_unique( $usernames[1] );
97
-
98
- // Bail if no usernames.
99
- if ( empty( $usernames ) ) {
100
- return false;
101
- }
102
-
103
- $mentioned_users = array();
104
-
105
- // We've found some mentions! Check to see if users exist.
106
- foreach( (array) array_values( $usernames ) as $username ) {
107
- $user_id = bp_activity_get_userid_from_mentionname( $username );
108
-
109
- // The user ID exists, so let's add it to our array.
110
- if ( ! empty( $user_id ) ) {
111
- $mentioned_users[ $user_id ] = $username;
112
- }
113
- }
114
-
115
- if ( empty( $mentioned_users ) ) {
116
- return false;
117
- }
118
-
119
- /**
120
- * Filters the mentioned users.
121
- *
122
- * @since 2.5.0
123
- *
124
- * @param array $mentioned_users Associative array with user IDs as keys and usernames as values.
125
- */
126
- return apply_filters( 'bp_activity_mentioned_users', $mentioned_users );
127
- }
128
-
129
- /**
130
- * Reset a user's unread mentions list and count.
131
- *
132
- * @since 1.5.0
133
- *
134
- * @param int $user_id The id of the user whose unread mentions are being reset.
135
- */
136
- function bp_activity_clear_new_mentions( $user_id ) {
137
- bp_delete_user_meta( $user_id, 'bp_new_mention_count' );
138
- bp_delete_user_meta( $user_id, 'bp_new_mentions' );
139
-
140
- /**
141
- * Fires once mentions has been reset for a given user.
142
- *
143
- * @since 2.5.0
144
- *
145
- * @param int $user_id The id of the user whose unread mentions are being reset.
146
- */
147
- do_action( 'bp_activity_clear_new_mentions', $user_id );
148
- }
149
-
150
- /**
151
- * Adjusts mention count for mentioned users in activity items.
152
- *
153
- * This function is useful if you only have the activity ID handy and you
154
- * haven't parsed an activity item for @mentions yet.
155
- *
156
- * Currently, only used in {@link bp_activity_delete()}.
157
- *
158
- * @since 1.5.0
159
- *
160
- * @param int $activity_id The unique id for the activity item.
161
- * @param string $action Can be 'delete' or 'add'. Defaults to 'add'.
162
- * @return bool
163
- */
164
- function bp_activity_adjust_mention_count( $activity_id = 0, $action = 'add' ) {
165
-
166
- // Bail if no activity ID passed.
167
- if ( empty( $activity_id ) ) {
168
- return false;
169
- }
170
-
171
- // Get activity object.
172
- $activity = new BP_Activity_Activity( $activity_id );
173
-
174
- // Try to find mentions.
175
- $usernames = bp_activity_find_mentions( strip_tags( $activity->content ) );
176
-
177
- // Still empty? Stop now.
178
- if ( empty( $usernames ) ) {
179
- return false;
180
- }
181
-
182
- // Increment mention count foreach mentioned user.
183
- foreach( (array) array_keys( $usernames ) as $user_id ) {
184
- bp_activity_update_mention_count_for_user( $user_id, $activity_id, $action );
185
- }
186
- }
187
-
188
- /**
189
- * Update the mention count for a given user.
190
- *
191
- * This function should be used when you've already parsed your activity item
192
- * for @mentions.
193
- *
194
- * @since 1.7.0
195
- *
196
- * @param int $user_id The user ID.
197
- * @param int $activity_id The unique ID for the activity item.
198
- * @param string $action 'delete' or 'add'. Default: 'add'.
199
- * @return bool
200
- */
201
- function bp_activity_update_mention_count_for_user( $user_id, $activity_id, $action = 'add' ) {
202
-
203
- if ( empty( $user_id ) || empty( $activity_id ) ) {
204
- return false;
205
- }
206
-
207
- // Adjust the mention list and count for the member.
208
- $new_mention_count = (int) bp_get_user_meta( $user_id, 'bp_new_mention_count', true );
209
- $new_mentions = bp_get_user_meta( $user_id, 'bp_new_mentions', true );
210
-
211
- // Make sure new mentions is an array.
212
- if ( empty( $new_mentions ) ) {
213
- $new_mentions = array();
214
- }
215
-
216
- switch ( $action ) {
217
- case 'delete' :
218
- $key = array_search( $activity_id, $new_mentions );
219
-
220
- if ( $key !== false ) {
221
- unset( $new_mentions[$key] );
222
- }
223
-
224
- break;
225
-
226
- case 'add' :
227
- default :
228
- if ( !in_array( $activity_id, $new_mentions ) ) {
229
- $new_mentions[] = (int) $activity_id;
230
- }
231
-
232
- break;
233
- }
234
-
235
- // Get an updated mention count.
236
- $new_mention_count = count( $new_mentions );
237
-
238
- // Resave the user_meta.
239
- bp_update_user_meta( $user_id, 'bp_new_mention_count', $new_mention_count );
240
- bp_update_user_meta( $user_id, 'bp_new_mentions', $new_mentions );
241
-
242
- return true;
243
- }
244
-
245
- /**
246
- * Determine a user's "mentionname", the name used for that user in @-mentions.
247
- *
248
- * @since 1.9.0
249
- *
250
- * @param int|string $user_id ID of the user to get @-mention name for.
251
- * @return string $mentionname User name appropriate for @-mentions.
252
- */
253
- function bp_activity_get_user_mentionname( $user_id ) {
254
- $mentionname = '';
255
-
256
- $userdata = bp_core_get_core_userdata( $user_id );
257
-
258
- if ( $userdata ) {
259
- if ( bp_is_username_compatibility_mode() ) {
260
- $mentionname = str_replace( ' ', '-', $userdata->user_login );
261
- } else {
262
- $mentionname = $userdata->user_nicename;
263
- }
264
- }
265
-
266
- return $mentionname;
267
- }
268
-
269
- /**
270
- * Get a user ID from a "mentionname", the name used for a user in @-mentions.
271
- *
272
- * @since 1.9.0
273
- *
274
- * @param string $mentionname Username of user in @-mentions.
275
- * @return int|bool ID of the user, if one is found. Otherwise false.
276
- */
277
- function bp_activity_get_userid_from_mentionname( $mentionname ) {
278
- $user_id = false;
279
-
280
- /*
281
- * In username compatibility mode, hyphens are ambiguous between
282
- * actual hyphens and converted spaces.
283
- *
284
- * @todo There is the potential for username clashes between 'foo bar'
285
- * and 'foo-bar' in compatibility mode. Come up with a system for
286
- * unique mentionnames.
287
- */
288
- if ( bp_is_username_compatibility_mode() ) {
289
- // First, try the raw username.
290
- $userdata = get_user_by( 'login', $mentionname );
291
-
292
- // Doing a direct query to use proper regex. Necessary to
293
- // account for hyphens + spaces in the same user_login.
294
- if ( empty( $userdata ) || ! is_a( $userdata, 'WP_User' ) ) {
295
- global $wpdb;
296
- $regex = esc_sql( str_replace( '-', '[ \-]', $mentionname ) );
297
- $user_id = $wpdb->get_var( "SELECT ID FROM {$wpdb->users} WHERE user_login REGEXP '{$regex}'" );
298
- } else {
299
- $user_id = $userdata->ID;
300
- }
301
-
302
- // When username compatibility mode is disabled, the mentionname is
303
- // the same as the nicename.
304
- } else {
305
- $user_id = bp_core_get_userid_from_nicename( $mentionname );
306
- }
307
-
308
-
309
- return $user_id;
310
- }
311
-
312
- /** Actions ******************************************************************/
313
-
314
- /**
315
- * Register an activity 'type' and its action description/callback.
316
- *
317
- * Activity actions are strings used to describe items in the activity stream,
318
- * such as 'Joe became a registered member' or 'Bill and Susie are now
319
- * friends'. Each activity type (such as 'new_member' or 'friendship_created')
320
- * used by a component should be registered using this function.
321
- *
322
- * While it's possible to post items to the activity stream whose types are
323
- * not registered using bp_activity_set_action(), it is not recommended;
324
- * unregistered types will not be displayed properly in the activity admin
325
- * panel, and dynamic action generation (which is essential for multilingual
326
- * sites, etc) will not work.
327
- *
328
- * @since 1.1.0
329
- *
330
- * @param string $component_id The unique string ID of the component.
331
- * @param string $type The action type.
332
- * @param string $description The action description.
333
- * @param callable|bool $format_callback Callback for formatting the action string.
334
- * @param string|bool $label String to describe this action in the activity stream filter dropdown.
335
- * @param array $context Optional. Activity stream contexts where the filter should appear.
336
- * Values: 'activity', 'member', 'member_groups', 'group'.
337
- * @param int $position Optional. The position of the action when listed in dropdowns.
338
- * @return bool False if any param is empty, otherwise true.
339
- */
340
- function bp_activity_set_action( $component_id, $type, $description, $format_callback = false, $label = false, $context = array(), $position = 0 ) {
341
- $bp = buddypress();
342
-
343
- // Return false if any of the above values are not set.
344
- if ( empty( $component_id ) || empty( $type ) || empty( $description ) ) {
345
- return false;
346
- }
347
-
348
- // Set activity action.
349
- if ( ! isset( $bp->activity->actions ) || ! is_object( $bp->activity->actions ) ) {
350
- $bp->activity->actions = new stdClass;
351
- }
352
-
353
- // Verify callback.
354
- if ( ! is_callable( $format_callback ) ) {
355
- $format_callback = '';
356
- }
357
-
358
- if ( ! isset( $bp->activity->actions->{$component_id} ) || ! is_object( $bp->activity->actions->{$component_id} ) ) {
359
- $bp->activity->actions->{$component_id} = new stdClass;
360
- }
361
-
362
- /**
363
- * Filters the action type being set for the current activity item.
364
- *
365
- * @since 1.1.0
366
- *
367
- * @param array $array Array of arguments for action type being set.
368
- * @param string $component_id ID of the current component being set.
369
- * @param string $type Action type being set.
370
- * @param string $description Action description for action being set.
371
- * @param callable $format_callback Callback for formatting the action string.
372
- * @param string $label String to describe this action in the activity stream filter dropdown.
373
- * @param array $context Activity stream contexts where the filter should appear. 'activity', 'member',
374
- * 'member_groups', 'group'.
375
- */
376
- $bp->activity->actions->{$component_id}->{$type} = apply_filters( 'bp_activity_set_action', array(
377
- 'key' => $type,
378
- 'value' => $description,
379
- 'format_callback' => $format_callback,
380
- 'label' => $label,
381
- 'context' => $context,
382
- 'position' => $position,
383
- ), $component_id, $type, $description, $format_callback, $label, $context );
384
-
385
- // Sort the actions of the affected component.
386
- $action_array = (array) $bp->activity->actions->{$component_id};
387
- $action_array = bp_sort_by_key( $action_array, 'position', 'num' );
388
-
389
- // Restore keys.
390
- $bp->activity->actions->{$component_id} = new stdClass;
391
- foreach ( $action_array as $key_ordered ) {
392
- $bp->activity->actions->{$component_id}->{$key_ordered['key']} = $key_ordered;
393
- }
394
-
395
- return true;
396
- }
397
-
398
- /**
399
- * Set tracking arguments for a given post type.
400
- *
401
- * @since 2.2.0
402
- *
403
- * @global $wp_post_types
404
- *
405
- * @param string $post_type The name of the post type, as registered with WordPress. Eg 'post' or 'page'.
406
- * @param array $args {
407
- * An associative array of tracking parameters. All items are optional.
408
- * @type string $bp_activity_admin_filter String to use in the Dashboard > Activity dropdown.
409
- * @type string $bp_activity_front_filter String to use in the front-end dropdown.
410
- * @type string $bp_activity_new_post String format to use for generating the activity action. Should be a
411
- * translatable string where %1$s is replaced by a user link and %2$s is
412
- * the URL of the newly created post.
413
- * @type string $bp_activity_new_post_ms String format to use for generating the activity action on Multisite.
414
- * Should be a translatable string where %1$s is replaced by a user link,
415
- * %2$s is the URL of the newly created post, and %3$s is a link to
416
- * the site.
417
- * @type string $component_id ID of the BuddyPress component to associate the activity item.
418
- * @type string $action_id Value for the 'type' param of the new activity item.
419
- * @type callable $format_callback Callback for formatting the activity action string.
420
- * Default: 'bp_activity_format_activity_action_custom_post_type_post'.
421
- * @type array $contexts The directory contexts in which the filter will show.
422
- * Default: array( 'activity' ).
423
- * @type array $position Position of the item in filter dropdowns.
424
- * @type string $singular Singular, translatable name of the post type item. If no value is
425
- * provided, it's pulled from the 'singular_name' of the post type.
426
- * @type bool $activity_comment Whether to allow comments on the activity items. Defaults to true if
427
- * the post type does not natively support comments, otherwise false.
428
- * }
429
- * @return bool
430
- */
431
- function bp_activity_set_post_type_tracking_args( $post_type = '', $args = array() ) {
432
- global $wp_post_types;
433
-
434
- if ( empty( $wp_post_types[ $post_type ] ) || ! post_type_supports( $post_type, 'buddypress-activity' ) || ! is_array( $args ) ) {
435
- return false;
436
- }
437
-
438
- $activity_labels = array(
439
- /* Post labels */
440
- 'bp_activity_admin_filter',
441
- 'bp_activity_front_filter',
442
- 'bp_activity_new_post',
443
- 'bp_activity_new_post_ms',
444
- /* Comment labels */
445
- 'bp_activity_comments_admin_filter',
446
- 'bp_activity_comments_front_filter',
447
- 'bp_activity_new_comment',
448
- 'bp_activity_new_comment_ms'
449
- );
450
-
451
- // Labels are loaded into the post type object.
452
- foreach ( $activity_labels as $label_type ) {
453
- if ( ! empty( $args[ $label_type ] ) ) {
454
- $wp_post_types[ $post_type ]->labels->{$label_type} = $args[ $label_type ];
455
- unset( $args[ $label_type ] );
456
- }
457
- }
458
-
459
- // If there are any additional args, put them in the bp_activity attribute of the post type.
460
- if ( ! empty( $args ) ) {
461
- $wp_post_types[ $post_type ]->bp_activity = $args;
462
- }
463
- }
464
-
465
- /**
466
- * Get tracking arguments for a specific post type.
467
- *
468
- * @since 2.2.0
469
- * @since 2.5.0 Add post type comments tracking args
470
- *
471
- * @param string $post_type Name of the post type.
472
- * @return object The tracking arguments of the post type.
473
- */
474
- function bp_activity_get_post_type_tracking_args( $post_type ) {
475
- if ( ! post_type_supports( $post_type, 'buddypress-activity' ) ) {
476
- return false;
477
- }
478
-
479
- $post_type_object = get_post_type_object( $post_type );
480
- $post_type_support_comments = post_type_supports( $post_type, 'comments' );
481
-
482
- $post_type_activity = array(
483
- 'component_id' => buddypress()->activity->id,
484
- 'action_id' => 'new_' . $post_type,
485
- 'format_callback' => 'bp_activity_format_activity_action_custom_post_type_post',
486
- 'front_filter' => $post_type_object->labels->name,
487
- 'contexts' => array( 'activity' ),
488
- 'position' => 0,
489
- 'singular' => strtolower( $post_type_object->labels->singular_name ),
490
- 'activity_comment' => ! $post_type_support_comments,
491
- 'comment_action_id' => false,
492
- 'comment_format_callback' => 'bp_activity_format_activity_action_custom_post_type_comment',
493
- );
494
-
495
- if ( ! empty( $post_type_object->bp_activity ) ) {
496
- $post_type_activity = bp_parse_args( (array) $post_type_object->bp_activity, $post_type_activity, $post_type . '_tracking_args' );
497
- }
498
-
499
- $post_type_activity = (object) $post_type_activity;
500
-
501
- // Try to get the admin filter from the post type labels.
502
- if ( ! empty( $post_type_object->labels->bp_activity_admin_filter ) ) {
503
- $post_type_activity->admin_filter = $post_type_object->labels->bp_activity_admin_filter;
504
-
505
- // Fall back to a generic name.
506
- } else {
507
- $post_type_activity->admin_filter = _x( 'New item published', 'Post Type generic activity post admin filter', 'buddypress' );
508
- }
509
-
510
- // Check for the front filter in the post type labels.
511
- if ( ! empty( $post_type_object->labels->bp_activity_front_filter ) ) {
512
- $post_type_activity->front_filter = $post_type_object->labels->bp_activity_front_filter;
513
- }
514
-
515
- // Try to get the action for new post type action on non-multisite installations.
516
- if ( ! empty( $post_type_object->labels->bp_activity_new_post ) ) {
517
- $post_type_activity->new_post_type_action = $post_type_object->labels->bp_activity_new_post;
518
- }
519
-
520
- // Try to get the action for new post type action on multisite installations.
521
- if ( ! empty( $post_type_object->labels->bp_activity_new_post_ms ) ) {
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
-
534
- // Try to get the comments admin filter from the post type labels.
535
- if ( ! empty( $post_type_object->labels->bp_activity_comments_admin_filter ) ) {
536
- $post_type_activity->comments_tracking->admin_filter = $post_type_object->labels->bp_activity_comments_admin_filter;
537
-
538
- // Fall back to a generic name.
539
- } else {
540
- $post_type_activity->comments_tracking->admin_filter = _x( 'New item comment posted', 'Post Type generic comments activity admin filter', 'buddypress' );
541
- }
542
-
543
- $post_type_activity->comments_tracking->format_callback = $post_type_activity->comment_format_callback;
544
-
545
- // Check for the comments front filter in the post type labels.
546
- if ( ! empty( $post_type_object->labels->bp_activity_comments_front_filter ) ) {
547
- $post_type_activity->comments_tracking->front_filter = $post_type_object->labels->bp_activity_comments_front_filter;
548
-
549
- // Fall back to a generic name.
550
- } else {
551
- $post_type_activity->comments_tracking->front_filter = _x( 'Item comments', 'Post Type generic comments activity front filter', 'buddypress' );
552
- }
553
-
554
- $post_type_activity->comments_tracking->contexts = $post_type_activity->contexts;
555
- $post_type_activity->comments_tracking->position = (int) $post_type_activity->position + 1;
556
-
557
- // Try to get the action for new post type comment action on non-multisite installations.
558
- if ( ! empty( $post_type_object->labels->bp_activity_new_comment ) ) {
559
- $post_type_activity->comments_tracking->new_post_type_comment_action = $post_type_object->labels->bp_activity_new_comment;
560
- }
561
-
562
- // Try to get the action for new post type comment action on multisite installations.
563
- if ( ! empty( $post_type_object->labels->bp_activity_new_comment_ms ) ) {
564
- $post_type_activity->comments_tracking->new_post_type_comment_action_ms = $post_type_object->labels->bp_activity_new_comment_ms;
565
- }
566
- }
567
-
568
- // Finally make sure we'll be able to find the post type this activity type is associated to.
569
- $post_type_activity->post_type = $post_type;
570
-
571
- /**
572
- * Filters tracking arguments for a specific post type.
573
- *
574
- * @since 2.2.0
575
- *
576
- * @param object $post_type_activity The tracking arguments of the post type.
577
- * @param string $post_type Name of the post type.
578
- */
579
- return apply_filters( 'bp_activity_get_post_type_tracking_args', $post_type_activity, $post_type );
580
- }
581
-
582
- /**
583
- * Get tracking arguments for all post types.
584
- *
585
- * @since 2.2.0
586
- * @since 2.5.0 Include post type comments tracking args if needed
587
- *
588
- * @return array List of post types with their tracking arguments.
589
- */
590
- function bp_activity_get_post_types_tracking_args() {
591
- // Fetch all public post types.
592
- $post_types = get_post_types( array( 'public' => true ), 'names' );
593
-
594
- $post_types_tracking_args = array();
595
-
596
- foreach ( $post_types as $post_type ) {
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.
606
- $track_post_type->comments_tracking->post_type = $post_type;
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
-
614
- $post_types_tracking_args[ $track_post_type->action_id ] = $track_post_type;
615
- }
616
-
617
- }
618
-
619
- /**
620
- * Filters tracking arguments for all post types.
621
- *
622
- * @since 2.2.0
623
- *
624
- * @param array $post_types_tracking_args Array of post types with
625
- * their tracking arguments.
626
- */
627
- return apply_filters( 'bp_activity_get_post_types_tracking_args', $post_types_tracking_args );
628
- }
629
-
630
- /**
631
- * Check if the *Post Type* activity supports a specific feature.
632
- *
633
- * @since 2.5.0
634
- *
635
- * @param string $activity_type The activity type to check.
636
- * @param string $feature The feature to check. Currently supports:
637
- * 'post-type-comment-tracking', 'post-type-comment-reply' & 'comment-reply'.
638
- * See inline doc for more info.
639
- * @return bool
640
- */
641
- function bp_activity_type_supports( $activity_type = '', $feature = '' ) {
642
- $retval = false;
643
-
644
- $bp = buddypress();
645
-
646
- switch ( $feature ) {
647
- /**
648
- * Does this activity type support comment tracking?
649
- *
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
- }
657
-
658
- if ( ! empty( $bp->activity->track[ $activity_type ]->comments_tracking ) ) {
659
- $retval = true;
660
- }
661
- break;
662
-
663
- /**
664
- * Is this a parent activity type that support post comments?
665
- *
666
- * eg. 'new_blog_post' will return true; 'new_blog_comment' will return false.
667
- */
668
- case 'post-type-comment-reply' :
669
- // Set the activity track global if not set yet.
670
- if ( empty( $bp->activity->track ) ) {
671
- $bp->activity->track = bp_activity_get_post_types_tracking_args();
672
- }
673
-
674
- if ( ! empty( $bp->activity->track[ $activity_type ]->comments_tracking ) && ! empty( $bp->activity->track[ $activity_type ]->comment_action_id ) ) {
675
- $retval = true;
676
- }
677
- break;
678
-
679
- /**
680
- * Does this activity type support comment & reply?
681
- */
682
- case 'comment-reply' :
683
- // Set the activity track global if not set yet.
684
- if ( empty( $bp->activity->track ) ) {
685
- $bp->activity->track = bp_activity_get_post_types_tracking_args();
686
- }
687
-
688
- // Post Type activities
689
- if ( ! empty( $bp->activity->track[ $activity_type ] ) ) {
690
- if ( isset( $bp->activity->track[ $activity_type ]->activity_comment ) ) {
691
- $retval = $bp->activity->track[ $activity_type ]->activity_comment;
692
- }
693
-
694
- // Eventually override with comment synchronization feature.
695
- if ( isset( $bp->activity->track[ $activity_type ]->comments_tracking ) ) {
696
- $retval = $bp->activity->track[ $activity_type ]->comments_tracking && ! bp_disable_blogforum_comments();
697
- }
698
-
699
- // Retired Forums component
700
- } elseif ( 'new_forum_topic' === $activity_type || 'new_forum_post' === $activity_type ) {
701
- $retval = ! bp_disable_blogforum_comments();
702
-
703
- // By Default, all other activity types are supporting comments.
704
- } else {
705
- $retval = true;
706
- }
707
- break;
708
- }
709
-
710
- return $retval;
711
- }
712
-
713
- /**
714
- * Get a specific tracking argument for a given activity type
715
- *
716
- * @since 2.5.0
717
- *
718
- * @param string $activity_type the activity type.
719
- * @param string $arg the key of the tracking argument.
720
- * @return mixed the value of the tracking arg, false if not found.
721
- */
722
- function bp_activity_post_type_get_tracking_arg( $activity_type, $arg = '' ) {
723
- if ( empty( $activity_type ) || empty( $arg ) ) {
724
- return false;
725
- }
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
- }
733
-
734
- if ( isset( $bp->activity->track[ $activity_type ]->{$arg} ) ) {
735
- return $bp->activity->track[ $activity_type ]->{$arg};
736
- } else {
737
- return false;
738
- }
739
- }
740
-
741
- /**
742
- * Get all components' activity actions, sorted by their position attribute.
743
- *
744
- * @since 2.2.0
745
- *
746
- * @return object Actions ordered by their position.
747
- */
748
- function bp_activity_get_actions() {
749
- $bp = buddypress();
750
-
751
- $post_types = bp_activity_get_post_types_tracking_args();
752
-
753
- // Create the actions for the post types, if they haven't already been created.
754
- if ( ! empty( $post_types ) ) {
755
- foreach ( $post_types as $post_type ) {
756
- if ( isset( $bp->activity->actions->{$post_type->component_id}->{$post_type->action_id} ) ) {
757
- continue;
758
- }
759
-
760
- bp_activity_set_action(
761
- $post_type->component_id,
762
- $post_type->action_id,
763
- $post_type->admin_filter,
764
- $post_type->format_callback,
765
- $post_type->front_filter,
766
- $post_type->contexts,
767
- $post_type->position
768
- );
769
- }
770
- }
771
-
772
- return $bp->activity->actions;
773
- }
774
-
775
- /**
776
- * Retrieve the current action from a component and key.
777
- *
778
- * @since 1.1.0
779
- *
780
- * @param string $component_id The unique string ID of the component.
781
- * @param string $key The action key.
782
- * @return string|bool Action value if found, otherwise false.
783
- */
784
- function bp_activity_get_action( $component_id, $key ) {
785
-
786
- // Return false if any of the above values are not set.
787
- if ( empty( $component_id ) || empty( $key ) ) {
788
- return false;
789
- }
790
-
791
- $actions = bp_activity_get_actions();
792
- $retval = false;
793
-
794
- if ( isset( $actions->{$component_id}->{$key} ) ) {
795
- $retval = $actions->{$component_id}->{$key};
796
- }
797
-
798
- /**
799
- * Filters the current action by component and key.
800
- *
801
- * @since 1.1.0
802
- *
803
- * @param string|bool $retval The action key.
804
- * @param string $component_id The unique string ID of the component.
805
- * @param string $key The action key.
806
- */
807
- return apply_filters( 'bp_activity_get_action', $retval, $component_id, $key );
808
- }
809
-
810
- /**
811
- * Fetch details of all registered activity types.
812
- *
813
- * @since 1.7.0
814
- *
815
- * @return array array( type => description ), ...
816
- */
817
- function bp_activity_get_types() {
818
- $actions = array();
819
-
820
- // Walk through the registered actions, and build an array of actions/values.
821
- foreach ( bp_activity_get_actions() as $action ) {
822
- $action = array_values( (array) $action );
823
-
824
- for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ ) {
825
- $actions[ $action[$i]['key'] ] = $action[$i]['value'];
826
- }
827
- }
828
-
829
- // This was a mis-named activity type from before BP 1.6.
830
- unset( $actions['friends_register_activity_action'] );
831
-
832
- /**
833
- * Filters the available activity types.
834
- *
835
- * @since 1.7.0
836
- *
837
- * @param array $actions Array of registered activity types.
838
- */
839
- return apply_filters( 'bp_activity_get_types', $actions );
840
- }
841
-
842
- /**
843
- * Gets the current activity context.
844
- *
845
- * The "context" is the current view type, corresponding roughly to the
846
- * current component. Use this context to determine which activity actions
847
- * should be whitelisted for the filter dropdown.
848
- *
849
- * @since 2.8.0
850
- *
851
- * @return string Activity context. 'member', 'member_groups', 'group', 'activity'.
852
- */
853
- function bp_activity_get_current_context() {
854
- // On member pages, default to 'member', unless this is a user's Groups activity.
855
- if ( bp_is_user() ) {
856
- if ( bp_is_active( 'groups' ) && bp_is_current_action( bp_get_groups_slug() ) ) {
857
- $context = 'member_groups';
858
- } else {
859
- $context = 'member';
860
- }
861
-
862
- // On individual group pages, default to 'group'.
863
- } elseif ( bp_is_active( 'groups' ) && bp_is_group() ) {
864
- $context = 'group';
865
-
866
- // 'activity' everywhere else.
867
- } else {
868
- $context = 'activity';
869
- }
870
-
871
- return $context;
872
- }
873
-
874
- /**
875
- * Gets a flat list of activity actions compatible with a given context.
876
- *
877
- * @since 2.8.0
878
- *
879
- * @param string $context Optional. Name of the context. Defaults to the current context.
880
- * @return array
881
- */
882
- function bp_activity_get_actions_for_context( $context = '' ) {
883
- if ( ! $context ) {
884
- $context = bp_activity_get_current_context();
885
- }
886
-
887
- $actions = array();
888
- foreach ( bp_activity_get_actions() as $component_actions ) {
889
- foreach ( $component_actions as $component_action ) {
890
- if ( in_array( $context, (array) $component_action['context'], true ) ) {
891
- $actions[] = $component_action;
892
- }
893
- }
894
- }
895
-
896
- return $actions;
897
- }
898
-
899
- /** Favorites ****************************************************************/
900
-
901
- /**
902
- * Get a users favorite activity stream items.
903
- *
904
- * @since 1.2.0
905
- *
906
- * @param int $user_id ID of the user whose favorites are being queried.
907
- * @return array IDs of the user's favorite activity items.
908
- */
909
- function bp_activity_get_user_favorites( $user_id = 0 ) {
910
-
911
- // Fallback to logged in user if no user_id is passed.
912
- if ( empty( $user_id ) ) {
913
- $user_id = bp_displayed_user_id();
914
- }
915
-
916
- // Get favorites for user.
917
- $favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
918
-
919
- /**
920
- * Filters the favorited activity items for a specified user.
921
- *
922
- * @since 1.2.0
923
- *
924
- * @param array $favs Array of user's favorited activity items.
925
- */
926
- return apply_filters( 'bp_activity_get_user_favorites', $favs );
927
- }
928
-
929
- /**
930
- * Add an activity stream item as a favorite for a user.
931
- *
932
- * @since 1.2.0
933
- *
934
- * @param int $activity_id ID of the activity item being favorited.
935
- * @param int $user_id ID of the user favoriting the activity item.
936
- * @return bool True on success, false on failure.
937
- */
938
- function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) {
939
-
940
- // Favorite activity stream items are for logged in users only.
941
- if ( ! is_user_logged_in() ) {
942
- return false;
943
- }
944
-
945
- // Fallback to logged in user if no user_id is passed.
946
- if ( empty( $user_id ) ) {
947
- $user_id = bp_loggedin_user_id();
948
- }
949
-
950
- $my_favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
951
- if ( empty( $my_favs ) || ! is_array( $my_favs ) ) {
952
- $my_favs = array();
953
- }
954
-
955
- // Bail if the user has already favorited this activity item.
956
- if ( in_array( $activity_id, $my_favs ) ) {
957
- return false;
958
- }
959
-
960
- // Add to user's favorites.
961
- $my_favs[] = $activity_id;
962
-
963
- // Update the total number of users who have favorited this activity.
964
- $fav_count = bp_activity_get_meta( $activity_id, 'favorite_count' );
965
- $fav_count = !empty( $fav_count ) ? (int) $fav_count + 1 : 1;
966
-
967
- // Update user meta.
968
- bp_update_user_meta( $user_id, 'bp_favorite_activities', $my_favs );
969
-
970
- // Update activity meta counts.
971
- if ( bp_activity_update_meta( $activity_id, 'favorite_count', $fav_count ) ) {
972
-
973
- /**
974
- * Fires if bp_activity_update_meta() for favorite_count is successful and before returning a true value for success.
975
- *
976
- * @since 1.2.1
977
- *
978
- * @param int $activity_id ID of the activity item being favorited.
979
- * @param int $user_id ID of the user doing the favoriting.
980
- */
981
- do_action( 'bp_activity_add_user_favorite', $activity_id, $user_id );
982
-
983
- // Success.
984
- return true;
985
-
986
- // Saving meta was unsuccessful for an unknown reason.
987
- } else {
988
-
989
- /**
990
- * Fires if bp_activity_update_meta() for favorite_count is unsuccessful and before returning a false value for failure.
991
- *
992
- * @since 1.5.0
993
- *
994
- * @param int $activity_id ID of the activity item being favorited.
995
- * @param int $user_id ID of the user doing the favoriting.
996
- */
997
- do_action( 'bp_activity_add_user_favorite_fail', $activity_id, $user_id );
998
-
999
- return false;
1000
- }
1001
- }
1002
-
1003
- /**
1004
- * Remove an activity stream item as a favorite for a user.
1005
- *
1006
- * @since 1.2.0
1007
- *
1008
- * @param int $activity_id ID of the activity item being unfavorited.
1009
- * @param int $user_id ID of the user unfavoriting the activity item.
1010
- * @return bool True on success, false on failure.
1011
- */
1012
- function bp_activity_remove_user_favorite( $activity_id, $user_id = 0 ) {
1013
-
1014
- // Favorite activity stream items are for logged in users only.
1015
- if ( ! is_user_logged_in() ) {
1016
- return false;
1017
- }
1018
-
1019
- // Fallback to logged in user if no user_id is passed.
1020
- if ( empty( $user_id ) ) {
1021
- $user_id = bp_loggedin_user_id();
1022
- }
1023
-
1024
- $my_favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
1025
- $my_favs = array_flip( (array) $my_favs );
1026
-
1027
- // Bail if the user has not previously favorited the item.
1028
- if ( ! isset( $my_favs[ $activity_id ] ) ) {
1029
- return false;
1030
- }
1031
-
1032
- // Remove the fav from the user's favs.
1033
- unset( $my_favs[$activity_id] );
1034
- $my_favs = array_unique( array_flip( $my_favs ) );
1035
-
1036
- // Update the total number of users who have favorited this activity.
1037
- $fav_count = bp_activity_get_meta( $activity_id, 'favorite_count' );
1038
- if ( ! empty( $fav_count ) ) {
1039
-
1040
- // Deduct from total favorites.
1041
- if ( bp_activity_update_meta( $activity_id, 'favorite_count', (int) $fav_count - 1 ) ) {
1042
-
1043
- // Update users favorites.
1044
- if ( bp_update_user_meta( $user_id, 'bp_favorite_activities', $my_favs ) ) {
1045
-
1046
- /**
1047
- * Fires if bp_update_user_meta() is successful and before returning a true value for success.
1048
- *
1049
- * @since 1.2.1
1050
- *
1051
- * @param int $activity_id ID of the activity item being unfavorited.
1052
- * @param int $user_id ID of the user doing the unfavoriting.
1053
- */
1054
- do_action( 'bp_activity_remove_user_favorite', $activity_id, $user_id );
1055
-
1056
- // Success.
1057
- return true;
1058
-
1059
- // Error updating.
1060
- } else {
1061
- return false;
1062
- }
1063
-
1064
- // Error updating favorite count.
1065
- } else {
1066
- return false;
1067
- }
1068
-
1069
- // Error getting favorite count.
1070
- } else {
1071
- return false;
1072
- }
1073
- }
1074
-
1075
- /**
1076
- * Check whether an activity item exists with a given content string.
1077
- *
1078
- * @since 1.1.0
1079
- *
1080
- * @param string $content The content to filter by.
1081
- * @return int|null The ID of the located activity item. Null if none is found.
1082
- */
1083
- function bp_activity_check_exists_by_content( $content ) {
1084
-
1085
- /**
1086
- * Filters the results of the check for whether an activity item exists by specified content.
1087
- *
1088
- * @since 1.1.0
1089
- *
1090
- * @param BP_Activity_Activity $value ID of the activity if found, else null.
1091
- */
1092
- return apply_filters( 'bp_activity_check_exists_by_content', BP_Activity_Activity::check_exists_by_content( $content ) );
1093
- }
1094
-
1095
- /**
1096
- * Retrieve the last time activity was updated.
1097
- *
1098
- * @since 1.0.0
1099
- *
1100
- * @return string Date last updated.
1101
- */
1102
- function bp_activity_get_last_updated() {
1103
-
1104
- /**
1105
- * Filters the value for the last updated time for an activity item.
1106
- *
1107
- * @since 1.1.0
1108
- *
1109
- * @param BP_Activity_Activity $last_updated Date last updated.
1110
- */
1111
- return apply_filters( 'bp_activity_get_last_updated', BP_Activity_Activity::get_last_updated() );
1112
- }
1113
-
1114
- /**
1115
- * Retrieve the number of favorite activity stream items a user has.
1116
- *
1117
- * @since 1.2.0
1118
- *
1119
- * @param int $user_id ID of the user whose favorite count is being requested.
1120
- * @return int Total favorite count for the user.
1121
- */
1122
- function bp_activity_total_favorites_for_user( $user_id = 0 ) {
1123
-
1124
- // Fallback on displayed user, and then logged in user.
1125
- if ( empty( $user_id ) ) {
1126
- $user_id = ( bp_displayed_user_id() ) ? bp_displayed_user_id() : bp_loggedin_user_id();
1127
- }
1128
-
1129
- return BP_Activity_Activity::total_favorite_count( $user_id );
1130
- }
1131
-
1132
- /** Meta *********************************************************************/
1133
-
1134
- /**
1135
- * Delete a meta entry from the DB for an activity stream item.
1136
- *
1137
- * @since 1.2.0
1138
- *
1139
- * @global object $wpdb WordPress database access object.
1140
- *
1141
- * @param int $activity_id ID of the activity item whose metadata is being deleted.
1142
- * @param string $meta_key Optional. The key of the metadata being deleted. If
1143
- * omitted, all metadata associated with the activity
1144
- * item will be deleted.
1145
- * @param string $meta_value Optional. If present, the metadata will only be
1146
- * deleted if the meta_value matches this parameter.
1147
- * @param bool $delete_all Optional. If true, delete matching metadata entries
1148
- * for all objects, ignoring the specified object_id. Otherwise,
1149
- * only delete matching metadata entries for the specified
1150
- * activity item. Default: false.
1151
- * @return bool True on success, false on failure.
1152
- */
1153
- function bp_activity_delete_meta( $activity_id, $meta_key = '', $meta_value = '', $delete_all = false ) {
1154
-
1155
- // Legacy - if no meta_key is passed, delete all for the item.
1156
- if ( empty( $meta_key ) ) {
1157
- $all_meta = bp_activity_get_meta( $activity_id );
1158
- $keys = ! empty( $all_meta ) ? array_keys( $all_meta ) : array();
1159
-
1160
- // With no meta_key, ignore $delete_all.
1161
- $delete_all = false;
1162
- } else {
1163
- $keys = array( $meta_key );
1164
- }
1165
-
1166
- $retval = true;
1167
-
1168
- add_filter( 'query', 'bp_filter_metaid_column_name' );
1169
- foreach ( $keys as $key ) {
1170
- $retval = delete_metadata( 'activity', $activity_id, $key, $meta_value, $delete_all );
1171
- }
1172
- remove_filter( 'query', 'bp_filter_metaid_column_name' );
1173
-
1174
- return $retval;
1175
- }
1176
-
1177
- /**
1178
- * Get metadata for a given activity item.
1179
- *
1180
- * @since 1.2.0
1181
- *
1182
- * @param int $activity_id ID of the activity item whose metadata is being requested.
1183
- * @param string $meta_key Optional. If present, only the metadata matching
1184
- * that meta key will be returned. Otherwise, all metadata for the
1185
- * activity item will be fetched.
1186
- * @param bool $single Optional. If true, return only the first value of the
1187
- * specified meta_key. This parameter has no effect if meta_key is not
1188
- * specified. Default: true.
1189
- * @return mixed The meta value(s) being requested.
1190
- */
1191
- function bp_activity_get_meta( $activity_id = 0, $meta_key = '', $single = true ) {
1192
- add_filter( 'query', 'bp_filter_metaid_column_name' );
1193
- $retval = get_metadata( 'activity', $activity_id, $meta_key, $single );
1194
- remove_filter( 'query', 'bp_filter_metaid_column_name' );
1195
-
1196
- /**
1197
- * Filters the metadata for a specified activity item.
1198
- *
1199
- * @since 1.5.0
1200
- *
1201
- * @param mixed $retval The meta values for the activity item.
1202
- * @param int $activity_id ID of the activity item.
1203
- * @param string $meta_key Meta key for the value being requested.
1204
- * @param bool $single Whether to return one matched meta key row or all.
1205
- */
1206
- return apply_filters( 'bp_activity_get_meta', $retval, $activity_id, $meta_key, $single );
1207
- }
1208
-
1209
- /**
1210
- * Update a piece of activity meta.
1211
- *
1212
- * @since 1.2.0
1213
- *
1214
- * @param int $activity_id ID of the activity item whose metadata is being updated.
1215
- * @param string $meta_key Key of the metadata being updated.
1216
- * @param mixed $meta_value Value to be set.
1217
- * @param mixed $prev_value Optional. If specified, only update existing metadata entries
1218
- * with the specified value. Otherwise, update all entries.
1219
- * @return bool|int Returns false on failure. On successful update of existing
1220
- * metadata, returns true. On successful creation of new metadata,
1221
- * returns the integer ID of the new metadata row.
1222
- */
1223
- function bp_activity_update_meta( $activity_id, $meta_key, $meta_value, $prev_value = '' ) {
1224
- add_filter( 'query', 'bp_filter_metaid_column_name' );
1225
- $retval = update_metadata( 'activity', $activity_id, $meta_key, $meta_value, $prev_value );
1226
- remove_filter( 'query', 'bp_filter_metaid_column_name' );
1227
-
1228
- return $retval;
1229
- }
1230
-
1231
- /**
1232
- * Add a piece of activity metadata.
1233
- *
1234
- * @since 2.0.0
1235
- *
1236
- * @param int $activity_id ID of the activity item.
1237
- * @param string $meta_key Metadata key.
1238
- * @param mixed $meta_value Metadata value.
1239
- * @param bool $unique Optional. Whether to enforce a single metadata value for the
1240
- * given key. If true, and the object already has a value for
1241
- * the key, no change will be made. Default: false.
1242
- * @return int|bool The meta ID on successful update, false on failure.
1243
- */
1244
- function bp_activity_add_meta( $activity_id, $meta_key, $meta_value, $unique = false ) {
1245
- add_filter( 'query', 'bp_filter_metaid_column_name' );
1246
- $retval = add_metadata( 'activity', $activity_id, $meta_key, $meta_value, $unique );
1247
- remove_filter( 'query', 'bp_filter_metaid_column_name' );
1248
-
1249
- return $retval;
1250
- }
1251
-
1252
- /** Clean up *****************************************************************/
1253
-
1254
- /**
1255
- * Completely remove a user's activity data.
1256
- *
1257
- * @since 1.5.0
1258
- *
1259
- * @param int $user_id ID of the user whose activity is being deleted.
1260
- * @return bool
1261
- */
1262
- function bp_activity_remove_all_user_data( $user_id = 0 ) {
1263
-
1264
- // Do not delete user data unless a logged in user says so.
1265
- if ( empty( $user_id ) || ! is_user_logged_in() ) {
1266
- return false;
1267
- }
1268
-
1269
- // Clear the user's activity from the sitewide stream and clear their activity tables.
1270
- bp_activity_delete( array( 'user_id' => $user_id ) );
1271
-
1272
- // Remove any usermeta.
1273
- bp_delete_user_meta( $user_id, 'bp_latest_update' );
1274
- bp_delete_user_meta( $user_id, 'bp_favorite_activities' );
1275
-
1276
- // Execute additional code
1277
- do_action( 'bp_activity_remove_data', $user_id ); // Deprecated! Do not use!
1278
-
1279
- /**
1280
- * Fires after the removal of all of a user's activity data.
1281
- *
1282
- * @since 1.5.0
1283
- *
1284
- * @param int $user_id ID of the user being deleted.
1285
- */
1286
- do_action( 'bp_activity_remove_all_user_data', $user_id );
1287
- }
1288
- add_action( 'wpmu_delete_user', 'bp_activity_remove_all_user_data' );
1289
- add_action( 'delete_user', 'bp_activity_remove_all_user_data' );
1290
-
1291
- /**
1292
- * Mark all of the user's activity as spam.
1293
- *
1294
- * @since 1.6.0
1295
- *
1296
- * @global object $wpdb WordPress database access object.
1297
- *
1298
- * @param int $user_id ID of the user whose activity is being spammed.
1299
- * @return bool
1300
- */
1301
- function bp_activity_spam_all_user_data( $user_id = 0 ) {
1302
- global $wpdb;
1303
-
1304
- // Do not delete user data unless a logged in user says so.
1305
- if ( empty( $user_id ) || ! is_user_logged_in() ) {
1306
- return false;
1307
- }
1308
-
1309
- // Get all the user's activities.
1310
- $activities = bp_activity_get( array(
1311
- 'display_comments' => 'stream',
1312
- 'filter' => array( 'user_id' => $user_id ),
1313
- 'show_hidden' => true
1314
- ) );
1315
-
1316
- $bp = buddypress();
1317
-
1318
- // Mark each as spam.
1319
- foreach ( (array) $activities['activities'] as $activity ) {
1320
-
1321
- // Create an activity object.
1322
- $activity_obj = new BP_Activity_Activity;
1323
- foreach ( $activity as $k => $v ) {
1324
- $activity_obj->$k = $v;
1325
- }
1326
-
1327
- // Mark as spam.
1328
- bp_activity_mark_as_spam( $activity_obj );
1329
-
1330
- /*
1331
- * If Akismet is present, update the activity history meta.
1332
- *
1333
- * This is usually taken care of when BP_Activity_Activity::save() happens, but
1334
- * as we're going to be updating all the activity statuses directly, for efficiency,
1335
- * we need to update manually.
1336
- */
1337
- if ( ! empty( $bp->activity->akismet ) ) {
1338
- $bp->activity->akismet->update_activity_spam_meta( $activity_obj );
1339
- }
1340
-
1341
- // Tidy up.
1342
- unset( $activity_obj );
1343
- }
1344
-
1345
- // Mark all of this user's activities as spam.
1346
- $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET is_spam = 1 WHERE user_id = %d", $user_id ) );
1347
-
1348
- /**
1349
- * Fires after all activity data from a user has been marked as spam.
1350
- *
1351
- * @since 1.6.0
1352
- *
1353
- * @param int $user_id ID of the user whose activity is being marked as spam.
1354
- * @param array $activities Array of activity items being marked as spam.
1355
- */
1356
- do_action( 'bp_activity_spam_all_user_data', $user_id, $activities['activities'] );
1357
- }
1358
- add_action( 'bp_make_spam_user', 'bp_activity_spam_all_user_data' );
1359
-
1360
- /**
1361
- * Mark all of the user's activity as ham (not spam).
1362
- *
1363
- * @since 1.6.0
1364
- *
1365
- * @global object $wpdb WordPress database access object.
1366
- *
1367
- * @param int $user_id ID of the user whose activity is being hammed.
1368
- * @return bool
1369
- */
1370
- function bp_activity_ham_all_user_data( $user_id = 0 ) {
1371
- global $wpdb;
1372
-
1373
- // Do not delete user data unless a logged in user says so.
1374
- if ( empty( $user_id ) || ! is_user_logged_in() ) {
1375
- return false;
1376
- }
1377
-
1378
- // Get all the user's activities.
1379
- $activities = bp_activity_get( array(
1380
- 'display_comments' => 'stream',
1381
- 'filter' => array( 'user_id' => $user_id ),
1382
- 'show_hidden' => true,
1383
- 'spam' => 'all'
1384
- ) );
1385
-
1386
- $bp = buddypress();
1387
-
1388
- // Mark each as not spam.
1389
- foreach ( (array) $activities['activities'] as $activity ) {
1390
-
1391
- // Create an activity object.
1392
- $activity_obj = new BP_Activity_Activity;
1393
- foreach ( $activity as $k => $v ) {
1394
- $activity_obj->$k = $v;
1395
- }
1396
-
1397
- // Mark as not spam.
1398
- bp_activity_mark_as_ham( $activity_obj );
1399
-
1400
- /*
1401
- * If Akismet is present, update the activity history meta.
1402
- *
1403
- * This is usually taken care of when BP_Activity_Activity::save() happens, but
1404
- * as we're going to be updating all the activity statuses directly, for efficiency,
1405
- * we need to update manually.
1406
- */
1407
- if ( ! empty( $bp->activity->akismet ) ) {
1408
- $bp->activity->akismet->update_activity_ham_meta( $activity_obj );
1409
- }
1410
-
1411
- // Tidy up.
1412
- unset( $activity_obj );
1413
- }
1414
-
1415
- // Mark all of this user's activities as not spam.
1416
- $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET is_spam = 0 WHERE user_id = %d", $user_id ) );
1417
-
1418
- /**
1419
- * Fires after all activity data from a user has been marked as ham.
1420
- *
1421
- * @since 1.6.0
1422
- *
1423
- * @param int $user_id ID of the user whose activity is being marked as ham.
1424
- * @param array $activities Array of activity items being marked as ham.
1425
- */
1426
- do_action( 'bp_activity_ham_all_user_data', $user_id, $activities['activities'] );
1427
- }
1428
- add_action( 'bp_make_ham_user', 'bp_activity_ham_all_user_data' );
1429
-
1430
- /**
1431
- * Register the activity stream actions for updates.
1432
- *
1433
- * @since 1.6.0
1434
- */
1435
- function bp_activity_register_activity_actions() {
1436
- $bp = buddypress();
1437
-
1438
- bp_activity_set_action(
1439
- $bp->activity->id,
1440
- 'activity_update',
1441
- __( 'Posted a status update', 'buddypress' ),
1442
- 'bp_activity_format_activity_action_activity_update',
1443
- __( 'Updates', 'buddypress' ),
1444
- array( 'activity', 'group', 'member', 'member_groups' )
1445
- );
1446
-
1447
- bp_activity_set_action(
1448
- $bp->activity->id,
1449
- 'activity_comment',
1450
- __( 'Replied to a status update', 'buddypress' ),
1451
- 'bp_activity_format_activity_action_activity_comment',
1452
- __( 'Activity Comments', 'buddypress' )
1453
- );
1454
-
1455
- /**
1456
- * Fires at the end of the activity actions registration.
1457
- *
1458
- * Allows plugin authors to add their own activity actions alongside the core actions.
1459
- *
1460
- * @since 1.6.0
1461
- */
1462
- do_action( 'bp_activity_register_activity_actions' );
1463
-
1464
- // Backpat. Don't use this.
1465
- do_action( 'updates_register_activity_actions' );
1466
- }
1467
- add_action( 'bp_register_activity_actions', 'bp_activity_register_activity_actions' );
1468
-
1469
- /**
1470
- * Generate an activity action string for an activity item.
1471
- *
1472
- * @since 2.0.0
1473
- *
1474
- * @param object $activity Activity data object.
1475
- * @return string|bool Returns false if no callback is found, otherwise returns
1476
- * the formatted action string.
1477
- */
1478
- function bp_activity_generate_action_string( $activity ) {
1479
-
1480
- // Check for valid input.
1481
- if ( empty( $activity->component ) || empty( $activity->type ) ) {
1482
- return false;
1483
- }
1484
-
1485
- // Check for registered format callback.
1486
- $actions = bp_activity_get_actions();
1487
- if ( empty( $actions->{$activity->component}->{$activity->type}['format_callback'] ) ) {
1488
- return false;
1489
- }
1490
-
1491
- // We apply the format_callback as a filter.
1492
- add_filter( 'bp_activity_generate_action_string', $actions->{$activity->component}->{$activity->type}['format_callback'], 10, 2 );
1493
-
1494
- /**
1495
- * Filters the string for the activity action being returned.
1496
- *
1497
- * @since 2.0.0
1498
- *
1499
- * @param BP_Activity_Activity $action Action string being requested.
1500
- * @param BP_Activity_Activity $activity Activity item object.
1501
- */
1502
- $action = apply_filters( 'bp_activity_generate_action_string', $activity->action, $activity );
1503
-
1504
- // Remove the filter for future activity items.
1505
- remove_filter( 'bp_activity_generate_action_string', $actions->{$activity->component}->{$activity->type}['format_callback'], 10 );
1506
-
1507
- return $action;
1508
- }
1509
-
1510
- /**
1511
- * Format 'activity_update' activity actions.
1512
- *
1513
- * @since 2.0.0
1514
- *
1515
- * @param string $action Static activity action.
1516
- * @param object $activity Activity data object.
1517
- * @return string $action
1518
- */
1519
- function bp_activity_format_activity_action_activity_update( $action, $activity ) {
1520
- $action = sprintf( __( '%s posted an update', 'buddypress' ), bp_core_get_userlink( $activity->user_id ) );
1521
-
1522
- /**
1523
- * Filters the formatted activity action update string.
1524
- *
1525
- * @since 1.2.0
1526
- *
1527
- * @param string $action Activity action string value.
1528
- * @param BP_Activity_Activity $activity Activity item object.
1529
- */
1530
- return apply_filters( 'bp_activity_new_update_action', $action, $activity );
1531
- }
1532
-
1533
- /**
1534
- * Format 'activity_comment' activity actions.
1535
- *
1536
- * @since 2.0.0
1537
- *
1538
- * @param string $action Static activity action.
1539
- * @param object $activity Activity data object.
1540
- * @return string $action
1541
- */
1542
- function bp_activity_format_activity_action_activity_comment( $action, $activity ) {
1543
- $action = sprintf( __( '%s posted a new activity comment', 'buddypress' ), bp_core_get_userlink( $activity->user_id ) );
1544
-
1545
- /**
1546
- * Filters the formatted activity action comment string.
1547
- *
1548
- * @since 1.2.0
1549
- *
1550
- * @param string $action Activity action string value.
1551
- * @param BP_Activity_Activity $activity Activity item object.
1552
- */
1553
- return apply_filters( 'bp_activity_comment_action', $action, $activity );
1554
- }
1555
-
1556
- /**
1557
- * Format activity action strings for custom post types.
1558
- *
1559
- * @since 2.2.0
1560
- *
1561
- * @param string $action Static activity action.
1562
- * @param object $activity Activity data object.
1563
- * @return string $action
1564
- */
1565
- function bp_activity_format_activity_action_custom_post_type_post( $action, $activity ) {
1566
- $bp = buddypress();
1567
-
1568
- // Fetch all the tracked post types once.
1569
- if ( empty( $bp->activity->track ) ) {
1570
- $bp->activity->track = bp_activity_get_post_types_tracking_args();
1571
- }
1572
-
1573
- if ( empty( $activity->type ) || empty( $bp->activity->track[ $activity->type ] ) ) {
1574
- return $action;
1575
- }
1576
-
1577
- $user_link = bp_core_get_userlink( $activity->user_id );
1578
- $blog_url = get_home_url( $activity->item_id );
1579
-
1580
- if ( empty( $activity->post_url ) ) {
1581
- $post_url = add_query_arg( 'p', $activity->secondary_item_id, trailingslashit( $blog_url ) );
1582
- } else {
1583
- $post_url = $activity->post_url;
1584
- }
1585
-
1586
- if ( is_multisite() ) {
1587
- $blog_link = '<a href="' . esc_url( $blog_url ) . '">' . get_blog_option( $activity->item_id, 'blogname' ) . '</a>';
1588
-
1589
- if ( ! empty( $bp->activity->track[ $activity->type ]->new_post_type_action_ms ) ) {
1590
- $action = sprintf( $bp->activity->track[ $activity->type ]->new_post_type_action_ms, $user_link, $post_url, $blog_link );
1591
- } else {
1592
- $action = sprintf( _x( '%1$s wrote a new <a href="%2$s">item</a>, on the site %3$s', 'Activity Custom Post Type post action', 'buddypress' ), $user_link, esc_url( $post_url ), $blog_link );
1593
- }
1594
- } else {
1595
- if ( ! empty( $bp->activity->track[ $activity->type ]->new_post_type_action ) ) {
1596
- $action = sprintf( $bp->activity->track[ $activity->type ]->new_post_type_action, $user_link, $post_url );
1597
- } else {
1598
- $action = sprintf( _x( '%1$s wrote a new <a href="%2$s">item</a>', 'Activity Custom Post Type post action', 'buddypress' ), $user_link, esc_url( $post_url ) );
1599
- }
1600
- }
1601
-
1602
- /**
1603
- * Filters the formatted custom post type activity post action string.
1604
- *
1605
- * @since 2.2.0
1606
- *
1607
- * @param string $action Activity action string value.
1608
- * @param BP_Activity_Activity $activity Activity item object.
1609
- */
1610
- return apply_filters( 'bp_activity_custom_post_type_post_action', $action, $activity );
1611
- }
1612
-
1613
- /**
1614
- * Format activity action strings for custom post types comments.
1615
- *
1616
- * @since 2.5.0
1617
- *
1618
- * @param string $action Static activity action.
1619
- * @param object $activity Activity data object.
1620
- *
1621
- * @return string
1622
- */
1623
- function bp_activity_format_activity_action_custom_post_type_comment( $action, $activity ) {
1624
- $bp = buddypress();
1625
-
1626
- // Fetch all the tracked post types once.
1627
- if ( empty( $bp->activity->track ) ) {
1628
- $bp->activity->track = bp_activity_get_post_types_tracking_args();
1629
- }
1630
-
1631
- if ( empty( $activity->type ) || empty( $bp->activity->track[ $activity->type ] ) ) {
1632
- return $action;
1633
- }
1634
-
1635
- $user_link = bp_core_get_userlink( $activity->user_id );
1636
-
1637
- if ( is_multisite() ) {
1638
- $blog_link = '<a href="' . esc_url( get_home_url( $activity->item_id ) ) . '">' . get_blog_option( $activity->item_id, 'blogname' ) . '</a>';
1639
-
1640
- if ( ! empty( $bp->activity->track[ $activity->type ]->new_post_type_comment_action_ms ) ) {
1641
- $action = sprintf( $bp->activity->track[ $activity->type ]->new_post_type_comment_action_ms, $user_link, $activity->primary_link, $blog_link );
1642
- } else {
1643
- $action = sprintf( _x( '%1$s commented on the <a href="%2$s">item</a>, on the site %3$s', 'Activity Custom Post Type comment action', 'buddypress' ), $user_link, $activity->primary_link, $blog_link );
1644
- }
1645
- } else {
1646
- if ( ! empty( $bp->activity->track[ $activity->type ]->new_post_type_comment_action ) ) {
1647
- $action = sprintf( $bp->activity->track[ $activity->type ]->new_post_type_comment_action, $user_link, $activity->primary_link );
1648
- } else {
1649
- $action = sprintf( _x( '%1$s commented on the <a href="%2$s">item</a>', 'Activity Custom Post Type post comment action', 'buddypress' ), $user_link, $activity->primary_link );
1650
- }
1651
- }
1652
-
1653
- /**
1654
- * Filters the formatted custom post type activity comment action string.
1655
- *
1656
- * @since 2.5.0
1657
- *
1658
- * @param string $action Activity action string value.
1659
- * @param BP_Activity_Activity $activity Activity item object.
1660
- */
1661
- return apply_filters( 'bp_activity_custom_post_type_comment_action', $action, $activity );
1662
- }
1663
-
1664
- /*
1665
- * Business functions are where all the magic happens in BuddyPress. They will
1666
- * handle the actual saving or manipulation of information. Usually they will
1667
- * hand off to a database class for data access, then return
1668
- * true or false on success or failure.
1669
- */
1670
-
1671
- /**
1672
- * Retrieve an activity or activities.
1673
- *
1674
- * The bp_activity_get() function shares all arguments with BP_Activity_Activity::get().
1675
- * The following is a list of bp_activity_get() parameters that have different
1676
- * default values from BP_Activity_Activity::get() (value in parentheses is
1677
- * the default for the bp_activity_get()).
1678
- * - 'per_page' (false)
1679
- *
1680
- * @since 1.2.0
1681
- * @since 2.4.0 Introduced the `$fields` parameter.
1682
- *
1683
- * @see BP_Activity_Activity::get() For more information on accepted arguments
1684
- * and the format of the returned value.
1685
- *
1686
- * @param array|string $args See BP_Activity_Activity::get() for description.
1687
- * @return array $activity See BP_Activity_Activity::get() for description.
1688
- */
1689
- function bp_activity_get( $args = '' ) {
1690
-
1691
- $r = bp_parse_args( $args, array(
1692
- 'max' => false, // Maximum number of results to return.
1693
- 'fields' => 'all',
1694
- 'page' => 1, // Page 1 without a per_page will result in no pagination.
1695
- 'per_page' => false, // results per page
1696
- 'sort' => 'DESC', // sort ASC or DESC
1697
- 'display_comments' => false, // False for no comments. 'stream' for within stream display, 'threaded' for below each activity item.
1698
-
1699
- 'search_terms' => false, // Pass search terms as a string
1700
- 'meta_query' => false, // Filter by activity meta. See WP_Meta_Query for format
1701
- 'date_query' => false, // Filter by date. See first parameter of WP_Date_Query for format.
1702
- 'filter_query' => false,
1703
- 'show_hidden' => false, // Show activity items that are hidden site-wide?
1704
- 'exclude' => false, // Comma-separated list of activity IDs to exclude.
1705
- 'in' => false, // Comma-separated list or array of activity IDs to which you
1706
- // want to limit the query.
1707
- 'spam' => 'ham_only', // 'ham_only' (default), 'spam_only' or 'all'.
1708
- 'update_meta_cache' => true,
1709
- 'count_total' => false,
1710
- 'scope' => false,
1711
-
1712
- /**
1713
- * Pass filters as an array -- all filter items can be multiple values comma separated:
1714
- * array(
1715
- * 'user_id' => false, // User ID to filter on.
1716
- * 'object' => false, // Object to filter on e.g. groups, profile, status, friends.
1717
- * 'action' => false, // Action to filter on e.g. activity_update, profile_updated.
1718
- * 'primary_id' => false, // Object ID to filter on e.g. a group_id or forum_id or blog_id etc.
1719
- * 'secondary_id' => false, // Secondary object ID to filter on e.g. a post_id.
1720
- * );
1721
- */
1722
- 'filter' => array()
1723
- ), 'activity_get' );
1724
-
1725
- $activity = BP_Activity_Activity::get( array(
1726
- 'page' => $r['page'],
1727
- 'per_page' => $r['per_page'],
1728
- 'max' => $r['max'],
1729
- 'sort' => $r['sort'],
1730
- 'search_terms' => $r['search_terms'],
1731
- 'meta_query' => $r['meta_query'],
1732
- 'date_query' => $r['date_query'],
1733
- 'filter_query' => $r['filter_query'],
1734
- 'filter' => $r['filter'],
1735
- 'scope' => $r['scope'],
1736
- 'display_comments' => $r['display_comments'],
1737
- 'show_hidden' => $r['show_hidden'],
1738
- 'exclude' => $r['exclude'],
1739
- 'in' => $r['in'],
1740
- 'spam' => $r['spam'],
1741
- 'update_meta_cache' => $r['update_meta_cache'],
1742
- 'count_total' => $r['count_total'],
1743
- 'fields' => $r['fields'],
1744
- ) );
1745
-
1746
- /**
1747
- * Filters the requested activity item(s).
1748
- *
1749
- * @since 1.2.0
1750
- *
1751
- * @param BP_Activity_Activity $activity Requested activity object.
1752
- * @param array $r Arguments used for the activity query.
1753
- */
1754
- return apply_filters_ref_array( 'bp_activity_get', array( &$activity, &$r ) );
1755
- }
1756
-
1757
- /**
1758
- * Fetch specific activity items.
1759
- *
1760
- * @since 1.2.0
1761
- *
1762
- * @see BP_Activity_Activity::get() For more information on accepted arguments.
1763
- *
1764
- * @param array|string $args {
1765
- * All arguments and defaults are shared with BP_Activity_Activity::get(),
1766
- * except for the following:
1767
- * @type string|int|array Single activity ID, comma-separated list of IDs,
1768
- * or array of IDs.
1769
- * }
1770
- * @return array $activity See BP_Activity_Activity::get() for description.
1771
- */
1772
- function bp_activity_get_specific( $args = '' ) {
1773
-
1774
- $r = bp_parse_args( $args, array(
1775
- 'activity_ids' => false, // A single activity_id or array of IDs.
1776
- 'display_comments' => false, // True or false to display threaded comments for these specific activity items.
1777
- 'max' => false, // Maximum number of results to return.
1778
- 'page' => 1, // Page 1 without a per_page will result in no pagination.
1779
- 'per_page' => false, // Results per page.
1780
- 'show_hidden' => true, // When fetching specific items, show all.
1781
- 'sort' => 'DESC', // Sort ASC or DESC
1782
- 'spam' => 'ham_only', // Retrieve items marked as spam.
1783
- 'update_meta_cache' => true,
1784
- ), 'activity_get_specific' );
1785
-
1786
- $get_args = array(
1787
- 'display_comments' => $r['display_comments'],
1788
- 'in' => $r['activity_ids'],
1789
- 'max' => $r['max'],
1790
- 'page' => $r['page'],
1791
- 'per_page' => $r['per_page'],
1792
- 'show_hidden' => $r['show_hidden'],
1793
- 'sort' => $r['sort'],
1794
- 'spam' => $r['spam'],
1795
- 'update_meta_cache' => $r['update_meta_cache'],
1796
- );
1797
-
1798
- /**
1799
- * Filters the requested specific activity item.
1800
- *
1801
- * @since 1.2.0
1802
- *
1803
- * @param BP_Activity_Activity $activity Requested activity object.
1804
- * @param array $args Original passed in arguments.
1805
- * @param array $get_args Constructed arguments used with request.
1806
- */
1807
- return apply_filters( 'bp_activity_get_specific', BP_Activity_Activity::get( $get_args ), $args, $get_args );
1808
- }
1809
-
1810
- /**
1811
- * Add an activity item.
1812
- *
1813
- * @since 1.1.0
1814
- * @since 2.6.0 Added 'error_type' parameter to $args.
1815
- *
1816
- * @param array|string $args {
1817
- * An array of arguments.
1818
- * @type int|bool $id Pass an activity ID to update an existing item, or
1819
- * false to create a new item. Default: false.
1820
- * @type string $action Optional. The activity action/description, typically
1821
- * something like "Joe posted an update". Values passed to this param
1822
- * will be stored in the database and used as a fallback for when the
1823
- * activity item's format_callback cannot be found (eg, when the
1824
- * component is disabled). As long as you have registered a
1825
- * format_callback for your $type, it is unnecessary to include this
1826
- * argument - BP will generate it automatically.
1827
- * See {@link bp_activity_set_action()}.
1828
- * @type string $content Optional. The content of the activity item.
1829
- * @type string $component The unique name of the component associated with
1830
- * the activity item - 'groups', 'profile', etc.
1831
- * @type string $type The specific activity type, used for directory
1832
- * filtering. 'new_blog_post', 'activity_update', etc.
1833
- * @type string $primary_link Optional. The URL for this item, as used in
1834
- * RSS feeds. Defaults to the URL for this activity
1835
- * item's permalink page.
1836
- * @type int|bool $user_id Optional. The ID of the user associated with the activity
1837
- * item. May be set to false or 0 if the item is not related
1838
- * to any user. Default: the ID of the currently logged-in user.
1839
- * @type int $item_id Optional. The ID of the associated item.
1840
- * @type int $secondary_item_id Optional. The ID of a secondary associated item.
1841
- * @type string $date_recorded Optional. The GMT time, in Y-m-d h:i:s format, when
1842
- * the item was recorded. Defaults to the current time.
1843
- * @type bool $hide_sitewide Should the item be hidden on sitewide streams?
1844
- * Default: false.
1845
- * @type bool $is_spam Should the item be marked as spam? Default: false.
1846
- * @type string $error_type Optional. Error type. Either 'bool' or 'wp_error'. Default: 'bool'.
1847
- * }
1848
- * @return WP_Error|bool|int The ID of the activity on success. False on error.
1849
- */
1850
- function bp_activity_add( $args = '' ) {
1851
-
1852
- $r = bp_parse_args( $args, array(
1853
- 'id' => false, // Pass an existing activity ID to update an existing entry.
1854
- 'action' => '', // The activity action - e.g. "Jon Doe posted an update"
1855
- 'content' => '', // Optional: The content of the activity item e.g. "BuddyPress is awesome guys!"
1856
- 'component' => false, // The name/ID of the component e.g. groups, profile, mycomponent.
1857
- 'type' => false, // The activity type e.g. activity_update, profile_updated.
1858
- 'primary_link' => '', // Optional: The primary URL for this item in RSS feeds (defaults to activity permalink).
1859
- 'user_id' => bp_loggedin_user_id(), // Optional: The user to record the activity for, can be false if this activity is not for a user.
1860
- 'item_id' => false, // Optional: The ID of the specific item being recorded, e.g. a blog_id.
1861
- 'secondary_item_id' => false, // Optional: A second ID used to further filter e.g. a comment_id.
1862
- 'recorded_time' => bp_core_current_time(), // The GMT time that this activity was recorded.
1863
- 'hide_sitewide' => false, // Should this be hidden on the sitewide activity stream?
1864
- 'is_spam' => false, // Is this activity item to be marked as spam?
1865
- 'error_type' => 'bool'
1866
- ), 'activity_add' );
1867
-
1868
- // Make sure we are backwards compatible.
1869
- if ( empty( $r['component'] ) && !empty( $r['component_name'] ) ) {
1870
- $r['component'] = $r['component_name'];
1871
- }
1872
-
1873
- if ( empty( $r['type'] ) && !empty( $r['component_action'] ) ) {
1874
- $r['type'] = $r['component_action'];
1875
- }
1876
-
1877
- // Setup activity to be added.
1878
- $activity = new BP_Activity_Activity( $r['id'] );
1879
- $activity->user_id = $r['user_id'];
1880
- $activity->component = $r['component'];
1881
- $activity->type = $r['type'];
1882
- $activity->content = $r['content'];
1883
- $activity->primary_link = $r['primary_link'];
1884
- $activity->item_id = $r['item_id'];
1885
- $activity->secondary_item_id = $r['secondary_item_id'];
1886
- $activity->date_recorded = $r['recorded_time'];
1887
- $activity->hide_sitewide = $r['hide_sitewide'];
1888
- $activity->is_spam = $r['is_spam'];
1889
- $activity->error_type = $r['error_type'];
1890
- $activity->action = ! empty( $r['action'] )
1891
- ? $r['action']
1892
- : bp_activity_generate_action_string( $activity );
1893
-
1894
- $save = $activity->save();
1895
-
1896
- if ( 'wp_error' === $r['error_type'] && is_wp_error( $save ) ) {
1897
- return $save;
1898
- } elseif ('bool' === $r['error_type'] && false === $save ) {
1899
- return false;
1900
- }
1901
-
1902
- // If this is an activity comment, rebuild the tree.
1903
- if ( 'activity_comment' === $activity->type ) {
1904
- // Also clear the comment cache for the parent activity ID.
1905
- wp_cache_delete( $activity->item_id, 'bp_activity_comments' );
1906
-
1907
- BP_Activity_Activity::rebuild_activity_comment_tree( $activity->item_id );
1908
- }
1909
-
1910
- wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
1911
-
1912
- /**
1913
- * Fires at the end of the execution of adding a new activity item, before returning the new activity item ID.
1914
- *
1915
- * @since 1.1.0
1916
- *
1917
- * @param array $r Array of parsed arguments for the activity item being added.
1918
- */
1919
- do_action( 'bp_activity_add', $r );
1920
-
1921
- return $activity->id;
1922
- }
1923
-
1924
- /**
1925
- * Post an activity update.
1926
- *
1927
- * @since 1.2.0
1928
- *
1929
- * @param array|string $args {
1930
- * @type string $content The content of the activity update.
1931
- * @type int $user_id Optional. Defaults to the logged-in user.
1932
- * @type string $error_type Optional. Error type to return. Either 'bool' or 'wp_error'. Defaults to
1933
- * 'bool' for boolean. 'wp_error' will return a WP_Error object.
1934
- * }
1935
- * @return int|bool|WP_Error $activity_id The activity id on success. On failure, either boolean false or WP_Error
1936
- * object depending on the 'error_type' $args parameter.
1937
- */
1938
- function bp_activity_post_update( $args = '' ) {
1939
-
1940
- $r = wp_parse_args( $args, array(
1941
- 'content' => false,
1942
- 'user_id' => bp_loggedin_user_id(),
1943
- 'error_type' => 'bool',
1944
- ) );
1945
-
1946
- if ( empty( $r['content'] ) || !strlen( trim( $r['content'] ) ) ) {
1947
- return false;
1948
- }
1949
-
1950
- if ( bp_is_user_inactive( $r['user_id'] ) ) {
1951
- return false;
1952
- }
1953
-
1954
- // Record this on the user's profile.
1955
- $activity_content = $r['content'];
1956
- $primary_link = bp_core_get_userlink( $r['user_id'], false, true );
1957
-
1958
- /**
1959
- * Filters the new activity content for current activity item.
1960
- *
1961
- * @since 1.2.0
1962
- *
1963
- * @param string $activity_content Activity content posted by user.
1964
- */
1965
- $add_content = apply_filters( 'bp_activity_new_update_content', $activity_content );
1966
-
1967
- /**
1968
- * Filters the activity primary link for current activity item.
1969
- *
1970
- * @since 1.2.0
1971
- *
1972
- * @param string $primary_link Link to the profile for the user who posted the activity.
1973
- */
1974
- $add_primary_link = apply_filters( 'bp_activity_new_update_primary_link', $primary_link );
1975
-
1976
- // Now write the values.
1977
- $activity_id = bp_activity_add( array(
1978
- 'user_id' => $r['user_id'],
1979
- 'content' => $add_content,
1980
- 'primary_link' => $add_primary_link,
1981
- 'component' => buddypress()->activity->id,
1982
- 'type' => 'activity_update',
1983
- 'error_type' => $r['error_type']
1984
- ) );
1985
-
1986
- // Bail on failure.
1987
- if ( false === $activity_id || is_wp_error( $activity_id ) ) {
1988
- return $activity_id;
1989
- }
1990
-
1991
- /**
1992
- * Filters the latest update content for the activity item.
1993
- *
1994
- * @since 1.6.0
1995
- *
1996
- * @param string $r Content of the activity update.
1997
- * @param string $activity_content Content of the activity update.
1998
- */
1999
- $activity_content = apply_filters( 'bp_activity_latest_update_content', $r['content'], $activity_content );
2000
-
2001
- // Add this update to the "latest update" usermeta so it can be fetched anywhere.
2002
- bp_update_user_meta( bp_loggedin_user_id(), 'bp_latest_update', array(
2003
- 'id' => $activity_id,
2004
- 'content' => $activity_content
2005
- ) );
2006
-
2007
- /**
2008
- * Fires at the end of an activity post update, before returning the updated activity item ID.
2009
- *
2010
- * @since 1.2.0
2011
- *
2012
- * @param string $content Content of the activity post update.
2013
- * @param int $user_id ID of the user posting the activity update.
2014
- * @param int $activity_id ID of the activity item being updated.
2015
- */
2016
- do_action( 'bp_activity_posted_update', $r['content'], $r['user_id'], $activity_id );
2017
-
2018
- return $activity_id;
2019
- }
2020
-
2021
- /**
2022
- * Create an activity item for a newly published post type post.
2023
- *
2024
- * @since 2.2.0
2025
- *
2026
- * @param int $post_id ID of the new post.
2027
- * @param WP_Post|null $post Post object.
2028
- * @param int $user_id ID of the post author.
2029
- * @return null|WP_Error|bool|int The ID of the activity on success. False on error.
2030
- */
2031
- function bp_activity_post_type_publish( $post_id = 0, $post = null, $user_id = 0 ) {
2032
-
2033
- if ( ! is_a( $post, 'WP_Post' ) ) {
2034
- return;
2035
- }
2036
-
2037
- // Get the post type tracking args.
2038
- $activity_post_object = bp_activity_get_post_type_tracking_args( $post->post_type );
2039
-
2040
- if ( 'publish' != $post->post_status || ! empty( $post->post_password ) || empty( $activity_post_object->action_id ) ) {
2041
- return;
2042
- }
2043
-
2044
- if ( empty( $post_id ) ) {
2045
- $post_id = $post->ID;
2046
- }
2047
-
2048
- $blog_id = get_current_blog_id();
2049
-
2050
- if ( empty( $user_id ) ) {
2051
- $user_id = (int) $post->post_author;
2052
- }
2053
-
2054
- // Bail if an activity item already exists for this post.
2055
- $existing = bp_activity_get( array(
2056
- 'filter' => array(
2057
- 'action' => $activity_post_object->action_id,
2058
- 'primary_id' => $blog_id,
2059
- 'secondary_id' => $post_id,
2060
- )
2061
- ) );
2062
-
2063
- if ( ! empty( $existing['activities'] ) ) {
2064
- return;
2065
- }
2066
-
2067
- /**
2068
- * Filters whether or not to post the activity.
2069
- *
2070
- * This is a variable filter, dependent on the post type,
2071
- * that lets components or plugins bail early if needed.
2072
- *
2073
- * @since 2.2.0
2074
- *
2075
- * @param bool $value Whether or not to continue.
2076
- * @param int $blog_id ID of the current site.
2077
- * @param int $post_id ID of the current post being published.
2078
- * @param int $user_id ID of the current user or post author.
2079
- */
2080
- if ( false === apply_filters( "bp_activity_{$post->post_type}_pre_publish", true, $blog_id, $post_id, $user_id ) ) {
2081
- return;
2082
- }
2083
-
2084
- // Record this in activity streams.
2085
- $blog_url = get_home_url( $blog_id );
2086
- $post_url = add_query_arg(
2087
- 'p',
2088
- $post_id,
2089
- trailingslashit( $blog_url )
2090
- );
2091
-
2092
- // Backward compatibility filters for the 'blogs' component.
2093
- if ( 'blogs' == $activity_post_object->component_id ) {
2094
- $activity_content = apply_filters( 'bp_blogs_activity_new_post_content', $post->post_content, $post, $post_url, $post->post_type );
2095
- $activity_primary_link = apply_filters( 'bp_blogs_activity_new_post_primary_link', $post_url, $post_id, $post->post_type );
2096
- } else {
2097
- $activity_content = $post->post_content;
2098
- $activity_primary_link = $post_url;
2099
- }
2100
-
2101
- $activity_args = array(
2102
- 'user_id' => $user_id,
2103
- 'content' => $activity_content,
2104
- 'primary_link' => $activity_primary_link,
2105
- 'component' => $activity_post_object->component_id,
2106
- 'type' => $activity_post_object->action_id,
2107
- 'item_id' => $blog_id,
2108
- 'secondary_item_id' => $post_id,
2109
- 'recorded_time' => $post->post_date_gmt,
2110
- );
2111
-
2112
- if ( ! empty( $activity_args['content'] ) ) {
2113
- // Create the excerpt.
2114
- $activity_summary = bp_activity_create_summary( $activity_args['content'], $activity_args );
2115
-
2116
- // Backward compatibility filter for blog posts.
2117
- if ( 'blogs' == $activity_post_object->component_id ) {
2118
- $activity_args['content'] = apply_filters( 'bp_blogs_record_activity_content', $activity_summary, $activity_args['content'], $activity_args, $post->post_type );
2119
- } else {
2120
- $activity_args['content'] = $activity_summary;
2121
- }
2122
- }
2123
-
2124
- // Set up the action by using the format functions.
2125
- $action_args = array_merge( $activity_args, array(
2126
- 'post_title' => $post->post_title,
2127
- 'post_url' => $post_url,
2128
- ) );
2129
-
2130
- $activity_args['action'] = call_user_func_array( $activity_post_object->format_callback, array( '', (object) $action_args ) );
2131
-
2132
- // Make sure the action is set.
2133
- if ( empty( $activity_args['action'] ) ) {
2134
- return;
2135
- } else {
2136
- // Backward compatibility filter for the blogs component.
2137
- if ( 'blogs' == $activity_post_object->component_id ) {
2138
- $activity_args['action'] = apply_filters( 'bp_blogs_record_activity_action', $activity_args['action'] );
2139
- }
2140
- }
2141
-
2142
- $activity_id = bp_activity_add( $activity_args );
2143
-
2144
- /**
2145
- * Fires after the publishing of an activity item for a newly published post type post.
2146
- *
2147
- * @since 2.2.0
2148
- *
2149
- * @param int $activity_id ID of the newly published activity item.
2150
- * @param WP_Post $post Post object.
2151
- * @param array $activity_args Array of activity arguments.
2152
- */
2153
- do_action( 'bp_activity_post_type_published', $activity_id, $post, $activity_args );
2154
-
2155
- return $activity_id;
2156
- }
2157
-
2158
- /**
2159
- * Update the activity item for a custom post type entry.
2160
- *
2161
- * @since 2.2.0
2162
- *
2163
- * @param WP_Post|null $post Post item.
2164
- * @return null|WP_Error|bool True on success, false on failure.
2165
- */
2166
- function bp_activity_post_type_update( $post = null ) {
2167
-
2168
- if ( ! is_a( $post, 'WP_Post' ) ) {
2169
- return;
2170
- }
2171
-
2172
- // Get the post type tracking args.
2173
- $activity_post_object = bp_activity_get_post_type_tracking_args( $post->post_type );
2174
-
2175
- if ( empty( $activity_post_object->action_id ) ) {
2176
- return;
2177
- }
2178
-
2179
- $activity_id = bp_activity_get_activity_id( array(
2180
- 'component' => $activity_post_object->component_id,
2181
- 'item_id' => get_current_blog_id(),
2182
- 'secondary_item_id' => $post->ID,
2183
- 'type' => $activity_post_object->action_id,
2184
- ) );
2185
-
2186
- // Activity ID doesn't exist, so stop!
2187
- if ( empty( $activity_id ) ) {
2188
- return;
2189
- }
2190
-
2191
- // Delete the activity if the post was updated with a password.
2192
- if ( ! empty( $post->post_password ) ) {
2193
- bp_activity_delete( array( 'id' => $activity_id ) );
2194
- }
2195
-
2196
- // Update the activity entry.
2197
- $activity = new BP_Activity_Activity( $activity_id );
2198
-
2199
- if ( ! empty( $post->post_content ) ) {
2200
- $activity_summary = bp_activity_create_summary( $post->post_content, (array) $activity );
2201
-
2202
- // Backward compatibility filter for the blogs component.
2203
- if ( 'blogs' == $activity_post_object->component_id ) {
2204
- $activity->content = apply_filters( 'bp_blogs_record_activity_content', $activity_summary, $post->post_content, (array) $activity, $post->post_type );
2205
- } else {
2206
- $activity->content = $activity_summary;
2207
- }
2208
- }
2209
-
2210
- // Save the updated activity.
2211
- $updated = $activity->save();
2212
-
2213
- /**
2214
- * Fires after the updating of an activity item for a custom post type entry.
2215
- *
2216
- * @since 2.2.0
2217
- * @since 2.5.0 Add the post type tracking args parameter
2218
- *
2219
- * @param WP_Post $post Post object.
2220
- * @param BP_Activity_Activity $activity Activity object.
2221
- * @param object $activity_post_object The post type tracking args object.
2222
- */
2223
- do_action( 'bp_activity_post_type_updated', $post, $activity, $activity_post_object );
2224
-
2225
- return $updated;
2226
- }
2227
-
2228
- /**
2229
- * Unpublish an activity for the custom post type.
2230
- *
2231
- * @since 2.2.0
2232
- *
2233
- * @param int $post_id ID of the post being unpublished.
2234
- * @param WP_Post|null $post Post object.
2235
- * @return bool True on success, false on failure.
2236
- */
2237
- function bp_activity_post_type_unpublish( $post_id = 0, $post = null ) {
2238
-
2239
- if ( ! is_a( $post, 'WP_Post' ) ) {
2240
- return;
2241
- }
2242
-
2243
- // Get the post type tracking args.
2244
- $activity_post_object = bp_activity_get_post_type_tracking_args( $post->post_type );
2245
-
2246
- if ( empty( $activity_post_object->action_id ) ) {
2247
- return;
2248
- }
2249
-
2250
- if ( empty( $post_id ) ) {
2251
- $post_id = $post->ID;
2252
- }
2253
-
2254
- $delete_activity_args = array(
2255
- 'item_id' => get_current_blog_id(),
2256
- 'secondary_item_id' => $post_id,
2257
- 'component' => $activity_post_object->component_id,
2258
- 'type' => $activity_post_object->action_id,
2259
- 'user_id' => false,
2260
- );
2261
-
2262
- $deleted = bp_activity_delete_by_item_id( $delete_activity_args );
2263
-
2264
- /**
2265
- * Fires after the unpublishing for the custom post type.
2266
- *
2267
- * @since 2.2.0
2268
- *
2269
- * @param array $delete_activity_args Array of arguments for activity deletion.
2270
- * @param WP_Post $post Post object.
2271
- * @param bool $activity Whether or not the activity was successfully deleted.
2272
- */
2273
- do_action( 'bp_activity_post_type_unpublished', $delete_activity_args, $post, $deleted );
2274
-
2275
- return $deleted;
2276
- }
2277
-
2278
- /**
2279
- * Create an activity item for a newly posted post type comment.
2280
- *
2281
- * @since 2.5.0
2282
- *
2283
- * @param int $comment_id ID of the comment.
2284
- * @param bool $is_approved Whether the comment is approved or not.
2285
- * @param object|null $activity_post_object The post type tracking args object.
2286
- * @return null|WP_Error|bool|int The ID of the activity on success. False on error.
2287
- */
2288
- function bp_activity_post_type_comment( $comment_id = 0, $is_approved = true, $activity_post_object = null ) {
2289
- // Get the users comment
2290
- $post_type_comment = get_comment( $comment_id );
2291
-
2292
- // Don't record activity if the comment hasn't been approved
2293
- if ( empty( $is_approved ) ) {
2294
- return false;
2295
- }
2296
-
2297
- // Don't record activity if no email address has been included
2298
- if ( empty( $post_type_comment->comment_author_email ) ) {
2299
- return false;
2300
- }
2301
-
2302
- // Don't record activity if the comment has already been marked as spam
2303
- if ( 'spam' === $is_approved ) {
2304
- return false;
2305
- }
2306
-
2307
- // Get the user by the comment author email.
2308
- $user = get_user_by( 'email', $post_type_comment->comment_author_email );
2309
-
2310
- // If user isn't registered, don't record activity
2311
- if ( empty( $user ) ) {
2312
- return false;
2313
- }
2314
-
2315
- // Get the user_id
2316
- $user_id = (int) $user->ID;
2317
-
2318
- // Get blog and post data
2319
- $blog_id = get_current_blog_id();
2320
-
2321
- // Get the post
2322
- $post_type_comment->post = get_post( $post_type_comment->comment_post_ID );
2323
-
2324
- if ( ! is_a( $post_type_comment->post, 'WP_Post' ) ) {
2325
- return false;
2326
- }
2327
-
2328
- /**
2329
- * Filters whether to publish activities about the comment regarding the post status
2330
- *
2331
- * @since 2.5.0
2332
- *
2333
- * @param bool true to bail, false otherwise.
2334
- */
2335
- $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 ) );
2336
-
2337
- // If this is a password protected post, or not a public post don't record the comment
2338
- if ( $is_post_status_not_allowed ) {
2339
- return false;
2340
- }
2341
-
2342
- // Set post type
2343
- $post_type = $post_type_comment->post->post_type;
2344
-
2345
- if ( empty( $activity_post_object ) ) {
2346
- // Get the post type tracking args.
2347
- $activity_post_object = bp_activity_get_post_type_tracking_args( $post_type );
2348
-
2349
- // Bail if the activity type does not exist
2350
- if ( empty( $activity_post_object->comments_tracking->action_id ) ) {
2351
- return false;
2352
- }
2353
- }
2354
-
2355
- // Set the $activity_comment_object
2356
- $activity_comment_object = $activity_post_object->comments_tracking;
2357
-
2358
- /**
2359
- * Filters whether or not to post the activity about the comment.
2360
- *
2361
- * This is a variable filter, dependent on the post type,
2362
- * that lets components or plugins bail early if needed.
2363
- *
2364
- * @since 2.5.0
2365
- *
2366
- * @param bool $value Whether or not to continue.
2367
- * @param int $blog_id ID of the current site.
2368
- * @param int $post_id ID of the current post being commented.
2369
- * @param int $user_id ID of the current user.
2370
- * @param int $comment_id ID of the current comment being posted.
2371
- */
2372
- if ( false === apply_filters( "bp_activity_{$post_type}_pre_comment", true, $blog_id, $post_type_comment->post->ID, $user_id, $comment_id ) ) {
2373
- return false;
2374
- }
2375
-
2376
- // Is this an update ?
2377
- $activity_id = bp_activity_get_activity_id( array(
2378
- 'user_id' => $user_id,
2379
- 'component' => $activity_comment_object->component_id,
2380
- 'type' => $activity_comment_object->action_id,
2381
- 'item_id' => $blog_id,
2382
- 'secondary_item_id' => $comment_id,
2383
- ) );
2384
-
2385
- // Record this in activity streams.
2386
- $comment_link = get_comment_link( $post_type_comment->comment_ID );
2387
-
2388
- // Backward compatibility filters for the 'blogs' component.
2389
- if ( 'blogs' == $activity_comment_object->component_id ) {
2390
- $activity_content = apply_filters_ref_array( 'bp_blogs_activity_new_comment_content', array( $post_type_comment->comment_content, &$post_type_comment, $comment_link ) );
2391
- $activity_primary_link = apply_filters_ref_array( 'bp_blogs_activity_new_comment_primary_link', array( $comment_link, &$post_type_comment ) );
2392
- } else {
2393
- $activity_content = $post_type_comment->comment_content;
2394
- $activity_primary_link = $comment_link;
2395
- }
2396
-
2397
- $activity_args = array(
2398
- 'id' => $activity_id,
2399
- 'user_id' => $user_id,
2400
- 'content' => $activity_content,
2401
- 'primary_link' => $activity_primary_link,
2402
- 'component' => $activity_comment_object->component_id,
2403
- 'recorded_time' => $post_type_comment->comment_date_gmt,
2404
- );
2405
-
2406
- if ( bp_disable_blogforum_comments() ) {
2407
- $blog_url = get_home_url( $blog_id );
2408
- $post_url = add_query_arg(
2409
- 'p',
2410
- $post_type_comment->post->ID,
2411
- trailingslashit( $blog_url )
2412
- );
2413
-
2414
- $activity_args['type'] = $activity_comment_object->action_id;
2415
- $activity_args['item_id'] = $blog_id;
2416
- $activity_args['secondary_item_id'] = $post_type_comment->comment_ID;
2417
-
2418
- if ( ! empty( $activity_args['content'] ) ) {
2419
- // Create the excerpt.
2420
- $activity_summary = bp_activity_create_summary( $activity_args['content'], $activity_args );
2421
-
2422
- // Backward compatibility filter for blog comments.
2423
- if ( 'blogs' == $activity_post_object->component_id ) {
2424
- $activity_args['content'] = apply_filters( 'bp_blogs_record_activity_content', $activity_summary, $activity_args['content'], $activity_args, $post_type );
2425
- } else {
2426
- $activity_args['content'] = $activity_summary;
2427
- }
2428
- }
2429
-
2430
- // Set up the action by using the format functions.
2431
- $action_args = array_merge( $activity_args, array(
2432
- 'post_title' => $post_type_comment->post->post_title,
2433
- 'post_url' => $post_url,
2434
- 'blog_url' => $blog_url,
2435
- 'blog_name' => get_blog_option( $blog_id, 'blogname' ),
2436
- ) );
2437
-
2438
- $activity_args['action'] = call_user_func_array( $activity_comment_object->format_callback, array( '', (object) $action_args ) );
2439
-
2440
- // Make sure the action is set.
2441
- if ( empty( $activity_args['action'] ) ) {
2442
- return;
2443
- } else {
2444
- // Backward compatibility filter for the blogs component.
2445
- if ( 'blogs' === $activity_post_object->component_id ) {
2446
- $activity_args['action'] = apply_filters( 'bp_blogs_record_activity_action', $activity_args['action'] );
2447
- }
2448
- }
2449
-
2450
- $activity_id = bp_activity_add( $activity_args );
2451
- }
2452
-
2453
- /**
2454
- * Fires after the publishing of an activity item for a newly published post type post.
2455
- *
2456
- * @since 2.5.0
2457
- *
2458
- * @param int $activity_id ID of the newly published activity item.
2459
- * @param WP_Comment $post_type_comment Comment object.
2460
- * @param array $activity_args Array of activity arguments.
2461
- * @param object $activity_post_object the post type tracking args object.
2462
- */
2463
- do_action_ref_array( 'bp_activity_post_type_comment', array( &$activity_id, $post_type_comment, $activity_args, $activity_post_object ) );
2464
-
2465
- return $activity_id;
2466
- }
2467
- add_action( 'comment_post', 'bp_activity_post_type_comment', 10, 2 );
2468
- add_action( 'edit_comment', 'bp_activity_post_type_comment', 10 );
2469
-
2470
- /**
2471
- * Remove an activity item when a comment about a post type is deleted.
2472
- *
2473
- * @since 2.5.0
2474
- *
2475
- * @param int $comment_id ID of the comment.
2476
- * @param object|null $activity_post_object The post type tracking args object.
2477
- * @return bool True on success. False on error.
2478
- */
2479
- function bp_activity_post_type_remove_comment( $comment_id = 0, $activity_post_object = null ) {
2480
- if ( empty( $activity_post_object ) ) {
2481
- $comment = get_comment( $comment_id );
2482
- if ( ! $comment ) {
2483
- return;
2484
- }
2485
-
2486
- $post_type = get_post_type( $comment->comment_post_ID );
2487
- if ( ! $post_type ) {
2488
- return;
2489
- }
2490
-
2491
- // Get the post type tracking args.
2492
- $activity_post_object = bp_activity_get_post_type_tracking_args( $post_type );
2493
-
2494
- // Bail if the activity type does not exist
2495
- if ( empty( $activity_post_object->comments_tracking->action_id ) ) {
2496
- return false;
2497
- }
2498
- }
2499
-
2500
- // Set the $activity_comment_object
2501
- $activity_comment_object = $activity_post_object->comments_tracking;
2502
-
2503
- if ( empty( $activity_comment_object->action_id ) ) {
2504
- return false;
2505
- }
2506
-
2507
- $deleted = false;
2508
-
2509
- if ( bp_disable_blogforum_comments() ) {
2510
- $deleted = bp_activity_delete_by_item_id( array(
2511
- 'item_id' => get_current_blog_id(),
2512
- 'secondary_item_id' => $comment_id,
2513
- 'component' => $activity_comment_object->component_id,
2514
- 'type' => $activity_comment_object->action_id,
2515
- 'user_id' => false,
2516
- ) );
2517
- }
2518
-
2519
- /**
2520
- * Fires after the custom post type comment activity was removed.
2521
- *
2522
- * @since 2.5.0
2523
- *
2524
- * @param bool $deleted True if the activity was deleted false otherwise
2525
- * @param WP_Comment $comment Comment object.
2526
- * @param object $activity_post_object The post type tracking args object.
2527
- * @param string $value The post type comment activity type.
2528
- */
2529
- do_action( 'bp_activity_post_type_remove_comment', $deleted, $comment_id, $activity_post_object, $activity_comment_object->action_id );
2530
-
2531
- return $deleted;
2532
- }
2533
- add_action( 'delete_comment', 'bp_activity_post_type_remove_comment', 10, 1 );
2534
-
2535
- /**
2536
- * Add an activity comment.
2537
- *
2538
- * @since 1.2.0
2539
- * @since 2.5.0 Add a new possible parameter $skip_notification for the array of arguments.
2540
- * Add the $primary_link parameter for the array of arguments.
2541
- * @since 2.6.0 Added 'error_type' parameter to $args.
2542
- *
2543
- * @param array|string $args {
2544
- * An array of arguments.
2545
- * @type int $id Optional. Pass an ID to update an existing comment.
2546
- * @type string $content The content of the comment.
2547
- * @type int $user_id Optional. The ID of the user making the comment.
2548
- * Defaults to the ID of the logged-in user.
2549
- * @type int $activity_id The ID of the "root" activity item, ie the oldest
2550
- * ancestor of the comment.
2551
- * @type int $parent_id Optional. The ID of the parent activity item, ie the item to
2552
- * which the comment is an immediate reply. If not provided,
2553
- * this value defaults to the $activity_id.
2554
- * @type string $primary_link Optional. the primary link for the comment.
2555
- * Defaults to an empty string.
2556
- * @type bool $skip_notification Optional. false to send a comment notification, false otherwise.
2557
- * Defaults to false.
2558
- * @type string $error_type Optional. Error type. Either 'bool' or 'wp_error'. Default: 'bool'.
2559
- * }
2560
- * @return WP_Error|bool|int The ID of the comment on success, otherwise false.
2561
- */
2562
- function bp_activity_new_comment( $args = '' ) {
2563
- $bp = buddypress();
2564
-
2565
- $r = wp_parse_args( $args, array(
2566
- 'id' => false,
2567
- 'content' => false,
2568
- 'user_id' => bp_loggedin_user_id(),
2569
- 'activity_id' => false, // ID of the root activity item.
2570
- 'parent_id' => false, // ID of a parent comment (optional).
2571
- 'primary_link' => '',
2572
- 'skip_notification' => false,
2573
- 'error_type' => 'bool'
2574
- ) );
2575
-
2576
- // Error type is boolean; need to initialize some variables for backpat.
2577
- if ( 'bool' === $r['error_type'] ) {
2578
- if ( empty( $bp->activity->errors ) ) {
2579
- $bp->activity->errors = array();
2580
- }
2581
- }
2582
-
2583
- // Default error message.
2584
- $feedback = __( 'There was an error posting your reply. Please try again.', 'buddypress' );
2585
-
2586
- // Bail if missing necessary data.
2587
- if ( empty( $r['content'] ) || empty( $r['user_id'] ) || empty( $r['activity_id'] ) ) {
2588
- $error = new WP_Error( 'missing_data', $feedback );
2589
-
2590
- if ( 'wp_error' === $r['error_type'] ) {
2591
- return $error;
2592
-
2593
- // Backpat.
2594
- } else {
2595
- $bp->activity->errors['new_comment'] = $error;
2596
- return false;
2597
- }
2598
- }
2599
-
2600
- // Maybe set current activity ID as the parent.
2601
- if ( empty( $r['parent_id'] ) ) {
2602
- $r['parent_id'] = $r['activity_id'];
2603
- }
2604
-
2605
- $activity_id = $r['activity_id'];
2606
-
2607
- // Get the parent activity.
2608
- $activity = new BP_Activity_Activity( $activity_id );
2609
-
2610
- // Bail if the parent activity does not exist.
2611
- if ( empty( $activity->date_recorded ) ) {
2612
- $error = new WP_Error( 'missing_activity', __( 'The item you were replying to no longer exists.', 'buddypress' ) );
2613
-
2614
- if ( 'wp_error' === $r['error_type'] ) {
2615
- return $error;
2616
-
2617
- // Backpat.
2618
- } else {
2619
- $bp->activity->errors['new_comment'] = $error;
2620
- return false;
2621
- }
2622
-
2623
- }
2624
-
2625
- // Check to see if the parent activity is hidden, and if so, hide this comment publicly.
2626
- $is_hidden = $activity->hide_sitewide ? 1 : 0;
2627
-
2628
- /**
2629
- * Filters the content of a new comment.
2630
- *
2631
- * @since 1.2.0
2632
- *
2633
- * @param string $r Content for the newly posted comment.
2634
- */
2635
- $comment_content = apply_filters( 'bp_activity_comment_content', $r['content'] );
2636
-
2637
- // Insert the activity comment.
2638
- $comment_id = bp_activity_add( array(
2639
- 'id' => $r['id'],
2640
- 'content' => $comment_content,
2641
- 'component' => buddypress()->activity->id,
2642
- 'type' => 'activity_comment',
2643
- 'primary_link' => $r['primary_link'],
2644
- 'user_id' => $r['user_id'],
2645
- 'item_id' => $activity_id,
2646
- 'secondary_item_id' => $r['parent_id'],
2647
- 'hide_sitewide' => $is_hidden,
2648
- 'error_type' => $r['error_type']
2649
- ) );
2650
-
2651
- // Bail on failure.
2652
- if ( false === $comment_id || is_wp_error( $comment_id ) ) {
2653
- return $comment_id;
2654
- }
2655
-
2656
- // Comment caches are stored only with the top-level item.
2657
- wp_cache_delete( $activity_id, 'bp_activity_comments' );
2658
-
2659
- // Walk the tree to clear caches for all parent items.
2660
- $clear_id = $r['parent_id'];
2661
- while ( $clear_id != $activity_id ) {
2662
- $clear_object = new BP_Activity_Activity( $clear_id );
2663
- wp_cache_delete( $clear_id, 'bp_activity' );
2664
- $clear_id = intval( $clear_object->secondary_item_id );
2665
- }
2666
- wp_cache_delete( $activity_id, 'bp_activity' );
2667
-
2668
- if ( empty( $r[ 'skip_notification' ] ) ) {
2669
- /**
2670
- * Fires near the end of an activity comment posting, before the returning of the comment ID.
2671
- * Sends a notification to the user @see bp_activity_new_comment_notification_helper().
2672
- *
2673
- * @since 1.2.0
2674
- *
2675
- * @param int $comment_id ID of the newly posted activity comment.
2676
- * @param array $r Array of parsed comment arguments.
2677
- * @param BP_Activity_Activity $activity Activity item being commented on.
2678
- */
2679
- do_action( 'bp_activity_comment_posted', $comment_id, $r, $activity );
2680
- } else {
2681
- /**
2682
- * Fires near the end of an activity comment posting, before the returning of the comment ID.
2683
- * without sending a notification to the user
2684
- *
2685
- * @since 2.5.0
2686
- *
2687
- * @param int $comment_id ID of the newly posted activity comment.
2688
- * @param array $r Array of parsed comment arguments.
2689
- * @param BP_Activity_Activity $activity Activity item being commented on.
2690
- */
2691
- do_action( 'bp_activity_comment_posted_notification_skipped', $comment_id, $r, $activity );
2692
- }
2693
-
2694
- if ( empty( $comment_id ) ) {
2695
- $error = new WP_Error( 'comment_failed', $feedback );
2696
-
2697
- if ( 'wp_error' === $r['error_type'] ) {
2698
- return $error;
2699
-
2700
- // Backpat.
2701
- } else {
2702
- $bp->activity->errors['new_comment'] = $error;
2703
- }
2704
- }
2705
-
2706
- return $comment_id;
2707
- }
2708
-
2709
- /**
2710
- * Fetch the activity_id for an existing activity entry in the DB.
2711
- *
2712
- * @since 1.2.0
2713
- *
2714
- * @see BP_Activity_Activity::get() For more information on accepted arguments.
2715
- *
2716
- * @param array|string $args See BP_Activity_Activity::get() for description.
2717
- * @return int $activity_id The ID of the activity item found.
2718
- */
2719
- function bp_activity_get_activity_id( $args = '' ) {
2720
-
2721
- $r = bp_parse_args( $args, array(
2722
- 'user_id' => false,
2723
- 'component' => false,
2724
- 'type' => false,
2725
- 'item_id' => false,
2726
- 'secondary_item_id' => false,
2727
- 'action' => false,
2728
- 'content' => false,
2729
- 'date_recorded' => false,
2730
- ) );
2731
-
2732
- /**
2733
- * Filters the activity ID being requested.
2734
- *
2735
- * @since 1.2.0
2736
- * @since 2.5.0 Added the `$r` and `$args` parameters.
2737
- *
2738
- * @param BP_Activity_Activity $value ID returned by BP_Activity_Activity get_id() method with provided arguments.
2739
- * @param array $r Parsed function arguments.
2740
- * @param array $args Arguments passed to the function.
2741
- */
2742
- return apply_filters( 'bp_activity_get_activity_id', BP_Activity_Activity::get_id(
2743
- $r['user_id'],
2744
- $r['component'],
2745
- $r['type'],
2746
- $r['item_id'],
2747
- $r['secondary_item_id'],
2748
- $r['action'],
2749
- $r['content'],
2750
- $r['date_recorded']
2751
- ), $r, $args );
2752
- }
2753
-
2754
- /**
2755
- * Delete activity item(s).
2756
- *
2757
- * If you're looking to hook into one action that provides the ID(s) of
2758
- * the activity/activities deleted, then use:
2759
- *
2760
- * add_action( 'bp_activity_deleted_activities', 'my_function' );
2761
- *
2762
- * The action passes one parameter that is a single activity ID or an
2763
- * array of activity IDs depending on the number deleted.
2764
- *
2765
- * If you are deleting an activity comment please use bp_activity_delete_comment();
2766
- *
2767
- * @since 1.0.0
2768
- *
2769
- * @see BP_Activity_Activity::get() For more information on accepted arguments.
2770
- *
2771
- * @param array|string $args To delete specific activity items, use
2772
- * $args = array( 'id' => $ids ); Otherwise, to use
2773
- * filters for item deletion, the argument format is
2774
- * the same as BP_Activity_Activity::get().
2775
- * See that method for a description.
2776
- * @return bool True on success, false on failure.
2777
- */
2778
- function bp_activity_delete( $args = '' ) {
2779
-
2780
- // Pass one or more the of following variables to delete by those variables.
2781
- $args = bp_parse_args( $args, array(
2782
- 'id' => false,
2783
- 'action' => false,
2784
- 'content' => false,
2785
- 'component' => false,
2786
- 'type' => false,
2787
- 'primary_link' => false,
2788
- 'user_id' => false,
2789
- 'item_id' => false,
2790
- 'secondary_item_id' => false,
2791
- 'date_recorded' => false,
2792
- 'hide_sitewide' => false
2793
- ) );
2794
-
2795
- /**
2796
- * Fires before an activity item proceeds to be deleted.
2797
- *
2798
- * @since 1.5.0
2799
- *
2800
- * @param array $args Array of arguments to be used with the activity deletion.
2801
- */
2802
- do_action( 'bp_before_activity_delete', $args );
2803
-
2804
- // Adjust the new mention count of any mentioned member.
2805
- bp_activity_adjust_mention_count( $args['id'], 'delete' );
2806
-
2807
- $activity_ids_deleted = BP_Activity_Activity::delete( $args );
2808
- if ( empty( $activity_ids_deleted ) ) {
2809
- return false;
2810
- }
2811
-
2812
- // Check if the user's latest update has been deleted.
2813
- $user_id = empty( $args['user_id'] )
2814
- ? bp_loggedin_user_id()
2815
- : $args['user_id'];
2816
-
2817
- $latest_update = bp_get_user_meta( $user_id, 'bp_latest_update', true );
2818
- if ( !empty( $latest_update ) ) {
2819
- if ( in_array( (int) $latest_update['id'], (array) $activity_ids_deleted ) ) {
2820
- bp_delete_user_meta( $user_id, 'bp_latest_update' );
2821
- }
2822
- }
2823
-
2824
- /**
2825
- * Fires after the activity item has been deleted.
2826
- *
2827
- * @since 1.0.0
2828
- *
2829
- * @param array $args Array of arguments used with the activity deletion.
2830
- */
2831
- do_action( 'bp_activity_delete', $args );
2832
-
2833
- /**
2834
- * Fires after the activity item has been deleted.
2835
- *
2836
- * @since 1.2.0
2837
- *
2838
- * @param array $activity_ids_deleted Array of affected activity item IDs.
2839
- */
2840
- do_action( 'bp_activity_deleted_activities', $activity_ids_deleted );
2841
-
2842
- wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
2843
-
2844
- return true;
2845
- }
2846
-
2847
- /**
2848
- * Delete an activity item by activity id.
2849
- *
2850
- * You should use bp_activity_delete() instead.
2851
- *
2852
- * @since 1.1.0
2853
- * @deprecated 1.2.0
2854
- *
2855
- *
2856
- * @param array|string $args See BP_Activity_Activity::get for a
2857
- * description of accepted arguments.
2858
- * @return bool True on success, false on failure.
2859
- */
2860
- function bp_activity_delete_by_item_id( $args = '' ) {
2861
-
2862
- $r = bp_parse_args( $args, array(
2863
- 'item_id' => false,
2864
- 'component' => false,
2865
- 'type' => false,
2866
- 'user_id' => false,
2867
- 'secondary_item_id' => false
2868
- ) );
2869
-
2870
- return bp_activity_delete( $r );
2871
- }
2872
-
2873
- /**
2874
- * Delete an activity item by activity id.
2875
- *
2876
- * @since 1.1.0
2877
- *
2878
- *
2879
- * @param int $activity_id ID of the activity item to be deleted.
2880
- * @return bool True on success, false on failure.
2881
- */
2882
- function bp_activity_delete_by_activity_id( $activity_id ) {
2883
- return bp_activity_delete( array( 'id' => $activity_id ) );
2884
- }
2885
-
2886
- /**
2887
- * Delete an activity item by its content.
2888
- *
2889
- * You should use bp_activity_delete() instead.
2890
- *
2891
- * @since 1.1.0
2892
- * @deprecated 1.2.0
2893
- *
2894
- *
2895
- * @param int $user_id The user id.
2896
- * @param string $content The activity id.
2897
- * @param string $component The activity component.
2898
- * @param string $type The activity type.
2899
- * @return bool True on success, false on failure.
2900
- */
2901
- function bp_activity_delete_by_content( $user_id, $content, $component, $type ) {
2902
- return bp_activity_delete( array(
2903
- 'user_id' => $user_id,
2904
- 'content' => $content,
2905
- 'component' => $component,
2906
- 'type' => $type
2907
- ) );
2908
- }
2909
-
2910
- /**
2911
- * Delete a user's activity for a component.
2912
- *
2913
- * You should use bp_activity_delete() instead.
2914
- *
2915
- * @since 1.1.0
2916
- * @deprecated 1.2.0
2917
- *
2918
- *
2919
- * @param int $user_id The user id.
2920
- * @param string $component The activity component.
2921
- * @return bool True on success, false on failure.
2922
- */
2923
- function bp_activity_delete_for_user_by_component( $user_id, $component ) {
2924
- return bp_activity_delete( array(
2925
- 'user_id' => $user_id,
2926
- 'component' => $component
2927
- ) );
2928
- }
2929
-
2930
- /**
2931
- * Delete an activity comment.
2932
- *
2933
- * @since 1.2.0
2934
- *
2935
- * @todo Why is an activity id required? We could look this up.
2936
- * @todo Why do we encourage users to call this function directly? We could just
2937
- * as easily examine the activity type in bp_activity_delete() and then
2938
- * call this function with the proper arguments if necessary.
2939
- *
2940
- * @param int $activity_id The ID of the "root" activity, ie the comment's
2941
- * oldest ancestor.
2942
- * @param int $comment_id The ID of the comment to be deleted.
2943
- * @return bool True on success, false on failure.
2944
- */
2945
- function bp_activity_delete_comment( $activity_id, $comment_id ) {
2946
- $deleted = false;
2947
-
2948
- /**
2949
- * Filters whether BuddyPress should delete an activity comment or not.
2950
- *
2951
- * You may want to hook into this filter if you want to override this function and
2952
- * handle the deletion of child comments differently. Make sure you return false.
2953
- *
2954
- * @since 1.2.0
2955
- * @since 2.5.0 Add the deleted parameter (passed by reference)
2956
- *
2957
- * @param bool $value Whether BuddyPress should continue or not.
2958
- * @param int $activity_id ID of the root activity item being deleted.
2959
- * @param int $comment_id ID of the comment being deleted.
2960
- * @param bool $deleted Whether the activity comment has been deleted or not.
2961
- */
2962
- if ( ! apply_filters_ref_array( 'bp_activity_delete_comment_pre', array( true, $activity_id, $comment_id, &$deleted ) ) ) {
2963
- return $deleted;
2964
- }
2965
-
2966
- // Check if comment still exists.
2967
- $comment = new BP_Activity_Activity( $comment_id );
2968
- if ( empty( $comment->id ) ) {
2969
- return false;
2970
- }
2971
-
2972
- // Delete any children of this comment.
2973
- bp_activity_delete_children( $activity_id, $comment_id );
2974
-
2975
- // Delete the actual comment.
2976
- if ( ! bp_activity_delete( array( 'id' => $comment_id, 'type' => 'activity_comment' ) ) ) {
2977
- return false;
2978
- } else {
2979
- $deleted = true;
2980
- }
2981
-
2982
- // Purge comment cache for the root activity update.
2983
- wp_cache_delete( $activity_id, 'bp_activity_comments' );
2984
-
2985
- // Recalculate the comment tree.
2986
- BP_Activity_Activity::rebuild_activity_comment_tree( $activity_id );
2987
-
2988
- /**
2989
- * Fires at the end of the deletion of an activity comment, before returning success.
2990
- *
2991
- * @since 1.2.0
2992
- *
2993
- * @param int $activity_id ID of the activity that has had a comment deleted from.
2994
- * @param int $comment_id ID of the comment that was deleted.
2995
- */
2996
- do_action( 'bp_activity_delete_comment', $activity_id, $comment_id );
2997
-
2998
- return $deleted;
2999
- }
3000
-
3001
- /**
3002
- * Delete an activity comment's children.
3003
- *
3004
- * @since 1.2.0
3005
- *
3006
- *
3007
- * @param int $activity_id The ID of the "root" activity, ie the
3008
- * comment's oldest ancestor.
3009
- * @param int $comment_id The ID of the comment to be deleted.
3010
- */
3011
- function bp_activity_delete_children( $activity_id, $comment_id ) {
3012
- // Check if comment still exists.
3013
- $comment = new BP_Activity_Activity( $comment_id );
3014
- if ( empty( $comment->id ) ) {
3015
- return;
3016
- }
3017
-
3018
- // Get activity children to delete.
3019
- $children = BP_Activity_Activity::get_child_comments( $comment_id );
3020
-
3021
- // Recursively delete all children of this comment.
3022
- if ( ! empty( $children ) ) {
3023
- foreach( (array) $children as $child ) {
3024
- bp_activity_delete_children( $activity_id, $child->id );
3025
- }
3026
- }
3027
-
3028
- // Delete the comment itself.
3029
- bp_activity_delete( array(
3030
- 'secondary_item_id' => $comment_id,
3031
- 'type' => 'activity_comment',
3032
- 'item_id' => $activity_id
3033
- ) );
3034
- }
3035
-
3036
- /**
3037
- * Get the permalink for a single activity item.
3038
- *
3039
- * When only the $activity_id param is passed, BP has to instantiate a new
3040
- * BP_Activity_Activity object. To save yourself some processing overhead,
3041
- * be sure to pass the full $activity_obj parameter as well, if you already
3042
- * have it available.
3043
- *
3044
- * @since 1.2.0
3045
- *
3046
- * @param int $activity_id The unique id of the activity object.
3047
- * @param object|bool $activity_obj Optional. The activity object.
3048
- * @return string $link Permalink for the activity item.
3049
- */
3050
- function bp_activity_get_permalink( $activity_id, $activity_obj = false ) {
3051
- $bp = buddypress();
3052
-
3053
- if ( empty( $activity_obj ) ) {
3054
- $activity_obj = new BP_Activity_Activity( $activity_id );
3055
- }
3056
-
3057
- if ( isset( $activity_obj->current_comment ) ) {
3058
- $activity_obj = $activity_obj->current_comment;
3059
- }
3060
-
3061
- $use_primary_links = array(
3062
- 'new_blog_post',
3063
- 'new_blog_comment',
3064
- 'new_forum_topic',
3065
- 'new_forum_post',
3066
- );
3067
-
3068
- if ( ! empty( $bp->activity->track ) ) {
3069
- $use_primary_links = array_merge( $use_primary_links, array_keys( $bp->activity->track ) );
3070
- }
3071
-
3072
- if ( false !== array_search( $activity_obj->type, $use_primary_links ) ) {
3073
- $link = $activity_obj->primary_link;
3074
- } else {
3075
- if ( 'activity_comment' == $activity_obj->type ) {
3076
- $link = bp_get_root_domain() . '/' . bp_get_activity_root_slug() . '/p/' . $activity_obj->item_id . '/#acomment-' . $activity_obj->id;
3077
- } else {
3078
- $link = bp_get_root_domain() . '/' . bp_get_activity_root_slug() . '/p/' . $activity_obj->id . '/';
3079
- }
3080
- }
3081
-
3082
- /**
3083
- * Filters the activity permalink for the specified activity item.
3084
- *
3085
- * @since 1.2.0
3086
- *
3087
- * @param array $array Array holding activity permalink and activity item object.
3088
- */
3089
- return apply_filters_ref_array( 'bp_activity_get_permalink', array( $link, &$activity_obj ) );
3090
- }
3091
-
3092
- /**
3093
- * Hide a user's activity.
3094
- *
3095
- * @since 1.2.0
3096
- *
3097
- * @param int $user_id The ID of the user whose activity is being hidden.
3098
- * @return bool True on success, false on failure.
3099
- */
3100
- function bp_activity_hide_user_activity( $user_id ) {
3101
- return BP_Activity_Activity::hide_all_for_user( $user_id );
3102
- }
3103
-
3104
- /**
3105
- * Take content, remove images, and replace them with a single thumbnail image.
3106
- *
3107
- * The format of items in the activity stream is such that we do not want to
3108
- * allow an arbitrary number of arbitrarily large images to be rendered.
3109
- * However, the activity stream is built to elegantly display a single
3110
- * thumbnail corresponding to the activity comment. This function looks
3111
- * through the content, grabs the first image and converts it to a thumbnail,
3112
- * and removes the rest of the images from the string.
3113
- *
3114
- * As of BuddyPress 2.3, this function is no longer in use.
3115
- *
3116
- * @since 1.2.0
3117
- *
3118
- * @param string $content The content of the activity item.
3119
- * @param string|bool $link Optional. The unescaped URL that the image should link
3120
- * to. If absent, the image will not be a link.
3121
- * @param array|bool $args Optional. The args passed to the activity
3122
- * creation function (eg bp_blogs_record_activity()).
3123
- * @return string $content The content with images stripped and replaced with a
3124
- * single thumb.
3125
- */
3126
- function bp_activity_thumbnail_content_images( $content, $link = false, $args = false ) {
3127
-
3128
- preg_match_all( '/<img[^>]*>/Ui', $content, $matches );
3129
-
3130
- // Remove <img> tags. Also remove caption shortcodes and caption text if present.
3131
- $content = preg_replace('|(\[caption(.*?)\])?<img[^>]*>([^\[\[]*\[\/caption\])?|', '', $content );
3132
-
3133
- if ( !empty( $matches ) && !empty( $matches[0] ) ) {
3134
-
3135
- // Get the SRC value.
3136
- preg_match( '/<img.*?(src\=[\'|"]{0,1}.*?[\'|"]{0,1})[\s|>]{1}/i', $matches[0][0], $src );
3137
-
3138
- // Get the width and height.
3139
- preg_match( '/<img.*?(height\=[\'|"]{0,1}.*?[\'|"]{0,1})[\s|>]{1}/i', $matches[0][0], $height );
3140
- preg_match( '/<img.*?(width\=[\'|"]{0,1}.*?[\'|"]{0,1})[\s|>]{1}/i', $matches[0][0], $width );
3141
-
3142
- if ( ! empty( $src ) ) {
3143
- $src = substr( substr( str_replace( 'src=', '', $src[1] ), 0, -1 ), 1 );
3144
-
3145
- if ( isset( $width[1] ) ) {
3146
- $width = substr( substr( str_replace( 'width=', '', $width[1] ), 0, -1 ), 1 );
3147
- }
3148
-
3149
- if ( isset( $height[1] ) ) {
3150
- $height = substr( substr( str_replace( 'height=', '', $height[1] ), 0, -1 ), 1 );
3151
- }
3152
-
3153
- if ( empty( $width ) || empty( $height ) ) {
3154
- $width = 100;
3155
- $height = 100;
3156
- }
3157
-
3158
- $ratio = (int) $width / (int) $height;
3159
- $new_height = (int) $height >= 100 ? 100 : $height;
3160
- $new_width = $new_height * $ratio;
3161
- $image = '<img src="' . esc_url( $src ) . '" width="' . absint( $new_width ) . '" height="' . absint( $new_height ) . '" alt="' . __( 'Thumbnail', 'buddypress' ) . '" class="align-left thumbnail" />';
3162
-
3163
- if ( !empty( $link ) ) {
3164
- $image = '<a href="' . esc_url( $link ) . '">' . $image . '</a>';
3165
- }
3166
-
3167
- $content = $image . $content;
3168
- }
3169
- }
3170
-
3171
- /**
3172
- * Filters the activity content that had a thumbnail replace images.
3173
- *
3174
- * @since 1.2.0
3175
- *
3176
- * @param string $content Activity content that had images replaced in.
3177
- * @param array $matches Array of all image tags found in the posted content.
3178
- * @param array $args Arguments passed into function creating the activity update.
3179
- */
3180
- return apply_filters( 'bp_activity_thumbnail_content_images', $content, $matches, $args );
3181
- }
3182
-
3183
- /**
3184
- * Gets the excerpt length for activity items.
3185
- *
3186
- * @since 2.8.0
3187
- *
3188
- * @return int Character length for activity excerpts.
3189
- */
3190
- function bp_activity_get_excerpt_length() {
3191
- /**
3192
- * Filters the excerpt length for the activity excerpt.
3193
- *
3194
- * @since 1.5.0
3195
- *
3196
- * @param int Character length for activity excerpts.
3197
- */
3198
- return (int) apply_filters( 'bp_activity_excerpt_length', 358 );
3199
- }
3200
-
3201
- /**
3202
- * Create a rich summary of an activity item for the activity stream.
3203
- *
3204
- * More than just a simple excerpt, the summary could contain oEmbeds and other types of media.
3205
- * Currently, it's only used for blog post items, but it will probably be used for all types of
3206
- * activity in the future.
3207
- *
3208
- * @since 2.3.0
3209
- *
3210
- * @param string $content The content of the activity item.
3211
- * @param array $activity The data passed to bp_activity_add() or the values
3212
- * from an Activity obj.
3213
- * @return string $summary
3214
- */
3215
- function bp_activity_create_summary( $content, $activity ) {
3216
- $args = array(
3217
- 'width' => isset( $GLOBALS['content_width'] ) ? (int) $GLOBALS['content_width'] : 'medium',
3218
- );
3219
-
3220
- // Get the WP_Post object if this activity type is a blog post.
3221
- if ( $activity['type'] === 'new_blog_post' ) {
3222
- $content = get_post( $activity['secondary_item_id'] );
3223
- }
3224
-
3225
- /**
3226
- * Filter the class name of the media extractor when creating an Activity summary.
3227
- *
3228
- * Use this filter to change the media extractor used to extract media info for the activity item.
3229
- *
3230
- * @since 2.3.0
3231
- *
3232
- * @param string $extractor Class name.
3233
- * @param string $content The content of the activity item.
3234
- * @param array $activity The data passed to bp_activity_add() or the values from an Activity obj.
3235
- */
3236
- $extractor = apply_filters( 'bp_activity_create_summary_extractor_class', 'BP_Media_Extractor', $content, $activity );
3237
- $extractor = new $extractor;
3238
-
3239
- /**
3240
- * Filter the arguments passed to the media extractor when creating an Activity summary.
3241
- *
3242
- * @since 2.3.0
3243
- *
3244
- * @param array $args Array of bespoke data for the media extractor.
3245
- * @param string $content The content of the activity item.
3246
- * @param array $activity The data passed to bp_activity_add() or the values from an Activity obj.
3247
- * @param BP_Media_Extractor $extractor The media extractor object.
3248
- */
3249
- $args = apply_filters( 'bp_activity_create_summary_extractor_args', $args, $content, $activity, $extractor );
3250
-
3251
-
3252
- // Extract media information from the $content.
3253
- $media = $extractor->extract( $content, BP_Media_Extractor::ALL, $args );
3254
-
3255
- // If we converted $content to an object earlier, flip it back to a string.
3256
- if ( is_a( $content, 'WP_Post' ) ) {
3257
- $content = $content->post_content;
3258
- }
3259
-
3260
- $para_count = substr_count( strtolower( wpautop( $content ) ), '<p>' );
3261
- $has_audio = ! empty( $media['has']['audio'] ) && $media['has']['audio'];
3262
- $has_videos = ! empty( $media['has']['videos'] ) && $media['has']['videos'];
3263
- $has_feat_image = ! empty( $media['has']['featured_images'] ) && $media['has']['featured_images'];
3264
- $has_galleries = ! empty( $media['has']['galleries'] ) && $media['has']['galleries'];
3265
- $has_images = ! empty( $media['has']['images'] ) && $media['has']['images'];
3266
- $has_embeds = false;
3267
-
3268
- // Embeds must be subtracted from the paragraph count.
3269
- if ( ! empty( $media['has']['embeds'] ) ) {
3270
- $has_embeds = $media['has']['embeds'] > 0;
3271
- $para_count -= count( $media['has']['embeds'] );
3272
- }
3273
-
3274
- $extracted_media = array();
3275
- $use_media_type = '';
3276
- $image_source = '';
3277
-
3278
- // If it's a short article and there's an embed/audio/video, use it.
3279
- if ( $para_count <= 3 ) {
3280
- if ( $has_embeds ) {
3281
- $use_media_type = 'embeds';
3282
- } elseif ( $has_audio ) {
3283
- $use_media_type = 'audio';
3284
- } elseif ( $has_videos ) {
3285
- $use_media_type = 'videos';
3286
- }
3287
- }
3288
-
3289
- // If not, or in any other situation, try to use an image.
3290
- if ( ! $use_media_type && $has_images ) {
3291
- $use_media_type = 'images';
3292
- $image_source = 'html';
3293
-
3294
- // Featured Image > Galleries > inline <img>.
3295
- if ( $has_feat_image ) {
3296
- $image_source = 'featured_images';
3297
-
3298
- } elseif ( $has_galleries ) {
3299
- $image_source = 'galleries';
3300
- }
3301
- }
3302
-
3303
- // Extract an item from the $media results.
3304
- if ( $use_media_type ) {
3305
- if ( $use_media_type === 'images' ) {
3306
- $extracted_media = wp_list_filter( $media[ $use_media_type ], array( 'source' => $image_source ) );
3307
- $extracted_media = array_shift( $extracted_media );
3308
- } else {
3309
- $extracted_media = array_shift( $media[ $use_media_type ] );
3310
- }
3311
-
3312
- /**
3313
- * Filter the results of the media extractor when creating an Activity summary.
3314
- *
3315
- * @since 2.3.0
3316
- *
3317
- * @param array $extracted_media Extracted media item. See {@link BP_Media_Extractor::extract()} for format.
3318
- * @param string $content Content of the activity item.
3319
- * @param array $activity The data passed to bp_activity_add() or the values from an Activity obj.
3320
- * @param array $media All results from the media extraction.
3321
- * See {@link BP_Media_Extractor::extract()} for format.
3322
- * @param string $use_media_type The kind of media item that was preferentially extracted.
3323
- * @param string $image_source If $use_media_type was "images", the preferential source of the image.
3324
- * Otherwise empty.
3325
- */
3326
- $extracted_media = apply_filters(
3327
- 'bp_activity_create_summary_extractor_result',
3328
- $extracted_media,
3329
- $content,
3330
- $activity,
3331
- $media,
3332
- $use_media_type,
3333
- $image_source
3334
- );
3335
- }
3336
-
3337
- // Generate a text excerpt for this activity item (and remove any oEmbeds URLs).
3338
- $summary = bp_create_excerpt( html_entity_decode( $content ), 225, array(
3339
- 'html' => false,
3340
- 'filter_shortcodes' => true,
3341
- 'strip_tags' => true,
3342
- 'remove_links' => true
3343
- ) );
3344
-
3345
- if ( $use_media_type === 'embeds' ) {
3346
- $summary .= PHP_EOL . PHP_EOL . $extracted_media['url'];
3347
- } elseif ( $use_media_type === 'images' ) {
3348
- $summary .= sprintf( ' <img src="%s">', esc_url( $extracted_media['url'] ) );
3349
- } elseif ( in_array( $use_media_type, array( 'audio', 'videos' ), true ) ) {
3350
- $summary .= PHP_EOL . PHP_EOL . $extracted_media['original']; // Full shortcode.
3351
- }
3352
-
3353
- /**
3354
- * Filters the newly-generated summary for the activity item.
3355
- *
3356
- * @since 2.3.0
3357
- *
3358
- * @param string $summary Activity summary HTML.
3359
- * @param string $content Content of the activity item.
3360
- * @param array $activity The data passed to bp_activity_add() or the values from an Activity obj.
3361
- * @param array $extracted_media Media item extracted. See {@link BP_Media_Extractor::extract()} for format.
3362
- */
3363
- return apply_filters( 'bp_activity_create_summary', $summary, $content, $activity, $extracted_media );
3364
- }
3365
-
3366
- /**
3367
- * Fetch whether the current user is allowed to mark items as spam.
3368
- *
3369
- * @since 1.6.0
3370
- *
3371
- * @return bool True if user is allowed to mark activity items as spam.
3372
- */
3373
- function bp_activity_user_can_mark_spam() {
3374
-
3375
- /**
3376
- * Filters whether the current user should be able to mark items as spam.
3377
- *
3378
- * @since 1.6.0
3379
- *
3380
- * @param bool $moderate Whether or not the current user has bp_moderate capability.
3381
- */
3382
- return apply_filters( 'bp_activity_user_can_mark_spam', bp_current_user_can( 'bp_moderate' ) );
3383
- }
3384
-
3385
- /**
3386
- * Mark an activity item as spam.
3387
- *
3388
- * @since 1.6.0
3389
- *
3390
- * @todo We should probably save $source to activity meta.
3391
- *
3392
- * @param BP_Activity_Activity $activity The activity item to be spammed.
3393
- * @param string $source Optional. Default is "by_a_person" (ie, a person has
3394
- * manually marked the activity as spam). BP core also
3395
- * accepts 'by_akismet'.
3396
- */
3397
- function bp_activity_mark_as_spam( &$activity, $source = 'by_a_person' ) {
3398
- $bp = buddypress();
3399
-
3400
- $activity->is_spam = 1;
3401
-
3402
- // Clear the activity stream first page cache.
3403
- wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
3404
-
3405
- // Clear the activity comment cache for this activity item.
3406
- wp_cache_delete( $activity->id, 'bp_activity_comments' );
3407
-
3408
- // If Akismet is active, and this was a manual spam/ham request, stop Akismet checking the activity.
3409
- if ( 'by_a_person' == $source && !empty( $bp->activity->akismet ) ) {
3410
- remove_action( 'bp_activity_before_save', array( $bp->activity->akismet, 'check_activity' ), 4 );
3411
-
3412
- // Build data package for Akismet.
3413
- $activity_data = BP_Akismet::build_akismet_data_package( $activity );
3414
-
3415
- // Tell Akismet this is spam.
3416
- $activity_data = $bp->activity->akismet->send_akismet_request( $activity_data, 'submit', 'spam' );
3417
-
3418
- // Update meta.
3419
- add_action( 'bp_activity_after_save', array( $bp->activity->akismet, 'update_activity_spam_meta' ), 1, 1 );
3420
- }
3421
-
3422
- /**
3423
- * Fires at the end of the process to mark an activity item as spam.
3424
- *
3425
- * @since 1.6.0
3426
- *
3427
- * @param BP_Activity_Activity $activity Activity item being marked as spam.
3428
- * @param string $source Source of determination of spam status. For example
3429
- * "by_a_person" or "by_akismet".
3430
- */
3431
- do_action( 'bp_activity_mark_as_spam', $activity, $source );
3432
- }
3433
-
3434
- /**
3435
- * Mark an activity item as ham.
3436
- *
3437
- * @since 1.6.0
3438
- *
3439
- * @param BP_Activity_Activity $activity The activity item to be hammed. Passed by reference.
3440
- * @param string $source Optional. Default is "by_a_person" (ie, a person has
3441
- * manually marked the activity as spam). BP core also accepts
3442
- * 'by_akismet'.
3443
- */
3444
- function bp_activity_mark_as_ham( &$activity, $source = 'by_a_person' ) {
3445
- $bp = buddypress();
3446
-
3447
- $activity->is_spam = 0;
3448
-
3449
- // Clear the activity stream first page cache.
3450
- wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
3451
-
3452
- // Clear the activity comment cache for this activity item.
3453
- wp_cache_delete( $activity->id, 'bp_activity_comments' );
3454
-
3455
- // If Akismet is active, and this was a manual spam/ham request, stop Akismet checking the activity.
3456
- if ( 'by_a_person' == $source && !empty( $bp->activity->akismet ) ) {
3457
- remove_action( 'bp_activity_before_save', array( $bp->activity->akismet, 'check_activity' ), 4 );
3458
-
3459
- // Build data package for Akismet.
3460
- $activity_data = BP_Akismet::build_akismet_data_package( $activity );
3461
-
3462
- // Tell Akismet this is spam.
3463
- $activity_data = $bp->activity->akismet->send_akismet_request( $activity_data, 'submit', 'ham' );
3464
-
3465
- // Update meta.
3466
- add_action( 'bp_activity_after_save', array( $bp->activity->akismet, 'update_activity_ham_meta' ), 1, 1 );
3467
- }
3468
-
3469
- /**
3470
- * Fires at the end of the process to mark an activity item as ham.
3471
- *
3472
- * @since 1.6.0
3473
- *
3474
- * @param BP_Activity_Activity $activity Activity item being marked as ham.
3475
- * @param string $source Source of determination of ham status. For example
3476
- * "by_a_person" or "by_akismet".
3477
- */
3478
- do_action( 'bp_activity_mark_as_ham', $activity, $source );
3479
- }
3480
-
3481
- /* Emails *********************************************************************/
3482
-
3483
- /**
3484
- * Send email and BP notifications when a user is mentioned in an update.
3485
- *
3486
- * @since 1.2.0
3487
- *
3488
- * @param int $activity_id The ID of the activity update.
3489
- * @param int $receiver_user_id The ID of the user who is receiving the update.
3490
- */
3491
- function bp_activity_at_message_notification( $activity_id, $receiver_user_id ) {
3492
- $notifications = BP_Core_Notification::get_all_for_user( $receiver_user_id, 'all' );
3493
-
3494
- // Don't leave multiple notifications for the same activity item.
3495
- foreach( $notifications as $notification ) {
3496
- if ( $activity_id == $notification->item_id ) {
3497
- return;
3498
- }
3499
- }
3500
-
3501
- $activity = new BP_Activity_Activity( $activity_id );
3502
- $email_type = 'activity-at-message';
3503
- $group_name = '';
3504
- $message_link = bp_activity_get_permalink( $activity_id );
3505
- $poster_name = bp_core_get_user_displayname( $activity->user_id );
3506
-
3507
- remove_filter( 'bp_get_activity_content_body', 'convert_smilies' );
3508
- remove_filter( 'bp_get_activity_content_body', 'wpautop' );
3509
- remove_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
3510
-
3511
- /** This filter is documented in bp-activity/bp-activity-template.php */
3512
- $content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $activity->content, &$activity ) );
3513
-
3514
- add_filter( 'bp_get_activity_content_body', 'convert_smilies' );
3515
- add_filter( 'bp_get_activity_content_body', 'wpautop' );
3516
- add_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
3517
-
3518
- // Now email the user with the contents of the message (if they have enabled email notifications).
3519
- if ( 'no' != bp_get_user_meta( $receiver_user_id, 'notification_activity_new_mention', true ) ) {
3520
- if ( bp_is_active( 'groups' ) && bp_is_group() ) {
3521
- $email_type = 'groups-at-message';
3522
- $group_name = bp_get_current_group_name();
3523
- }
3524
-
3525
- $unsubscribe_args = array(
3526
- 'user_id' => $receiver_user_id,
3527
- 'notification_type' => $email_type,
3528
- );
3529
-
3530
- $args = array(
3531
- 'tokens' => array(
3532
- 'activity' => $activity,
3533
- 'usermessage' => wp_strip_all_tags( $content ),
3534
- 'group.name' => $group_name,
3535
- 'mentioned.url' => $message_link,
3536
- 'poster.name' => $poster_name,
3537
- 'receiver-user.id' => $receiver_user_id,
3538
- 'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ),
3539
- ),
3540
- );
3541
-
3542
- bp_send_email( $email_type, $receiver_user_id, $args );
3543
- }
3544
-
3545
- /**
3546
- * Fires after the sending of an @mention email notification.
3547
- *
3548
- * @since 1.5.0
3549
- * @since 2.5.0 $subject, $message, $content arguments unset and deprecated.
3550
- *
3551
- * @param BP_Activity_Activity $activity Activity Item object.
3552
- * @param string $deprecated Removed in 2.5; now an empty string.
3553
- * @param string $deprecated Removed in 2.5; now an empty string.
3554
- * @param string $deprecated Removed in 2.5; now an empty string.
3555
- * @param int $receiver_user_id The ID of the user who is receiving the update.
3556
- */
3557
- do_action( 'bp_activity_sent_mention_email', $activity, '', '', '', $receiver_user_id );
3558
- }
3559
-
3560
- /**
3561
- * Send email and BP notifications when an activity item receives a comment.
3562
- *
3563
- * @since 1.2.0
3564
- * @since 2.5.0 Updated to use new email APIs.
3565
- *
3566
- * @param int $comment_id The comment id.
3567
- * @param int $commenter_id The ID of the user who posted the comment.
3568
- * @param array $params {@link bp_activity_new_comment()}.
3569
- */
3570
- function bp_activity_new_comment_notification( $comment_id = 0, $commenter_id = 0, $params = array() ) {
3571
- $original_activity = new BP_Activity_Activity( $params['activity_id'] );
3572
- $poster_name = bp_core_get_user_displayname( $commenter_id );
3573
- $thread_link = bp_activity_get_permalink( $params['activity_id'] );
3574
-
3575
- remove_filter( 'bp_get_activity_content_body', 'convert_smilies' );
3576
- remove_filter( 'bp_get_activity_content_body', 'wpautop' );
3577
- remove_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
3578
-
3579
- /** This filter is documented in bp-activity/bp-activity-template.php */
3580
- $content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $params['content'], &$original_activity ) );
3581
-
3582
- add_filter( 'bp_get_activity_content_body', 'convert_smilies' );
3583
- add_filter( 'bp_get_activity_content_body', 'wpautop' );
3584
- add_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
3585
-
3586
- if ( $original_activity->user_id != $commenter_id ) {
3587
-
3588
- // Send an email if the user hasn't opted-out.
3589
- if ( 'no' != bp_get_user_meta( $original_activity->user_id, 'notification_activity_new_reply', true ) ) {
3590
-
3591
- $unsubscribe_args = array(
3592
- 'user_id' => $original_activity->user_id,
3593
- 'notification_type' => 'activity-comment',
3594
- );
3595
-
3596
- $args = array(
3597
- 'tokens' => array(
3598
- 'comment.id' => $comment_id,
3599
- 'commenter.id' => $commenter_id,
3600
- 'usermessage' => wp_strip_all_tags( $content ),
3601
- 'original_activity.user_id' => $original_activity->user_id,
3602
- 'poster.name' => $poster_name,
3603
- 'thread.url' => esc_url( $thread_link ),
3604
- 'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ),
3605
- ),
3606
- );
3607
-
3608
- bp_send_email( 'activity-comment', $original_activity->user_id, $args );
3609
- }
3610
-
3611
- /**
3612
- * Fires at the point that notifications should be sent for activity comments.
3613
- *
3614
- * @since 2.6.0
3615
- *
3616
- * @param BP_Activity_Activity $original_activity The original activity.
3617
- * @param int $comment_id ID for the newly received comment.
3618
- * @param int $commenter_id ID of the user who made the comment.
3619
- * @param array $params Arguments used with the original activity comment.
3620
- */
3621
- do_action( 'bp_activity_sent_reply_to_update_notification', $original_activity, $comment_id, $commenter_id, $params );
3622
- }
3623
-
3624
-
3625
- /*
3626
- * If this is a reply to another comment, send an email notification to the
3627
- * author of the immediate parent comment.
3628
- */
3629
- if ( empty( $params['parent_id'] ) || ( $params['activity_id'] == $params['parent_id'] ) ) {
3630
- return;
3631
- }
3632
-
3633
- $parent_comment = new BP_Activity_Activity( $params['parent_id'] );
3634
-
3635
- if ( $parent_comment->user_id != $commenter_id && $original_activity->user_id != $parent_comment->user_id ) {
3636
-
3637
- // Send an email if the user hasn't opted-out.
3638
- if ( 'no' != bp_get_user_meta( $parent_comment->user_id, 'notification_activity_new_reply', true ) ) {
3639
-
3640
- $unsubscribe_args = array(
3641
- 'user_id' => $parent_comment->user_id,
3642
- 'notification_type' => 'activity-comment-author',
3643
- );
3644
-
3645
- $args = array(
3646
- 'tokens' => array(
3647
- 'comment.id' => $comment_id,
3648
- 'commenter.id' => $commenter_id,
3649
- 'usermessage' => wp_strip_all_tags( $content ),
3650
- 'parent-comment-user.id' => $parent_comment->user_id,
3651
- 'poster.name' => $poster_name,
3652
- 'thread.url' => esc_url( $thread_link ),
3653
- 'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ),
3654
- ),
3655
- );
3656
-
3657
- bp_send_email( 'activity-comment-author', $parent_comment->user_id, $args );
3658
- }
3659
-
3660
- /**
3661
- * Fires at the point that notifications should be sent for comments on activity replies.
3662
- *
3663
- * @since 2.6.0
3664
- *
3665
- * @param BP_Activity_Activity $parent_comment The parent activity.
3666
- * @param int $comment_id ID for the newly received comment.
3667
- * @param int $commenter_id ID of the user who made the comment.
3668
- * @param array $params Arguments used with the original activity comment.
3669
- */
3670
- do_action( 'bp_activity_sent_reply_to_reply_notification', $parent_comment, $comment_id, $commenter_id, $params );
3671
- }
3672
- }
3673
-
3674
- /**
3675
- * Helper method to map action arguments to function parameters.
3676
- *
3677
- * @since 1.9.0
3678
- *
3679
- * @param int $comment_id ID of the comment being notified about.
3680
- * @param array $params Parameters to use with notification.
3681
- */
3682
- function bp_activity_new_comment_notification_helper( $comment_id, $params ) {
3683
- bp_activity_new_comment_notification( $comment_id, $params['user_id'], $params );
3684
- }
3685
- add_action( 'bp_activity_comment_posted', 'bp_activity_new_comment_notification_helper', 10, 2 );
3686
-
3687
- /** Embeds *******************************************************************/
3688
-
3689
- /**
3690
- * Set up activity oEmbed cache during the activity loop.
3691
- *
3692
- * During an activity loop, this function sets up the hooks necessary to grab
3693
- * each item's embeds from the cache, or put them in the cache if they are
3694
- * not there yet.
3695
- *
3696
- * This does not cover recursive activity comments, as they do not use a real loop.
3697
- * For that, see {@link bp_activity_comment_embed()}.
3698
- *
3699
- * @since 1.5.0
3700
- *
3701
- * @see BP_Embed
3702
- * @see bp_embed_activity_cache()
3703
- * @see bp_embed_activity_save_cache()
3704
- *
3705
- */
3706
- function bp_activity_embed() {
3707
- add_filter( 'embed_post_id', 'bp_get_activity_id' );
3708
- add_filter( 'oembed_dataparse', 'bp_activity_oembed_dataparse', 10, 2 );
3709
- add_filter( 'bp_embed_get_cache', 'bp_embed_activity_cache', 10, 3 );
3710
- add_action( 'bp_embed_update_cache', 'bp_embed_activity_save_cache', 10, 3 );
3711
- }
3712
- add_action( 'activity_loop_start', 'bp_activity_embed' );
3713
-
3714
- /**
3715
- * Cache full oEmbed response from oEmbed.
3716
- *
3717
- * @since 2.6.0
3718
- *
3719
- * @param string $retval Current oEmbed result.
3720
- * @param object $data Full oEmbed response.
3721
- * @param string $url URL used for the oEmbed request.
3722
- * @return string
3723
- */
3724
- function bp_activity_oembed_dataparse( $retval, $data ) {
3725
- buddypress()->activity->oembed_response = $data;
3726
-
3727
- return $retval;
3728
- }
3729
-
3730
- /**
3731
- * Set up activity oEmbed cache while recursing through activity comments.
3732
- *
3733
- * While crawling through an activity comment tree
3734
- * ({@link bp_activity_recurse_comments}), this function sets up the hooks
3735
- * necessary to grab each comment's embeds from the cache, or put them in
3736
- * the cache if they are not there yet.
3737
- *
3738
- * @since 1.5.0
3739
- *
3740
- * @see BP_Embed
3741
- * @see bp_embed_activity_cache()
3742
- * @see bp_embed_activity_save_cache()
3743
- *
3744
- */
3745
- function bp_activity_comment_embed() {
3746
- add_filter( 'embed_post_id', 'bp_get_activity_comment_id' );
3747
- add_filter( 'bp_embed_get_cache', 'bp_embed_activity_cache', 10, 3 );
3748
- add_action( 'bp_embed_update_cache', 'bp_embed_activity_save_cache', 10, 3 );
3749
- }
3750
- add_action( 'bp_before_activity_comment', 'bp_activity_comment_embed' );
3751
-
3752
- /**
3753
- * When a user clicks on a "Read More" item, make sure embeds are correctly parsed and shown for the expanded content.
3754
- *
3755
- * @since 1.5.0
3756
- *
3757
- * @see BP_Embed
3758
- *
3759
- * @param object $activity The activity that is being expanded.
3760
- */
3761
- function bp_dtheme_embed_read_more( $activity ) {
3762
- buddypress()->activity->read_more_id = $activity->id;
3763
-
3764
- add_filter( 'embed_post_id', function() { return buddypress()->activity->read_more_id; } );
3765
- add_filter( 'bp_embed_get_cache', 'bp_embed_activity_cache', 10, 3 );
3766
- add_action( 'bp_embed_update_cache', 'bp_embed_activity_save_cache', 10, 3 );
3767
- }
3768
- add_action( 'bp_dtheme_get_single_activity_content', 'bp_dtheme_embed_read_more' );
3769
- add_action( 'bp_legacy_theme_get_single_activity_content', 'bp_dtheme_embed_read_more' );
3770
-
3771
- /**
3772
- * Clean up 'embed_post_id' filter after comment recursion.
3773
- *
3774
- * This filter must be removed so that the non-comment filters take over again
3775
- * once the comments are done being processed.
3776
- *
3777
- * @since 1.5.0
3778
- *
3779
- * @see bp_activity_comment_embed()
3780
- */
3781
- function bp_activity_comment_embed_after_recurse() {
3782
- remove_filter( 'embed_post_id', 'bp_get_activity_comment_id' );
3783
- }
3784
- add_action( 'bp_after_activity_comment', 'bp_activity_comment_embed_after_recurse' );
3785
-
3786
- /**
3787
- * Fetch an activity item's cached embeds.
3788
- *
3789
- * Used during {@link BP_Embed::parse_oembed()} via {@link bp_activity_embed()}.
3790
- *
3791
- * @since 1.5.0
3792
- *
3793
- * @see BP_Embed::parse_oembed()
3794
- *
3795
- * @param string $cache An empty string passed by BP_Embed::parse_oembed() for
3796
- * functions like this one to filter.
3797
- * @param int $id The ID of the activity item.
3798
- * @param string $cachekey The cache key generated in BP_Embed::parse_oembed().
3799
- * @return mixed The cached embeds for this activity item.
3800
- */
3801
- function bp_embed_activity_cache( $cache, $id, $cachekey ) {
3802
- return bp_activity_get_meta( $id, $cachekey );
3803
- }
3804
-
3805
- /**
3806
- * Set an activity item's embed cache.
3807
- *
3808
- * Used during {@link BP_Embed::parse_oembed()} via {@link bp_activity_embed()}.
3809
- *
3810
- * @since 1.5.0
3811
- *
3812
- * @see BP_Embed::parse_oembed()
3813
- *
3814
- * @param string $cache An empty string passed by BP_Embed::parse_oembed() for
3815
- * functions like this one to filter.
3816
- * @param string $cachekey The cache key generated in BP_Embed::parse_oembed().
3817
- * @param int $id The ID of the activity item.
3818
- */
3819
- function bp_embed_activity_save_cache( $cache, $cachekey, $id ) {
3820
- bp_activity_update_meta( $id, $cachekey, $cache );
3821
-
3822
- // Cache full oEmbed response.
3823
- if ( true === isset( buddypress()->activity->oembed_response ) ) {
3824
- $cachekey = str_replace( '_oembed', '_oembed_response', $cachekey );
3825
- bp_activity_update_meta( $id, $cachekey, buddypress()->activity->oembed_response );
3826
- }
3827
- }
3828
-
3829
- /**
3830
- * Should we use Heartbeat to refresh activities?
3831
- *
3832
- * @since 2.0.0
3833
- *
3834
- * @return bool True if activity heartbeat is enabled, otherwise false.
3835
- */
3836
- function bp_activity_do_heartbeat() {
3837
- $retval = false;
3838
-
3839
- if ( bp_is_activity_heartbeat_active() && ( bp_is_activity_directory() || bp_is_group_activity() ) ) {
3840
- $retval = true;
3841
- }
3842
-
3843
- /**
3844
- * Filters whether the heartbeat feature in the activity stream should be active.
3845
- *
3846
- * @since 2.8.0
3847
- *
3848
- * @param bool $retval Whether or not activity heartbeat is active.
3849
- */
3850
- return (bool) apply_filters( 'bp_activity_do_heartbeat', $retval );
3851
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/bp-activity-loader.php DELETED
@@ -1,23 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Activity Streams Loader.
4
- *
5
- * An activity stream component, for users, groups, and site tracking.
6
- *
7
- * @package BuddyPress
8
- * @subpackage ActivityCore
9
- * @since 1.5.0
10
- */
11
-
12
- // Exit if accessed directly.
13
- defined( 'ABSPATH' ) || exit;
14
-
15
- /**
16
- * Set up the bp-activity component.
17
- *
18
- * @since 1.6.0
19
- */
20
- function bp_setup_activity() {
21
- buddypress()->activity = new BP_Activity_Component();
22
- }
23
- add_action( 'bp_setup_components', 'bp_setup_activity', 6 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/bp-activity-notifications.php CHANGED
@@ -1,341 +1,142 @@
1
  <?php
2
- /**
3
- * BuddyPress Activity Notifications.
4
- *
5
- * @package BuddyPress
6
- * @subpackage ActivityNotifications
7
- * @since 1.2.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Format notifications related to activity.
15
- *
16
- * @since 1.5.0
17
- *
18
- * @param string $action The type of activity item. Just 'new_at_mention' for now.
19
- * @param int $item_id The activity ID.
20
- * @param int $secondary_item_id In the case of at-mentions, this is the mentioner's ID.
21
- * @param int $total_items The total number of notifications to format.
22
- * @param string $format 'string' to get a BuddyBar-compatible notification, 'array' otherwise.
23
- * @param int $id Optional. The notification ID.
24
- * @return string $return Formatted @mention notification.
25
- */
26
- function bp_activity_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string', $id = 0 ) {
27
- $action_filter = $action;
28
- $return = false;
29
- $activity_id = $item_id;
30
- $user_id = $secondary_item_id;
31
- $user_fullname = bp_core_get_user_displayname( $user_id );
32
-
33
- switch ( $action ) {
34
- case 'new_at_mention':
35
- $action_filter = 'at_mentions';
36
- $link = bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/';
37
- $title = sprintf( __( '@%s Mentions', 'buddypress' ), bp_get_loggedin_user_username() );
38
- $amount = 'single';
39
-
40
- if ( (int) $total_items > 1 ) {
41
- $text = sprintf( __( 'You have %1$d new mentions', 'buddypress' ), (int) $total_items );
42
- $amount = 'multiple';
43
- } else {
44
- $text = sprintf( __( '%1$s mentioned you', 'buddypress' ), $user_fullname );
45
- }
46
- break;
47
-
48
- case 'update_reply':
49
- $link = bp_get_notifications_permalink();
50
- $title = __( 'New Activity reply', 'buddypress' );
51
- $amount = 'single';
52
-
53
- if ( (int) $total_items > 1 ) {
54
- $link = add_query_arg( 'type', $action, $link );
55
- $text = sprintf( __( 'You have %1$d new replies', 'buddypress' ), (int) $total_items );
56
- $amount = 'multiple';
57
- } else {
58
- $link = add_query_arg( 'nid', (int) $id, bp_activity_get_permalink( $activity_id ) );
59
- $text = sprintf( __( '%1$s commented on one of your updates', 'buddypress' ), $user_fullname );
60
- }
61
- break;
62
-
63
- case 'comment_reply':
64
- $link = bp_get_notifications_permalink();
65
- $title = __( 'New Activity comment reply', 'buddypress' );
66
- $amount = 'single';
67
-
68
- if ( (int) $total_items > 1 ) {
69
- $link = add_query_arg( 'type', $action, $link );
70
- $text = sprintf( __( 'You have %1$d new comment replies', 'buddypress' ), (int) $total_items );
71
- $amount = 'multiple';
72
- } else {
73
- $link = add_query_arg( 'nid', (int) $id, bp_activity_get_permalink( $activity_id ) );
74
- $text = sprintf( __( '%1$s replied to one your activity comments', 'buddypress' ), $user_fullname );
75
- }
76
- break;
77
- }
78
 
79
- if ( 'string' == $format ) {
80
-
81
- /**
82
- * Filters the activity notification for the string format.
83
- *
84
- * This is a variable filter that is dependent on how many items
85
- * need notified about. The two possible hooks are bp_activity_single_at_mentions_notification
86
- * or bp_activity_multiple_at_mentions_notification.
87
- *
88
- * @since 1.5.0
89
- * @since 2.6.0 use the $action_filter as a new dynamic portion of the filter name.
90
- *
91
- * @param string $string HTML anchor tag for the interaction.
92
- * @param string $link The permalink for the interaction.
93
- * @param int $total_items How many items being notified about.
94
- * @param int $activity_id ID of the activity item being formatted.
95
- * @param int $user_id ID of the user who inited the interaction.
96
- */
97
- $return = apply_filters( 'bp_activity_' . $amount . '_' . $action_filter . '_notification', '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>', $link, (int) $total_items, $activity_id, $user_id );
98
- } else {
99
-
100
- /**
101
- * Filters the activity notification for any non-string format.
102
- *
103
- * This is a variable filter that is dependent on how many items need notified about.
104
- * The two possible hooks are bp_activity_single_at_mentions_notification
105
- * or bp_activity_multiple_at_mentions_notification.
106
- *
107
- * @since 1.5.0
108
- * @since 2.6.0 use the $action_filter as a new dynamic portion of the filter name.
109
- *
110
- * @param array $array Array holding the content and permalink for the interaction notification.
111
- * @param string $link The permalink for the interaction.
112
- * @param int $total_items How many items being notified about.
113
- * @param int $activity_id ID of the activity item being formatted.
114
- * @param int $user_id ID of the user who inited the interaction.
115
- */
116
- $return = apply_filters( 'bp_activity_' . $amount . '_' . $action_filter . '_notification', array(
117
- 'text' => $text,
118
- 'link' => $link
119
- ), $link, (int) $total_items, $activity_id, $user_id );
120
- }
121
 
122
- /**
123
- * Fires right before returning the formatted activity notifications.
124
- *
125
- * @since 1.2.0
126
- *
127
- * @param string $action The type of activity item.
128
- * @param int $item_id The activity ID.
129
- * @param int $secondary_item_id The user ID who inited the interaction.
130
- * @param int $total_items Total amount of items to format.
131
- */
132
- do_action( 'activity_format_notifications', $action, $item_id, $secondary_item_id, $total_items );
133
 
134
- return $return;
135
- }
 
136
 
137
- /**
138
- * Notify a member when their nicename is mentioned in an activity stream item.
139
- *
140
- * Hooked to the 'bp_activity_sent_mention_email' action, we piggy back off the
141
- * existing email code for now, since it does the heavy lifting for us. In the
142
- * future when we separate emails from Notifications, this will need its own
143
- * 'bp_activity_at_name_send_emails' equivalent helper function.
144
- *
145
- * @since 1.9.0
146
- *
147
- * @param object $activity Activity object.
148
- * @param string $subject (not used) Notification subject.
149
- * @param string $message (not used) Notification message.
150
- * @param string $content (not used) Notification content.
151
- * @param int $receiver_user_id ID of user receiving notification.
152
- */
153
- function bp_activity_at_mention_add_notification( $activity, $subject, $message, $content, $receiver_user_id ) {
154
- bp_notifications_add_notification( array(
155
- 'user_id' => $receiver_user_id,
156
- 'item_id' => $activity->id,
157
- 'secondary_item_id' => $activity->user_id,
158
- 'component_name' => buddypress()->activity->id,
159
- 'component_action' => 'new_at_mention',
160
- 'date_notified' => bp_core_current_time(),
161
- 'is_new' => 1,
162
- ) );
163
- }
164
- add_action( 'bp_activity_sent_mention_email', 'bp_activity_at_mention_add_notification', 10, 5 );
165
-
166
- /**
167
- * Notify a member one of their activity received a reply.
168
- *
169
- * @since 2.6.0
170
- *
171
- * @param BP_Activity_Activity $activity The original activity.
172
- * @param int $comment_id ID for the newly received comment.
173
- * @param int $commenter_id ID of the user who made the comment.
174
- */
175
- function bp_activity_update_reply_add_notification( $activity, $comment_id, $commenter_id ) {
176
- bp_notifications_add_notification( array(
177
- 'user_id' => $activity->user_id,
178
- 'item_id' => $comment_id,
179
- 'secondary_item_id' => $commenter_id,
180
- 'component_name' => buddypress()->activity->id,
181
- 'component_action' => 'update_reply',
182
- 'date_notified' => bp_core_current_time(),
183
- 'is_new' => 1,
184
- ) );
185
- }
186
- add_action( 'bp_activity_sent_reply_to_update_notification', 'bp_activity_update_reply_add_notification', 10, 3 );
187
-
188
- /**
189
- * Notify a member one of their activity comment received a reply.
190
- *
191
- * @since 2.6.0
192
- *
193
- * @param BP_Activity_Activity $activity_comment The parent activity.
194
- * @param int $comment_id ID for the newly received comment.
195
- * @param int $commenter_id ID of the user who made the comment.
196
- */
197
- function bp_activity_comment_reply_add_notification( $activity_comment, $comment_id, $commenter_id ) {
198
- bp_notifications_add_notification( array(
199
- 'user_id' => $activity_comment->user_id,
200
- 'item_id' => $comment_id,
201
- 'secondary_item_id' => $commenter_id,
202
- 'component_name' => buddypress()->activity->id,
203
- 'component_action' => 'comment_reply',
204
- 'date_notified' => bp_core_current_time(),
205
- 'is_new' => 1,
206
- ) );
207
- }
208
- add_action( 'bp_activity_sent_reply_to_reply_notification', 'bp_activity_comment_reply_add_notification', 10, 3 );
209
-
210
- /**
211
- * Mark at-mention notifications as read when users visit their Mentions page.
212
- *
213
- * @since 1.5.0
214
- * @since 2.5.0 Add the $user_id parameter
215
- *
216
- * @param int $user_id The id of the user whose notifications are marked as read.
217
- */
218
- function bp_activity_remove_screen_notifications( $user_id = 0 ) {
219
- // Only mark read if the current user is looking at his own mentions.
220
- if ( empty( $user_id ) || (int) $user_id !== (int) bp_loggedin_user_id() ) {
221
- return;
222
- }
223
 
224
- bp_notifications_mark_notifications_by_type( $user_id, buddypress()->activity->id, 'new_at_mention' );
225
- }
226
- add_action( 'bp_activity_clear_new_mentions', 'bp_activity_remove_screen_notifications', 10, 1 );
227
-
228
- /**
229
- * Mark at-mention notification as read when user visits the activity with the mention.
230
- *
231
- * @since 2.0.0
232
- *
233
- * @param BP_Activity_Activity $activity Activity object.
234
- */
235
- function bp_activity_remove_screen_notifications_single_activity_permalink( $activity ) {
236
- if ( ! is_user_logged_in() ) {
237
- return;
238
- }
239
 
240
- // Mark as read any notifications for the current user related to this activity item.
241
- bp_notifications_mark_notifications_by_item_id( bp_loggedin_user_id(), $activity->id, buddypress()->activity->id, 'new_at_mention' );
242
- }
243
- add_action( 'bp_activity_screen_single_activity_permalink', 'bp_activity_remove_screen_notifications_single_activity_permalink' );
244
-
245
- /**
246
- * Mark non-mention notifications as read when user visits our read permalink.
247
- *
248
- * In particular, 'update_reply' and 'comment_reply' notifications are handled
249
- * here. See {@link bp_activity_format_notifications()} for more info.
250
- *
251
- * @since 2.6.0
252
- */
253
- function bp_activity_remove_screen_notifications_for_non_mentions() {
254
- if ( false === is_singular() || false === is_user_logged_in() || empty( $_GET['nid'] ) ) {
255
- return;
256
- }
257
 
258
- // Mark notification as read.
259
- BP_Notifications_Notification::update(
260
- array(
261
- 'is_new' => false
262
- ),
263
- array(
264
- 'user_id' => bp_loggedin_user_id(),
265
- 'id' => (int) $_GET['nid']
266
- )
267
- );
268
- }
269
- add_action( 'bp_screens', 'bp_activity_remove_screen_notifications_for_non_mentions' );
270
-
271
- /**
272
- * Delete at-mention notifications when the corresponding activity item is deleted.
273
- *
274
- * @since 2.0.0
275
- *
276
- * @param array $activity_ids_deleted IDs of deleted activity items.
277
- */
278
- function bp_activity_at_mention_delete_notification( $activity_ids_deleted = array() ) {
279
- // Let's delete all without checking if content contains any mentions
280
- // to avoid a query to get the activity.
281
- if ( ! empty( $activity_ids_deleted ) ) {
282
- foreach ( $activity_ids_deleted as $activity_id ) {
283
- bp_notifications_delete_all_notifications_by_type( $activity_id, buddypress()->activity->id );
 
284
  }
285
  }
286
  }
287
- add_action( 'bp_activity_deleted_activities', 'bp_activity_at_mention_delete_notification', 10 );
288
-
289
- /**
290
- * Add a notification for post comments to the post author or post commenter.
291
- *
292
- * Requires "activity stream commenting on blog and forum posts" to be enabled.
293
- *
294
- * @since 2.6.0
295
- *
296
- * @param int $activity_id The activity comment ID.
297
- * @param WP_Comment $post_type_comment WP Comment object.
298
- * @param array $activity_args Activity comment arguments.
299
- * @param object $activity_post_object The post type tracking args object.
300
- */
301
- function bp_activity_add_notification_for_synced_blog_comment( $activity_id, $post_type_comment, $activity_args, $activity_post_object ) {
302
- // If activity comments are disabled for WP posts, stop now!
303
- if ( bp_disable_blogforum_comments() || empty( $activity_id ) ) {
304
- return;
305
- }
306
 
307
- // Send a notification to the blog post author.
308
- if ( (int) $post_type_comment->post->post_author !== (int) $activity_args['user_id'] ) {
309
- // Only add a notification if comment author is a registered user.
310
- // @todo Should we remove this restriction?
311
- if ( ! empty( $post_type_comment->user_id ) ) {
312
- bp_notifications_add_notification( array(
313
- 'user_id' => $post_type_comment->post->post_author,
314
- 'item_id' => $activity_id,
315
- 'secondary_item_id' => $post_type_comment->user_id,
316
- 'component_name' => buddypress()->activity->id,
317
- 'component_action' => 'update_reply',
318
- 'date_notified' => $post_type_comment->comment_date_gmt,
319
- 'is_new' => 1,
320
- ) );
321
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
322
  }
323
 
324
- // Send a notification to the parent comment author for follow-up comments.
325
- if ( ! empty( $post_type_comment->comment_parent ) ) {
326
- $parent_comment = get_comment( $post_type_comment->comment_parent );
327
-
328
- if ( ! empty( $parent_comment->user_id ) && (int) $parent_comment->user_id !== (int) $activity_args['user_id'] ) {
329
- bp_notifications_add_notification( array(
330
- 'user_id' => $parent_comment->user_id,
331
- 'item_id' => $activity_id,
332
- 'secondary_item_id' => $post_type_comment->user_id,
333
- 'component_name' => buddypress()->activity->id,
334
- 'component_action' => 'comment_reply',
335
- 'date_notified' => $post_type_comment->comment_date_gmt,
336
- 'is_new' => 1,
337
- ) );
338
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  }
340
  }
341
- add_action( 'bp_blogs_comment_sync_activity_comment', 'bp_activity_add_notification_for_synced_blog_comment', 10, 4 );
 
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
+ function bp_activity_at_message_notification( $content, $poster_user_id, $activity_id ) {
4
+ global $bp;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
+ /* Scan for @username strings in an activity update. Notify each user. */
7
+ $pattern = '/[@]+([A-Za-z0-9-_\.]+)/';
8
+ preg_match_all( $pattern, $content, $usernames );
 
 
 
 
 
 
 
 
9
 
10
+ /* Make sure there's only one instance of each username */
11
+ if ( !$usernames = array_unique( $usernames[1] ) )
12
+ return false;
13
 
14
+ foreach( (array)$usernames as $username ) {
15
+ if ( !$receiver_user_id = bp_core_get_userid( $username ) )
16
+ continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
+ // Now email the user with the contents of the message (if they have enabled email notifications)
19
+ if ( 'no' != get_user_meta( $receiver_user_id, 'notification_activity_new_mention', true ) ) {
20
+ $poster_name = bp_core_get_user_displayname( $poster_user_id );
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
+ $message_link = bp_activity_get_permalink( $activity_id );
23
+ $settings_link = bp_core_get_user_domain( $receiver_user_id ) . BP_SETTINGS_SLUG . '/notifications/';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
+ $poster_name = stripslashes( $poster_name );
26
+ $content = bp_activity_filter_kses( stripslashes($content) );
27
+
28
+ // Set up and send the message
29
+ $ud = bp_core_get_core_userdata( $receiver_user_id );
30
+ $to = $ud->user_email;
31
+ $sitename = wp_specialchars_decode( get_blog_option( BP_ROOT_BLOG, 'blogname' ), ENT_QUOTES );
32
+ $subject = '[' . $sitename . '] ' . sprintf( __( '%s mentioned you in an update', 'buddypress' ), $poster_name );
33
+
34
+ $message = sprintf( __(
35
+ '%s mentioned you in an update:
36
+
37
+ "%s"
38
+
39
+ To view and respond to the message, log in and visit: %s
40
+
41
+ ---------------------
42
+ ', 'buddypress' ), $poster_name, $content, $message_link );
43
+
44
+ $message .= sprintf( __( 'To disable these notifications please log in and go to: %s', 'buddypress' ), $settings_link );
45
+
46
+ /* Send the message */
47
+ $to = apply_filters( 'bp_activity_at_message_notification_to', $to );
48
+ $subject = apply_filters( 'bp_activity_at_message_notification_subject', $subject, $poster_name );
49
+ $message = apply_filters( 'bp_activity_at_message_notification_message', $message, $poster_name, $content, $message_link );
50
+
51
+ wp_mail( $to, $subject, $message );
52
  }
53
  }
54
  }
55
+ add_action( 'bp_activity_posted_update', 'bp_activity_at_message_notification', 10, 3 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
+ function bp_activity_new_comment_notification( $comment_id, $commenter_id, $params ) {
58
+ global $bp;
59
+
60
+ extract( $params );
61
+
62
+ $original_activity = new BP_Activity_Activity( $activity_id );
63
+
64
+ if ( $original_activity->user_id != $commenter_id && 'no' != get_user_meta( $original_activity->user_id, 'notification_activity_new_reply', true ) ) {
65
+ $poster_name = bp_core_get_user_displayname( $commenter_id );
66
+ $thread_link = bp_activity_get_permalink( $activity_id );
67
+ $settings_link = bp_core_get_user_domain( $original_activity->user_id ) . BP_SETTINGS_SLUG . '/notifications/';
68
+
69
+ $poster_name = stripslashes( $poster_name );
70
+ $content = bp_activity_filter_kses( stripslashes($content) );
71
+
72
+ // Set up and send the message
73
+ $ud = bp_core_get_core_userdata( $original_activity->user_id );
74
+ $to = $ud->user_email;
75
+ $sitename = wp_specialchars_decode( get_blog_option( BP_ROOT_BLOG, 'blogname' ), ENT_QUOTES );
76
+ $subject = '[' . $sitename . '] ' . sprintf( __( '%s replied to one of your updates', 'buddypress' ), $poster_name );
77
+
78
+ $message = sprintf( __(
79
+ '%s replied to one of your updates:
80
+
81
+ "%s"
82
+
83
+ To view your original update and all comments, log in and visit: %s
84
+
85
+ ---------------------
86
+ ', 'buddypress' ), $poster_name, $content, $thread_link );
87
+
88
+ $message .= sprintf( __( 'To disable these notifications please log in and go to: %s', 'buddypress' ), $settings_link );
89
+
90
+ /* Send the message */
91
+ $to = apply_filters( 'bp_activity_new_comment_notification_to', $to );
92
+ $subject = apply_filters( 'bp_activity_new_comment_notification_subject', $subject, $poster_name );
93
+ $message = apply_filters( 'bp_activity_new_comment_notification_message', $message, $poster_name, $content, $thread_link );
94
+
95
+ wp_mail( $to, $subject, $message );
96
  }
97
 
98
+ /***
99
+ * If this is a reply to another comment, send an email notification to the
100
+ * author of the immediate parent comment.
101
+ */
102
+ if ( $activity_id == $parent_id )
103
+ return false;
104
+
105
+ $parent_comment = new BP_Activity_Activity( $parent_id );
106
+
107
+ if ( $parent_comment->user_id != $commenter_id && $original_activity->user_id != $parent_comment->user_id && 'no' != get_user_meta( $parent_comment->user_id, 'notification_activity_new_reply', true ) ) {
108
+ $poster_name = bp_core_get_user_displayname( $commenter_id );
109
+ $thread_link = bp_activity_get_permalink( $activity_id );
110
+ $settings_link = bp_core_get_user_domain( $parent_comment->user_id ) . BP_SETTINGS_SLUG . '/notifications/';
111
+
112
+ // Set up and send the message
113
+ $ud = bp_core_get_core_userdata( $parent_comment->user_id );
114
+ $to = $ud->user_email;
115
+ $sitename = wp_specialchars_decode( get_blog_option( BP_ROOT_BLOG, 'blogname' ), ENT_QUOTES );
116
+ $subject = '[' . $sitename . '] ' . sprintf( __( '%s replied to one of your comments', 'buddypress' ), $poster_name );
117
+
118
+ $poster_name = stripslashes( $poster_name );
119
+ $content = bp_activity_filter_kses( stripslashes( $content ) );
120
+
121
+ $message = sprintf( __(
122
+ '%s replied to one of your comments:
123
+
124
+ "%s"
125
+
126
+ To view the original activity, your comment and all replies, log in and visit: %s
127
+
128
+ ---------------------
129
+ ', 'buddypress' ), $poster_name, $content, $thread_link );
130
+
131
+ $message .= sprintf( __( 'To disable these notifications please log in and go to: %s', 'buddypress' ), $settings_link );
132
+
133
+ /* Send the message */
134
+ $to = apply_filters( 'bp_activity_new_comment_notification_comment_author_to', $to );
135
+ $subject = apply_filters( 'bp_activity_new_comment_notification_comment_author_subject', $subject, $poster_name );
136
+ $message = apply_filters( 'bp_activity_new_comment_notification_comment_author_message', $message, $poster_name, $content );
137
+
138
+ wp_mail( $to, $subject, $message );
139
  }
140
  }
141
+
142
+ ?>
bp-activity/bp-activity-screens.php DELETED
@@ -1,379 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Activity Screens.
4
- *
5
- * The functions in this file detect, with each page load, whether an Activity
6
- * component page is being requested. If so, it parses any necessary data from
7
- * the URL, and tells BuddyPress to load the appropriate template.
8
- *
9
- * @package BuddyPress
10
- * @subpackage ActivityScreens
11
- * @since 1.5.0
12
- */
13
-
14
- // Exit if accessed directly.
15
- defined( 'ABSPATH' ) || exit;
16
-
17
- /**
18
- * Load the Activity directory.
19
- *
20
- * @since 1.5.0
21
- *
22
- */
23
- function bp_activity_screen_index() {
24
- if ( bp_is_activity_directory() ) {
25
- bp_update_is_directory( true, 'activity' );
26
-
27
- /**
28
- * Fires right before the loading of the Activity directory screen template file.
29
- *
30
- * @since 1.5.0
31
- */
32
- do_action( 'bp_activity_screen_index' );
33
-
34
- /**
35
- * Filters the template to load for the Activity directory screen.
36
- *
37
- * @since 1.5.0
38
- *
39
- * @param string $template Path to the activity template to load.
40
- */
41
- bp_core_load_template( apply_filters( 'bp_activity_screen_index', 'activity/index' ) );
42
- }
43
- }
44
- add_action( 'bp_screens', 'bp_activity_screen_index' );
45
-
46
- /**
47
- * Load the 'My Activity' page.
48
- *
49
- * @since 1.0.0
50
- *
51
- */
52
- function bp_activity_screen_my_activity() {
53
-
54
- /**
55
- * Fires right before the loading of the "My Activity" screen template file.
56
- *
57
- * @since 1.0.0
58
- */
59
- do_action( 'bp_activity_screen_my_activity' );
60
-
61
- /**
62
- * Filters the template to load for the "My Activity" screen.
63
- *
64
- * @since 1.0.0
65
- *
66
- * @param string $template Path to the activity template to load.
67
- */
68
- bp_core_load_template( apply_filters( 'bp_activity_template_my_activity', 'members/single/home' ) );
69
- }
70
-
71
- /**
72
- * Load the 'My Friends' activity page.
73
- *
74
- * @since 1.0.0
75
- *
76
- */
77
- function bp_activity_screen_friends() {
78
- if ( !bp_is_active( 'friends' ) )
79
- return false;
80
-
81
- bp_update_is_item_admin( bp_current_user_can( 'bp_moderate' ), 'activity' );
82
-
83
- /**
84
- * Fires right before the loading of the "My Friends" screen template file.
85
- *
86
- * @since 1.2.0
87
- */
88
- do_action( 'bp_activity_screen_friends' );
89
-
90
- /**
91
- * Filters the template to load for the "My Friends" screen.
92
- *
93
- * @since 1.0.0
94
- *
95
- * @param string $template Path to the activity template to load.
96
- */
97
- bp_core_load_template( apply_filters( 'bp_activity_template_friends_activity', 'members/single/home' ) );
98
- }
99
-
100
- /**
101
- * Load the 'My Groups' activity page.
102
- *
103
- * @since 1.2.0
104
- *
105
- */
106
- function bp_activity_screen_groups() {
107
- if ( !bp_is_active( 'groups' ) )
108
- return false;
109
-
110
- bp_update_is_item_admin( bp_current_user_can( 'bp_moderate' ), 'activity' );
111
-
112
- /**
113
- * Fires right before the loading of the "My Groups" screen template file.
114
- *
115
- * @since 1.2.0
116
- */
117
- do_action( 'bp_activity_screen_groups' );
118
-
119
- /**
120
- * Filters the template to load for the "My Groups" screen.
121
- *
122
- * @since 1.2.0
123
- *
124
- * @param string $template Path to the activity template to load.
125
- */
126
- bp_core_load_template( apply_filters( 'bp_activity_template_groups_activity', 'members/single/home' ) );
127
- }
128
-
129
- /**
130
- * Load the 'Favorites' activity page.
131
- *
132
- * @since 1.2.0
133
- *
134
- */
135
- function bp_activity_screen_favorites() {
136
- bp_update_is_item_admin( bp_current_user_can( 'bp_moderate' ), 'activity' );
137
-
138
- /**
139
- * Fires right before the loading of the "Favorites" screen template file.
140
- *
141
- * @since 1.2.0
142
- */
143
- do_action( 'bp_activity_screen_favorites' );
144
-
145
- /**
146
- * Filters the template to load for the "Favorites" screen.
147
- *
148
- * @since 1.2.0
149
- *
150
- * @param string $template Path to the activity template to load.
151
- */
152
- bp_core_load_template( apply_filters( 'bp_activity_template_favorite_activity', 'members/single/home' ) );
153
- }
154
-
155
- /**
156
- * Load the 'Mentions' activity page.
157
- *
158
- * @since 1.2.0
159
- *
160
- */
161
- function bp_activity_screen_mentions() {
162
- bp_update_is_item_admin( bp_current_user_can( 'bp_moderate' ), 'activity' );
163
-
164
- /**
165
- * Fires right before the loading of the "Mentions" screen template file.
166
- *
167
- * @since 1.2.0
168
- */
169
- do_action( 'bp_activity_screen_mentions' );
170
-
171
- /**
172
- * Filters the template to load for the "Mentions" screen.
173
- *
174
- * @since 1.2.0
175
- *
176
- * @param string $template Path to the activity template to load.
177
- */
178
- bp_core_load_template( apply_filters( 'bp_activity_template_mention_activity', 'members/single/home' ) );
179
- }
180
-
181
- /**
182
- * Reset the logged-in user's new mentions data when he visits his mentions screen.
183
- *
184
- * @since 1.5.0
185
- *
186
- */
187
- function bp_activity_reset_my_new_mentions() {
188
- if ( bp_is_my_profile() )
189
- bp_activity_clear_new_mentions( bp_loggedin_user_id() );
190
- }
191
- add_action( 'bp_activity_screen_mentions', 'bp_activity_reset_my_new_mentions' );
192
-
193
- /**
194
- * Load the page for a single activity item.
195
- *
196
- * @since 1.2.0
197
- *
198
- */
199
- function bp_activity_screen_single_activity_permalink() {
200
- $bp = buddypress();
201
-
202
- // No displayed user or not viewing activity component.
203
- if ( !bp_is_activity_component() )
204
- return false;
205
-
206
- if ( ! bp_current_action() || !is_numeric( bp_current_action() ) )
207
- return false;
208
-
209
- // Get the activity details.
210
- $activity = bp_activity_get_specific( array( 'activity_ids' => bp_current_action(), 'show_hidden' => true, 'spam' => 'ham_only', ) );
211
-
212
- // 404 if activity does not exist
213
- if ( empty( $activity['activities'][0] ) || bp_action_variables() ) {
214
- bp_do_404();
215
- return;
216
-
217
- } else {
218
- $activity = $activity['activities'][0];
219
- }
220
-
221
- // Default access is true.
222
- $has_access = true;
223
-
224
- // If activity is from a group, do an extra cap check.
225
- if ( isset( $bp->groups->id ) && $activity->component == $bp->groups->id ) {
226
-
227
- // Activity is from a group, but groups is currently disabled.
228
- if ( !bp_is_active( 'groups') ) {
229
- bp_do_404();
230
- return;
231
- }
232
-
233
- // Check to see if the group is not public, if so, check the
234
- // user has access to see this activity.
235
- if ( $group = groups_get_group( $activity->item_id ) ) {
236
-
237
- // Group is not public.
238
- if ( 'public' != $group->status ) {
239
-
240
- // User is not a member of group.
241
- if ( !groups_is_user_member( bp_loggedin_user_id(), $group->id ) ) {
242
- $has_access = false;
243
- }
244
- }
245
- }
246
- }
247
-
248
- // If activity author does not match displayed user, block access.
249
- if ( true === $has_access && bp_displayed_user_id() !== $activity->user_id ) {
250
- $has_access = false;
251
- }
252
-
253
- /**
254
- * Filters the access permission for a single activity view.
255
- *
256
- * @since 1.2.0
257
- *
258
- * @param array $access Array holding the current $has_access value and current activity item instance.
259
- */
260
- $has_access = apply_filters_ref_array( 'bp_activity_permalink_access', array( $has_access, &$activity ) );
261
-
262
- /**
263
- * Fires before the loading of a single activity template file.
264
- *
265
- * @since 1.2.0
266
- *
267
- * @param BP_Activity_Activity $activity Object representing the current activity item being displayed.
268
- * @param bool $has_access Whether or not the current user has access to view activity.
269
- */
270
- do_action( 'bp_activity_screen_single_activity_permalink', $activity, $has_access );
271
-
272
- // Access is specifically disallowed.
273
- if ( false === $has_access ) {
274
-
275
- // User feedback.
276
- bp_core_add_message( __( 'You do not have access to this activity.', 'buddypress' ), 'error' );
277
-
278
- // Redirect based on logged in status.
279
- if ( is_user_logged_in() ) {
280
- $url = bp_loggedin_user_domain();
281
-
282
- } else {
283
- $url = sprintf(
284
- site_url( 'wp-login.php?redirect_to=%s' ),
285
- urlencode( esc_url_raw( bp_activity_get_permalink( bp_current_action() ) ) )
286
- );
287
- }
288
-
289
- bp_core_redirect( $url );
290
- }
291
-
292
- /**
293
- * Filters the template to load for a single activity screen.
294
- *
295
- * @since 1.0.0
296
- *
297
- * @param string $template Path to the activity template to load.
298
- */
299
- bp_core_load_template( apply_filters( 'bp_activity_template_profile_activity_permalink', 'members/single/activity/permalink' ) );
300
- }
301
- add_action( 'bp_screens', 'bp_activity_screen_single_activity_permalink' );
302
-
303
- /**
304
- * Add activity notifications settings to the notifications settings page.
305
- *
306
- * @since 1.2.0
307
- *
308
- */
309
- function bp_activity_screen_notification_settings() {
310
-
311
- if ( bp_activity_do_mentions() ) {
312
- if ( ! $mention = bp_get_user_meta( bp_displayed_user_id(), 'notification_activity_new_mention', true ) ) {
313
- $mention = 'yes';
314
- }
315
- }
316
-
317
- if ( ! $reply = bp_get_user_meta( bp_displayed_user_id(), 'notification_activity_new_reply', true ) ) {
318
- $reply = 'yes';
319
- }
320
-
321
- ?>
322
-
323
- <table class="notification-settings" id="activity-notification-settings">
324
- <thead>
325
- <tr>
326
- <th class="icon">&nbsp;</th>
327
- <th class="title"><?php _e( 'Activity', 'buddypress' ) ?></th>
328
- <th class="yes"><?php _e( 'Yes', 'buddypress' ) ?></th>
329
- <th class="no"><?php _e( 'No', 'buddypress' )?></th>
330
- </tr>
331
- </thead>
332
-
333
- <tbody>
334
- <?php if ( bp_activity_do_mentions() ) : ?>
335
- <tr id="activity-notification-settings-mentions">
336
- <td>&nbsp;</td>
337
- <td><?php printf( __( 'A member mentions you in an update using "@%s"', 'buddypress' ), bp_core_get_username( bp_displayed_user_id() ) ) ?></td>
338
- <td class="yes"><input type="radio" name="notifications[notification_activity_new_mention]" id="notification-activity-new-mention-yes" value="yes" <?php checked( $mention, 'yes', true ) ?>/><label for="notification-activity-new-mention-yes" class="bp-screen-reader-text"><?php
339
- /* translators: accessibility text */
340
- _e( 'Yes, send email', 'buddypress' );
341
- ?></label></td>
342
- <td class="no"><input type="radio" name="notifications[notification_activity_new_mention]" id="notification-activity-new-mention-no" value="no" <?php checked( $mention, 'no', true ) ?>/><label for="notification-activity-new-mention-no" class="bp-screen-reader-text"><?php
343
- /* translators: accessibility text */
344
- _e( 'No, do not send email', 'buddypress' );
345
- ?></label></td>
346
- </tr>
347
- <?php endif; ?>
348
-
349
- <tr id="activity-notification-settings-replies">
350
- <td>&nbsp;</td>
351
- <td><?php _e( "A member replies to an update or comment you've posted", 'buddypress' ) ?></td>
352
- <td class="yes"><input type="radio" name="notifications[notification_activity_new_reply]" id="notification-activity-new-reply-yes" value="yes" <?php checked( $reply, 'yes', true ) ?>/><label for="notification-activity-new-reply-yes" class="bp-screen-reader-text"><?php
353
- /* translators: accessibility text */
354
- _e( 'Yes, send email', 'buddypress' );
355
- ?></label></td>
356
- <td class="no"><input type="radio" name="notifications[notification_activity_new_reply]" id="notification-activity-new-reply-no" value="no" <?php checked( $reply, 'no', true ) ?>/><label for="notification-activity-new-reply-no" class="bp-screen-reader-text"><?php
357
- /* translators: accessibility text */
358
- _e( 'No, do not send email', 'buddypress' );
359
- ?></label></td>
360
- </tr>
361
-
362
- <?php
363
-
364
- /**
365
- * Fires inside the closing </tbody> tag for activity screen notification settings.
366
- *
367
- * @since 1.2.0
368
- */
369
- do_action( 'bp_activity_screen_notification_settings' ) ?>
370
- </tbody>
371
- </table>
372
-
373
- <?php
374
- }
375
- add_action( 'bp_notification_settings', 'bp_activity_screen_notification_settings', 1 );
376
-
377
- /** Theme Compatibility *******************************************************/
378
-
379
- new BP_Activity_Theme_Compat();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/bp-activity-template.php DELETED
@@ -1,3881 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Activity Template Functions.
4
- *
5
- * @package BuddyPress
6
- * @subpackage ActivityTemplate
7
- * @since 1.5.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Output the activity component slug.
15
- *
16
- * @since 1.5.0
17
- *
18
- */
19
- function bp_activity_slug() {
20
- echo bp_get_activity_slug();
21
- }
22
- /**
23
- * Return the activity component slug.
24
- *
25
- * @since 1.5.0
26
- *
27
- *
28
- * @return string The activity component slug.
29
- */
30
- function bp_get_activity_slug() {
31
-
32
- /**
33
- * Filters the activity component slug.
34
- *
35
- * @since 1.5.0
36
- *
37
- * @param string $slug Activity component slug.
38
- */
39
- return apply_filters( 'bp_get_activity_slug', buddypress()->activity->slug );
40
- }
41
-
42
- /**
43
- * Output the activity component root slug.
44
- *
45
- * @since 1.5.0
46
- *
47
- */
48
- function bp_activity_root_slug() {
49
- echo bp_get_activity_root_slug();
50
- }
51
- /**
52
- * Return the activity component root slug.
53
- *
54
- * @since 1.5.0
55
- *
56
- *
57
- * @return string The activity component root slug.
58
- */
59
- function bp_get_activity_root_slug() {
60
-
61
- /**
62
- * Filters the activity component root slug.
63
- *
64
- * @since 1.5.0
65
- *
66
- * @param string $root_slug Activity component root slug.
67
- */
68
- return apply_filters( 'bp_get_activity_root_slug', buddypress()->activity->root_slug );
69
- }
70
-
71
- /**
72
- * Output activity directory permalink.
73
- *
74
- * @since 1.5.0
75
- *
76
- */
77
- function bp_activity_directory_permalink() {
78
- echo esc_url( bp_get_activity_directory_permalink() );
79
- }
80
- /**
81
- * Return activity directory permalink.
82
- *
83
- * @since 1.5.0
84
- *
85
- *
86
- * @return string Activity directory permalink.
87
- */
88
- function bp_get_activity_directory_permalink() {
89
-
90
- /**
91
- * Filters the activity directory permalink.
92
- *
93
- * @since 1.5.0
94
- *
95
- * @param string $url Permalink url for the activity directory.
96
- */
97
- return apply_filters( 'bp_get_activity_directory_permalink', trailingslashit( bp_get_root_domain() . '/' . bp_get_activity_root_slug() ) );
98
- }
99
-
100
- /**
101
- * Initialize the activity loop.
102
- *
103
- * Based on the $args passed, bp_has_activities() populates the
104
- * $activities_template global, enabling the use of BuddyPress templates and
105
- * template functions to display a list of activity items.
106
- *
107
- * @since 1.0.0
108
- * @since 2.4.0 Introduced the `$fields` parameter.
109
- *
110
- * @global object $activities_template {@link BP_Activity_Template}
111
- *
112
- * @param array|string $args {
113
- * Arguments for limiting the contents of the activity loop. Most arguments
114
- * are in the same format as {@link BP_Activity_Activity::get()}. However,
115
- * because the format of the arguments accepted here differs in a number of
116
- * ways, and because bp_has_activities() determines some default arguments in
117
- * a dynamic fashion, we list all accepted arguments here as well.
118
- *
119
- * Arguments can be passed as an associative array, or as a URL querystring
120
- * (eg, 'user_id=4&display_comments=threaded').
121
- *
122
- * @type int $page Which page of results to fetch. Using page=1 without per_page will result
123
- * in no pagination. Default: 1.
124
- * @type int|bool $per_page Number of results per page. Default: 20.
125
- * @type string $page_arg String used as a query parameter in pagination links. Default: 'acpage'.
126
- * @type int|bool $max Maximum number of results to return. Default: false (unlimited).
127
- * @type string $fields Activity fields to retrieve. 'all' to fetch entire activity objects,
128
- * 'ids' to get only the activity IDs. Default 'all'.
129
- * @type string|bool $count_total If true, an additional DB query is run to count the total activity items
130
- * for the query. Default: false.
131
- * @type string $sort 'ASC' or 'DESC'. Default: 'DESC'.
132
- * @type array|bool $exclude Array of activity IDs to exclude. Default: false.
133
- * @type array|bool $in Array of IDs to limit query by (IN). 'in' is intended to be used in
134
- * conjunction with other filter parameters. Default: false.
135
- * @type array|bool $include Array of exact activity IDs to query. Providing an 'include' array will
136
- * override all other filters passed in the argument array. When viewing the
137
- * permalink page for a single activity item, this value defaults to the ID of
138
- * that item. Otherwise the default is false.
139
- * @type array $meta_query Limit by activitymeta by passing an array of meta_query conditions. See
140
- * {@link WP_Meta_Query::queries} for a description of the syntax.
141
- * @type array $date_query Limit by date by passing an array of date_query conditions. See first
142
- * parameter of {@link WP_Date_Query::__construct()} for syntax.
143
- * @type array $filter_query Advanced activity filtering. See {@link BP_Activity_Query::__construct()}.
144
- * @type string $search_terms Limit results by a search term. Default: false.
145
- * @type string $scope Use a BuddyPress pre-built filter.
146
- * - 'just-me' retrieves items belonging only to a user; this is equivalent
147
- * to passing a 'user_id' argument.
148
- * - 'friends' retrieves items belonging to the friends of a user.
149
- * - 'groups' retrieves items belonging to groups to which a user belongs to.
150
- * - 'favorites' retrieves a user's favorited activity items.
151
- * - 'mentions' retrieves items where a user has received an @-mention.
152
- * The default value of 'scope' is set to one of the above if that value
153
- * appears in the appropriate place in the URL; eg, 'scope' will be 'groups'
154
- * when visiting http://example.com/members/joe/activity/groups/. Otherwise
155
- * defaults to false.
156
- * @type int|array|bool $user_id The ID(s) of user(s) whose activity should be fetched. Pass a single ID or
157
- * an array of IDs. When viewing a user profile page (but not that user's
158
- * activity subpages, ie My Friends, My Groups, etc), 'user_id' defaults to
159
- * the ID of the displayed user. Otherwise the default is false.
160
- * @type string|array|bool $object Filters by the `component` column in the database, which is generally the
161
- * component ID in the case of BuddyPress components, or the plugin slug in
162
- * the case of plugins. For example, 'groups' will limit results to those that
163
- * are associated with the BP Groups component. Accepts a single component
164
- * string, or an array of multiple components. Defaults to 'groups' when
165
- * viewing the page of a single group, the My Groups activity filter, or the
166
- * Activity > Groups filter of a user profile. Otherwise defaults to false.
167
- * @type string|array|bool $action Filters by the `type` column in the database, which is a string
168
- * categorizing the activity item (eg, 'new_blog_post', 'created_group').
169
- * Accepts a comma-delimited string or an array of types. Default: false.
170
- * @type int|array|bool $primary_id Filters by the `item_id` column in the database. The meaning of
171
- * 'primary_id' differs between components/types; for example, in the case of
172
- * 'created_group', 'primary_id' is the ID of the group. Accepts a single ID,
173
- * or an array of multiple IDs. When viewing a single group, defaults to the
174
- * current group ID. When viewing a user's Groups stream page, defaults to the
175
- * IDs of the user's groups. Otherwise defaults to false.
176
- * @type int|array|bool $secondary_id Filters by the `secondary_item_id` column in the database. The meaning of
177
- * 'secondary_id' differs between components/types. Accepts a single ID, or an
178
- * array of multiple IDs. Defaults to false.
179
- * @type int $offset Return only activity items with an ID greater than or equal to this one.
180
- * Note that providing an offset will disable pagination. Default: false.
181
- * @type string|bool $display_comments How to handle activity comments. Possible values:
182
- * - 'threaded' - comments appear in a threaded tree, under their parent
183
- * items.
184
- * - 'stream' - the activity stream is presented in a flat manner, with
185
- * comments sorted in chronological order alongside other activity items.
186
- * - false - don't fetch activity comments at all.
187
- * Default: 'threaded'.
188
- * @type bool $show_hidden Whether to show items marked hide_sitewide. Defaults to false, except in
189
- * the following cases:
190
- * - User is viewing his own activity stream.
191
- * - User is viewing the activity stream of a non-public group of which he
192
- * is a member.
193
- * @type string|bool $spam Spam status. 'ham_only', 'spam_only', or false to show all activity
194
- * regardless of spam status. Default: 'ham_only'.
195
- * @type bool $populate_extras Whether to pre-fetch the activity metadata for the queried items.
196
- * Default: true.
197
- * }
198
- * @return bool Returns true when activities are found, otherwise false.
199
- */
200
- function bp_has_activities( $args = '' ) {
201
- global $activities_template;
202
-
203
- // Get BuddyPress.
204
- $bp = buddypress();
205
-
206
- /*
207
- * Smart Defaults.
208
- */
209
-
210
- // User filtering.
211
- $user_id = bp_displayed_user_id()
212
- ? bp_displayed_user_id()
213
- : false;
214
-
215
- // Group filtering.
216
- if ( bp_is_group() ) {
217
- $object = $bp->groups->id;
218
- $primary_id = bp_get_current_group_id();
219
- $show_hidden = (bool) ( groups_is_user_member( bp_loggedin_user_id(), $primary_id ) || bp_current_user_can( 'bp_moderate' ) );
220
- } else {
221
- $object = false;
222
- $primary_id = false;
223
- $show_hidden = false;
224
- }
225
-
226
- // The default scope should recognize custom slugs.
227
- $scope = array_key_exists( bp_current_action(), (array) $bp->loaded_components )
228
- ? $bp->loaded_components[ bp_current_action() ]
229
- : bp_current_action();
230
-
231
- // Support for permalinks on single item pages: /groups/my-group/activity/124/.
232
- $include = bp_is_current_action( bp_get_activity_slug() )
233
- ? bp_action_variable( 0 )
234
- : false;
235
-
236
- $search_terms_default = false;
237
- $search_query_arg = bp_core_get_component_search_query_arg( 'activity' );
238
- if ( ! empty( $_REQUEST[ $search_query_arg ] ) ) {
239
- $search_terms_default = stripslashes( $_REQUEST[ $search_query_arg ] );
240
- }
241
-
242
- /*
243
- * Parse Args.
244
- */
245
-
246
- // Note: any params used for filtering can be a single value, or multiple
247
- // values comma separated.
248
- $r = bp_parse_args( $args, array(
249
- 'display_comments' => 'threaded', // False for none, stream/threaded - show comments in the stream or threaded under items.
250
- 'include' => $include, // Pass an activity_id or string of IDs comma-separated.
251
- 'exclude' => false, // Pass an activity_id or string of IDs comma-separated.
252
- 'in' => false, // Comma-separated list or array of activity IDs among which to search.
253
- 'sort' => 'DESC', // Sort DESC or ASC.
254
- 'page' => 1, // Which page to load.
255
- 'per_page' => 20, // Number of items per page.
256
- 'page_arg' => 'acpage', // See https://buddypress.trac.wordpress.org/ticket/3679.
257
- 'max' => false, // Max number to return.
258
- 'fields' => 'all',
259
- 'count_total' => false,
260
- 'show_hidden' => $show_hidden, // Show activity items that are hidden site-wide?
261
- 'spam' => 'ham_only', // Hide spammed items.
262
-
263
- // Scope - pre-built activity filters for a user (friends/groups/favorites/mentions).
264
- 'scope' => $scope,
265
-
266
- // Filtering
267
- 'user_id' => $user_id, // user_id to filter on.
268
- 'object' => $object, // Object to filter on e.g. groups, profile, status, friends.
269
- 'action' => false, // Action to filter on e.g. activity_update, new_forum_post, profile_updated.
270
- 'primary_id' => $primary_id, // Object ID to filter on e.g. a group_id or forum_id or blog_id etc.
271
- 'secondary_id' => false, // Secondary object ID to filter on e.g. a post_id.
272
- 'offset' => false, // Return only items >= this ID.
273
- 'since' => false, // Return only items recorded since this Y-m-d H:i:s date.
274
-
275
- 'meta_query' => false, // Filter on activity meta. See WP_Meta_Query for format.
276
- 'date_query' => false, // Filter by date. See first parameter of WP_Date_Query for format.
277
- 'filter_query' => false, // Advanced filtering. See BP_Activity_Query for format.
278
-
279
- // Searching.
280
- 'search_terms' => $search_terms_default,
281
- 'update_meta_cache' => true,
282
- ), 'has_activities' );
283
-
284
- /*
285
- * Smart Overrides.
286
- */
287
-
288
- // Translate various values for 'display_comments'
289
- // This allows disabling comments via ?display_comments=0
290
- // or =none or =false. Final true is a strict type check. See #5029.
291
- if ( in_array( $r['display_comments'], array( 0, '0', 'none', 'false' ), true ) ) {
292
- $r['display_comments'] = false;
293
- }
294
-
295
- // Ignore pagination if an offset is passed.
296
- if ( ! empty( $r['offset'] ) ) {
297
- $r['page'] = 0;
298
- }
299
-
300
- // Search terms.
301
- if ( ! empty( $_REQUEST['s'] ) && empty( $r['search_terms'] ) ) {
302
- $r['search_terms'] = $_REQUEST['s'];
303
- }
304
-
305
- // Do not exceed the maximum per page.
306
- if ( ! empty( $r['max'] ) && ( (int) $r['per_page'] > (int) $r['max'] ) ) {
307
- $r['per_page'] = $r['max'];
308
- }
309
-
310
- /**
311
- * Filters whether BuddyPress should enable afilter support.
312
- *
313
- * Support for basic filters in earlier BP versions is disabled by default.
314
- * To enable, put add_filter( 'bp_activity_enable_afilter_support', '__return_true' );
315
- * into bp-custom.php or your theme's functions.php.
316
- *
317
- * @since 1.6.0
318
- *
319
- * @param bool $value True if BuddyPress should enable afilter support.
320
- */
321
- if ( isset( $_GET['afilter'] ) && apply_filters( 'bp_activity_enable_afilter_support', false ) ) {
322
- $r['filter'] = array(
323
- 'object' => $_GET['afilter']
324
- );
325
- } elseif ( ! empty( $r['user_id'] ) || ! empty( $r['object'] ) || ! empty( $r['action'] ) || ! empty( $r['primary_id'] ) || ! empty( $r['secondary_id'] ) || ! empty( $r['offset'] ) || ! empty( $r['since'] ) ) {
326
- $r['filter'] = array(
327
- 'user_id' => $r['user_id'],
328
- 'object' => $r['object'],
329
- 'action' => $r['action'],
330
- 'primary_id' => $r['primary_id'],
331
- 'secondary_id' => $r['secondary_id'],
332
- 'offset' => $r['offset'],
333
- 'since' => $r['since']
334
- );
335
- } else {
336
- $r['filter'] = false;
337
- }
338
-
339
- // If specific activity items have been requested, override the $hide_spam
340
- // argument. This prevents backpat errors with AJAX.
341
- if ( ! empty( $r['include'] ) && ( 'ham_only' === $r['spam'] ) ) {
342
- $r['spam'] = 'all';
343
- }
344
-
345
- /*
346
- * Query
347
- */
348
-
349
- $activities_template = new BP_Activity_Template( $r );
350
-
351
- /**
352
- * Filters whether or not there are activity items to display.
353
- *
354
- * @since 1.1.0
355
- *
356
- * @param bool $value Whether or not there are activity items to display.
357
- * @param string $activities_template Current activities template being used.
358
- * @param array $r Array of arguments passed into the BP_Activity_Template class.
359
- */
360
- return apply_filters( 'bp_has_activities', $activities_template->has_activities(), $activities_template, $r );
361
- }
362
-
363
- /**
364
- * Determine if there are still activities left in the loop.
365
- *
366
- * @since 1.0.0
367
- *
368
- * @global object $activities_template {@link BP_Activity_Template}
369
- *
370
- * @return bool Returns true when activities are found.
371
- */
372
- function bp_activities() {
373
- global $activities_template;
374
- return $activities_template->user_activities();
375
- }
376
-
377
- /**
378
- * Get the current activity object in the loop.
379
- *
380
- * @since 1.0.0
381
- *
382
- * @global object $activities_template {@link BP_Activity_Template}
383
- *
384
- * @return object The current activity within the loop.
385
- */
386
- function bp_the_activity() {
387
- global $activities_template;
388
- return $activities_template->the_activity();
389
- }
390
-
391
- /**
392
- * Output the URL for the Load More link.
393
- *
394
- * @since 2.1.0
395
- */
396
- function bp_activity_load_more_link() {
397
- echo esc_url( bp_get_activity_load_more_link() );
398
- }
399
- /**
400
- * Get the URL for the Load More link.
401
- *
402
- * @since 2.1.0
403
- *
404
- * @return string $link
405
- */
406
- function bp_get_activity_load_more_link() {
407
- global $activities_template;
408
-
409
- $url = bp_get_requested_url();
410
- $link = add_query_arg( $activities_template->pag_arg, $activities_template->pag_page + 1, $url );
411
-
412
- /**
413
- * Filters the Load More link URL.
414
- *
415
- * @since 2.1.0
416
- *
417
- * @param string $link The "Load More" link URL with appropriate query args.
418
- * @param string $url The original URL.
419
- * @param object $activities_template The activity template loop global.
420
- */
421
- return apply_filters( 'bp_get_activity_load_more_link', $link, $url, $activities_template );
422
- }
423
-
424
- /**
425
- * Output the activity pagination count.
426
- *
427
- * @since 1.0.0
428
- *
429
- * @global object $activities_template {@link BP_Activity_Template}
430
- */
431
- function bp_activity_pagination_count() {
432
- echo bp_get_activity_pagination_count();
433
- }
434
-
435
- /**
436
- * Return the activity pagination count.
437
- *
438
- * @since 1.2.0
439
- *
440
- * @global object $activities_template {@link BP_Activity_Template}
441
- *
442
- * @return string The pagination text.
443
- */
444
- function bp_get_activity_pagination_count() {
445
- global $activities_template;
446
-
447
- $start_num = intval( ( $activities_template->pag_page - 1 ) * $activities_template->pag_num ) + 1;
448
- $from_num = bp_core_number_format( $start_num );
449
- $to_num = bp_core_number_format( ( $start_num + ( $activities_template->pag_num - 1 ) > $activities_template->total_activity_count ) ? $activities_template->total_activity_count : $start_num + ( $activities_template->pag_num - 1 ) );
450
- $total = bp_core_number_format( $activities_template->total_activity_count );
451
-
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
-
458
- return $message;
459
- }
460
-
461
- /**
462
- * Output the activity pagination links.
463
- *
464
- * @since 1.0.0
465
- *
466
- */
467
- function bp_activity_pagination_links() {
468
- echo bp_get_activity_pagination_links();
469
- }
470
-
471
- /**
472
- * Return the activity pagination links.
473
- *
474
- * @since 1.0.0
475
- *
476
- * @global object $activities_template {@link BP_Activity_Template}
477
- *
478
- * @return string The pagination links.
479
- */
480
- function bp_get_activity_pagination_links() {
481
- global $activities_template;
482
-
483
- /**
484
- * Filters the activity pagination link output.
485
- *
486
- * @since 1.0.0
487
- *
488
- * @param string $pag_links Output for the activity pagination links.
489
- */
490
- return apply_filters( 'bp_get_activity_pagination_links', $activities_template->pag_links );
491
- }
492
-
493
- /**
494
- * Return true when there are more activity items to be shown than currently appear.
495
- *
496
- * @since 1.5.0
497
- *
498
- * @global object $activities_template {@link BP_Activity_Template}
499
- *
500
- * @return bool $has_more_items True if more items, false if not.
501
- */
502
- function bp_activity_has_more_items() {
503
- global $activities_template;
504
-
505
- if ( ! empty( $activities_template->has_more_items ) ) {
506
- $has_more_items = true;
507
- } else {
508
- $remaining_pages = 0;
509
-
510
- if ( ! empty( $activities_template->pag_page ) ) {
511
- $remaining_pages = floor( ( $activities_template->total_activity_count - 1 ) / ( $activities_template->pag_num * $activities_template->pag_page ) );
512
- }
513
-
514
- $has_more_items = (int) $remaining_pages > 0;
515
- }
516
-
517
- /**
518
- * Filters whether there are more activity items to display.
519
- *
520
- * @since 1.5.0
521
- *
522
- * @param bool $has_more_items Whether or not there are more activity items to display.
523
- */
524
- return apply_filters( 'bp_activity_has_more_items', $has_more_items );
525
- }
526
-
527
- /**
528
- * Output the activity count.
529
- *
530
- * @since 1.2.0
531
- *
532
- */
533
- function bp_activity_count() {
534
- echo bp_get_activity_count();
535
- }
536
-
537
- /**
538
- * Return the activity count.
539
- *
540
- * @since 1.2.0
541
- *
542
- * @global object $activities_template {@link BP_Activity_Template}
543
- *
544
- * @return int The activity count.
545
- */
546
- function bp_get_activity_count() {
547
- global $activities_template;
548
-
549
- /**
550
- * Filters the activity count for the activity template.
551
- *
552
- * @since 1.2.0
553
- *
554
- * @param int $activity_count The count for total activity.
555
- */
556
- return apply_filters( 'bp_get_activity_count', (int) $activities_template->activity_count );
557
- }
558
-
559
- /**
560
- * Output the number of activities per page.
561
- *
562
- * @since 1.2.0
563
- *
564
- */
565
- function bp_activity_per_page() {
566
- echo bp_get_activity_per_page();
567
- }
568
-
569
- /**
570
- * Return the number of activities per page.
571
- *
572
- * @since 1.2.0
573
- *
574
- * @global object $activities_template {@link BP_Activity_Template}
575
- *
576
- * @return int The activities per page.
577
- */
578
- function bp_get_activity_per_page() {
579
- global $activities_template;
580
-
581
- /**
582
- * Filters the activity posts per page value.
583
- *
584
- * @since 1.2.0
585
- *
586
- * @param int $pag_num How many post should be displayed for pagination.
587
- */
588
- return apply_filters( 'bp_get_activity_per_page', (int) $activities_template->pag_num );
589
- }
590
-
591
- /**
592
- * Output the activities title.
593
- *
594
- * @since 1.0.0
595
- *
596
- * @todo Deprecate.
597
- */
598
- function bp_activities_title() {
599
- echo bp_get_activities_title();
600
- }
601
-
602
- /**
603
- * Return the activities title.
604
- *
605
- * @since 1.0.0
606
- *
607
- * @global string $bp_activity_title
608
- * @todo Deprecate.
609
- *
610
- * @return string The activities title.
611
- */
612
- function bp_get_activities_title() {
613
- global $bp_activity_title;
614
-
615
- /**
616
- * Filters the activities title for the activity template.
617
- *
618
- * @since 1.0.0
619
- *
620
- * @param string $bp_activity_title The title to be displayed.
621
- */
622
- return apply_filters( 'bp_get_activities_title', $bp_activity_title );
623
- }
624
-
625
- /**
626
- * {@internal Missing Description}
627
- *
628
- * @since 1.0.0
629
- *
630
- * @todo Deprecate.
631
- */
632
- function bp_activities_no_activity() {
633
- echo bp_get_activities_no_activity();
634
- }
635
-
636
- /**
637
- * {@internal Missing Description}
638
- *
639
- * @since 1.0.0
640
- *
641
- * @global string $bp_activity_no_activity
642
- * @todo Deprecate.
643
- *
644
- * @return string
645
- */
646
- function bp_get_activities_no_activity() {
647
- global $bp_activity_no_activity;
648
-
649
- /**
650
- * Filters the text used when there is no activity to display.
651
- *
652
- * @since 1.0.0
653
- *
654
- * @param string $bp_activity_no_activity Text to display for no activity.
655
- */
656
- return apply_filters( 'bp_get_activities_no_activity', $bp_activity_no_activity );
657
- }
658
-
659
- /**
660
- * Output the activity ID.
661
- *
662
- * @since 1.2.0
663
- *
664
- */
665
- function bp_activity_id() {
666
- echo bp_get_activity_id();
667
- }
668
-
669
- /**
670
- * Return the activity ID.
671
- *
672
- * @since 1.2.0
673
- *
674
- * @global object $activities_template {@link BP_Activity_Template}
675
- *
676
- * @return int The activity ID.
677
- */
678
- function bp_get_activity_id() {
679
- global $activities_template;
680
-
681
- /**
682
- * Filters the activity ID being displayed.
683
- *
684
- * @since 1.2.0
685
- *
686
- * @param int $id The activity ID.
687
- */
688
- return apply_filters( 'bp_get_activity_id', $activities_template->activity->id );
689
- }
690
-
691
- /**
692
- * Output the activity item ID.
693
- *
694
- * @since 1.2.0
695
- *
696
- */
697
- function bp_activity_item_id() {
698
- echo bp_get_activity_item_id();
699
- }
700
-
701
- /**
702
- * Return the activity item ID.
703
- *
704
- * @since 1.2.0
705
- *
706
- * @global object $activities_template {@link BP_Activity_Template}
707
- *
708
- * @return int The activity item ID.
709
- */
710
- function bp_get_activity_item_id() {
711
- global $activities_template;
712
-
713
- /**
714
- * Filters the activity item ID being displayed.
715
- *
716
- * @since 1.2.0
717
- *
718
- * @param int $item_id The activity item ID.
719
- */
720
- return apply_filters( 'bp_get_activity_item_id', $activities_template->activity->item_id );
721
- }
722
-
723
- /**
724
- * Output the activity secondary item ID.
725
- *
726
- * @since 1.2.0
727
- *
728
- */
729
- function bp_activity_secondary_item_id() {
730
- echo bp_get_activity_secondary_item_id();
731
- }
732
-
733
- /**
734
- * Return the activity secondary item ID.
735
- *
736
- * @since 1.2.0
737
- *
738
- * @global object $activities_template {@link BP_Activity_Template}
739
- *
740
- * @return int The activity secondary item ID.
741
- */
742
- function bp_get_activity_secondary_item_id() {
743
- global $activities_template;
744
-
745
- /**
746
- * Filters the activity secondary item ID being displayed.
747
- *
748
- * @since 1.2.0
749
- *
750
- * @param int $secondary_item_id The activity secondary item ID.
751
- */
752
- return apply_filters( 'bp_get_activity_secondary_item_id', $activities_template->activity->secondary_item_id );
753
- }
754
-
755
- /**
756
- * Output the date the activity was recorded.
757
- *
758
- * @since 1.2.0
759
- *
760
- */
761
- function bp_activity_date_recorded() {
762
- echo bp_get_activity_date_recorded();
763
- }
764
-
765
- /**
766
- * Return the date the activity was recorded.
767
- *
768
- * @since 1.2.0
769
- *
770
- * @global object $activities_template {@link BP_Activity_Template}
771
- *
772
- * @return string The date the activity was recorded.
773
- */
774
- function bp_get_activity_date_recorded() {
775
- global $activities_template;
776
-
777
- /**
778
- * Filters the date the activity was recorded.
779
- *
780
- * @since 1.2.0
781
- *
782
- * @param int $date_recorded The activity's date.
783
- */
784
- return apply_filters( 'bp_get_activity_date_recorded', $activities_template->activity->date_recorded );
785
- }
786
-
787
- /**
788
- * Output the display name of the member who posted the activity.
789
- *
790
- * @since 2.1.0
791
- *
792
- */
793
- function bp_activity_member_display_name() {
794
- echo bp_get_activity_member_display_name();
795
- }
796
-
797
- /**
798
- * Return the display name of the member who posted the activity.
799
- *
800
- * @since 2.1.0
801
- *
802
- * @global object $activities_template {@link BP_Activity_Template}
803
- *
804
- * @return string The date the activity was recorded.
805
- */
806
- function bp_get_activity_member_display_name() {
807
- global $activities_template;
808
-
809
- $retval = isset( $activities_template->activity->display_name )
810
- ? $activities_template->activity->display_name
811
- : '';
812
-
813
- /**
814
- * Filters the display name of the member who posted the activity.
815
- *
816
- * @since 2.1.0
817
- *
818
- * @param int $retval Display name for the member who posted.
819
- */
820
- return apply_filters( 'bp_get_activity_member_display_name', $retval );
821
- }
822
-
823
- /**
824
- * Output the activity object name.
825
- *
826
- * @since 1.2.0
827
- *
828
- */
829
- function bp_activity_object_name() {
830
- echo bp_get_activity_object_name();
831
- }
832
-
833
- /**
834
- * Return the activity object name.
835
- *
836
- * @since 1.2.0
837
- *
838
- * @global object $activities_template {@link BP_Activity_Template}
839
- *
840
- * @return string The activity object name.
841
- */
842
- function bp_get_activity_object_name() {
843
- global $activities_template;
844
-
845
- /**
846
- * Filters the activity object name.
847
- *
848
- * @since 1.2.0
849
- *
850
- * @param string $activity_component The activity object name.
851
- */
852
- return apply_filters( 'bp_get_activity_object_name', $activities_template->activity->component );
853
- }
854
-
855
- /**
856
- * Output the activity type.
857
- *
858
- * @since 1.2.0
859
- *
860
- */
861
- function bp_activity_type() {
862
- echo bp_get_activity_type();
863
- }
864
-
865
- /**
866
- * Return the activity type.
867
- *
868
- * @since 1.2.0
869
- *
870
- * @global object $activities_template {@link BP_Activity_Template}
871
- *
872
- * @return string The activity type.
873
- */
874
- function bp_get_activity_type() {
875
- global $activities_template;
876
-
877
- /**
878
- * Filters the activity type.
879
- *
880
- * @since 1.2.0
881
- *
882
- * @param string $activity_type The activity type.
883
- */
884
- return apply_filters( 'bp_get_activity_type', $activities_template->activity->type );
885
- }
886
-
887
- /**
888
- * Output the activity action name.
889
- *
890
- * Just a wrapper for bp_activity_type().
891
- *
892
- * @since 1.2.0
893
- * @deprecated 1.5.0
894
- *
895
- * @todo Properly deprecate in favor of bp_activity_type() and
896
- * remove redundant echo
897
- *
898
- */
899
- function bp_activity_action_name() { echo bp_activity_type(); }
900
-
901
- /**
902
- * Return the activity type.
903
- *
904
- * Just a wrapper for bp_get_activity_type().
905
- *
906
- * @since 1.2.0
907
- * @deprecated 1.5.0
908
- *
909
- * @todo Properly deprecate in favor of bp_get_activity_type().
910
- *
911
- *
912
- * @return string The activity type.
913
- */
914
- function bp_get_activity_action_name() { return bp_get_activity_type(); }
915
-
916
- /**
917
- * Output the activity user ID.
918
- *
919
- * @since 1.1.0
920
- *
921
- */
922
- function bp_activity_user_id() {
923
- echo bp_get_activity_user_id();
924
- }
925
-
926
- /**
927
- * Return the activity user ID.
928
- *
929
- * @since 1.1.0
930
- *
931
- * @global object $activities_template {@link BP_Activity_Template}
932
- *
933
- * @return int The activity user ID.
934
- */
935
- function bp_get_activity_user_id() {
936
- global $activities_template;
937
-
938
- /**
939
- * Filters the activity user ID.
940
- *
941
- * @since 1.1.0
942
- *
943
- * @param int $user_id The activity user ID.
944
- */
945
- return apply_filters( 'bp_get_activity_user_id', $activities_template->activity->user_id );
946
- }
947
-
948
- /**
949
- * Output the activity user link.
950
- *
951
- * @since 1.2.0
952
- *
953
- */
954
- function bp_activity_user_link() {
955
- echo bp_get_activity_user_link();
956
- }
957
-
958
- /**
959
- * Return the activity user link.
960
- *
961
- * @since 1.2.0
962
- *
963
- * @global object $activities_template {@link BP_Activity_Template}
964
- *
965
- * @return string $link The activity user link.
966
- */
967
- function bp_get_activity_user_link() {
968
- global $activities_template;
969
-
970
- if ( empty( $activities_template->activity->user_id ) || empty( $activities_template->activity->user_nicename ) || empty( $activities_template->activity->user_login ) ) {
971
- $link = $activities_template->activity->primary_link;
972
- } else {
973
- $link = bp_core_get_user_domain( $activities_template->activity->user_id, $activities_template->activity->user_nicename, $activities_template->activity->user_login );
974
- }
975
-
976
- /**
977
- * Filters the activity user link.
978
- *
979
- * @since 1.2.0
980
- *
981
- * @param string $link The activity user link.
982
- */
983
- return apply_filters( 'bp_get_activity_user_link', $link );
984
- }
985
-
986
- /**
987
- * Output the avatar of the user that performed the action.
988
- *
989
- * @since 1.1.0
990
- *
991
- * @see bp_get_activity_avatar() for description of arguments.
992
- *
993
- * @param array|string $args See {@link bp_get_activity_avatar()} for description.
994
- */
995
- function bp_activity_avatar( $args = '' ) {
996
- echo bp_get_activity_avatar( $args );
997
- }
998
- /**
999
- * Return the avatar of the user that performed the action.
1000
- *
1001
- * @since 1.1.0
1002
- *
1003
- * @see bp_core_fetch_avatar() For a description of the arguments.
1004
- * @global object $activities_template {@link BP_Activity_Template}
1005
- *
1006
- * @param array|string $args {
1007
- * Arguments are listed here with an explanation of their defaults.
1008
- * For more information about the arguments, see
1009
- * {@link bp_core_fetch_avatar()}.
1010
- * @type string $alt Default: 'Profile picture of [user name]' if
1011
- * activity user name is available, otherwise 'Profile picture'.
1012
- * @type string $class Default: 'avatar'.
1013
- * @type string|bool $email Default: Email of the activity's
1014
- * associated user, if available. Otherwise false.
1015
- * @type string $type Default: 'full' when viewing a single activity
1016
- * permalink page, otherwise 'thumb'.
1017
- * @type int|bool $user_id Default: ID of the activity's user.
1018
- * }
1019
- * @return string User avatar string.
1020
- */
1021
- function bp_get_activity_avatar( $args = '' ) {
1022
- global $activities_template;
1023
-
1024
- $bp = buddypress();
1025
-
1026
- // On activity permalink pages, default to the full-size avatar.
1027
- $type_default = bp_is_single_activity() ? 'full' : 'thumb';
1028
-
1029
- // Within the activity comment loop, the current activity should be set
1030
- // to current_comment. Otherwise, just use activity.
1031
- $current_activity_item = isset( $activities_template->activity->current_comment ) ? $activities_template->activity->current_comment : $activities_template->activity;
1032
-
1033
- // Activity user display name.
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,
1041
- 'class' => 'avatar',
1042
- 'email' => false,
1043
- 'type' => $type_default,
1044
- 'user_id' => false
1045
- );
1046
-
1047
- $r = wp_parse_args( $args, $defaults );
1048
- extract( $r, EXTR_SKIP );
1049
-
1050
- if ( !isset( $height ) && !isset( $width ) ) {
1051
-
1052
- // Backpat.
1053
- if ( isset( $bp->avatar->full->height ) || isset( $bp->avatar->thumb->height ) ) {
1054
- $height = ( 'full' == $type ) ? $bp->avatar->full->height : $bp->avatar->thumb->height;
1055
- } else {
1056
- $height = 20;
1057
- }
1058
-
1059
- // Backpat.
1060
- if ( isset( $bp->avatar->full->width ) || isset( $bp->avatar->thumb->width ) ) {
1061
- $width = ( 'full' == $type ) ? $bp->avatar->full->width : $bp->avatar->thumb->width;
1062
- } else {
1063
- $width = 20;
1064
- }
1065
- }
1066
-
1067
- /**
1068
- * Filters the activity avatar object based on current activity item component.
1069
- *
1070
- * This is a variable filter dependent on the component used.
1071
- * Possible hooks are bp_get_activity_avatar_object_blog,
1072
- * bp_get_activity_avatar_object_group, and bp_get_activity_avatar_object_user.
1073
- *
1074
- * @since 1.1.0
1075
- *
1076
- * @param string $component Component being displayed.
1077
- */
1078
- $object = apply_filters( 'bp_get_activity_avatar_object_' . $current_activity_item->component, 'user' );
1079
- $item_id = !empty( $user_id ) ? $user_id : $current_activity_item->user_id;
1080
-
1081
- /**
1082
- * Filters the activity avatar item ID.
1083
- *
1084
- * @since 1.2.10
1085
- *
1086
- * @param int $item_id Item ID for the activity avatar.
1087
- */
1088
- $item_id = apply_filters( 'bp_get_activity_avatar_item_id', $item_id );
1089
-
1090
- // If this is a user object pass the users' email address for Gravatar so we don't have to prefetch it.
1091
- if ( 'user' == $object && empty( $user_id ) && empty( $email ) && isset( $current_activity_item->user_email ) ) {
1092
- $email = $current_activity_item->user_email;
1093
- }
1094
-
1095
- /**
1096
- * Filters the value returned by bp_core_fetch_avatar.
1097
- *
1098
- * @since 1.1.3
1099
- *
1100
- * @param array $value HTML image element containing the activity avatar.
1101
- */
1102
- return apply_filters( 'bp_get_activity_avatar', bp_core_fetch_avatar( array(
1103
- 'item_id' => $item_id,
1104
- 'object' => $object,
1105
- 'type' => $type,
1106
- 'alt' => $alt,
1107
- 'class' => $class,
1108
- 'width' => $width,
1109
- 'height' => $height,
1110
- 'email' => $email
1111
- ) ) );
1112
- }
1113
-
1114
- /**
1115
- * Output the avatar of the object that action was performed on.
1116
- *
1117
- * @since 1.2.0
1118
- *
1119
- * @see bp_get_activity_secondary_avatar() for description of arguments.
1120
- *
1121
- * @param array|string $args See {@link bp_get_activity_secondary_avatar} for description.
1122
- */
1123
- function bp_activity_secondary_avatar( $args = '' ) {
1124
- echo bp_get_activity_secondary_avatar( $args );
1125
- }
1126
-
1127
- /**
1128
- * Return the avatar of the object that action was performed on.
1129
- *
1130
- * @since 1.2.0
1131
- *
1132
- * @see bp_core_fetch_avatar() for description of arguments.
1133
- * @global object $activities_template {@link BP_Activity_Template}
1134
- *
1135
- * @param array|string $args {
1136
- * For a complete description of arguments, see {@link bp_core_fetch_avatar()}.
1137
- * @type string $alt Default value varies based on current activity
1138
- * item component.
1139
- * @type string $type Default: 'full' when viewing a single activity
1140
- * permalink page, otherwise 'thumb'.
1141
- * @type string $class Default: 'avatar'.
1142
- * @type string|bool $email Default: email of the activity's user.
1143
- * @type int|bool $user_id Default: ID of the activity's user.
1144
- * }
1145
- * @return string The secondary avatar.
1146
- */
1147
- function bp_get_activity_secondary_avatar( $args = '' ) {
1148
- global $activities_template;
1149
-
1150
- $r = wp_parse_args( $args, array(
1151
- 'alt' => '',
1152
- 'type' => 'thumb',
1153
- 'width' => 20,
1154
- 'height' => 20,
1155
- 'class' => 'avatar',
1156
- 'link_class' => '',
1157
- 'linked' => true,
1158
- 'email' => false
1159
- ) );
1160
- extract( $r, EXTR_SKIP );
1161
-
1162
- // Set item_id and object (default to user).
1163
- switch ( $activities_template->activity->component ) {
1164
- case 'groups' :
1165
- if ( bp_disable_group_avatar_uploads() ) {
1166
- return false;
1167
- }
1168
-
1169
- $object = 'group';
1170
- $item_id = $activities_template->activity->item_id;
1171
- $link = '';
1172
- $name = '';
1173
-
1174
- // Only if groups is active.
1175
- if ( bp_is_active( 'groups' ) ) {
1176
- $group = groups_get_group( $item_id );
1177
- $link = bp_get_group_permalink( $group );
1178
- $name = $group->name;
1179
- }
1180
-
1181
- if ( empty( $alt ) ) {
1182
- $alt = __( 'Group logo', 'buddypress' );
1183
-
1184
- if ( ! empty( $name ) ) {
1185
- $alt = sprintf( __( 'Group logo of %s', 'buddypress' ), $name );
1186
- }
1187
- }
1188
-
1189
- break;
1190
- case 'blogs' :
1191
- $object = 'blog';
1192
- $item_id = $activities_template->activity->item_id;
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
-
1199
- break;
1200
- case 'friends' :
1201
- $object = 'user';
1202
- $item_id = $activities_template->activity->secondary_item_id;
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
-
1209
- break;
1210
- default :
1211
- $object = 'user';
1212
- $item_id = $activities_template->activity->user_id;
1213
- $email = $activities_template->activity->user_email;
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
-
1220
- break;
1221
- }
1222
-
1223
- /**
1224
- * Filters the activity secondary avatar object based on current activity item component.
1225
- *
1226
- * This is a variable filter dependent on the component used. Possible hooks are
1227
- * bp_get_activity_secondary_avatar_object_blog, bp_get_activity_secondary_avatar_object_group,
1228
- * and bp_get_activity_secondary_avatar_object_user.
1229
- *
1230
- * @since 1.2.10
1231
- *
1232
- * @param string $object Component being displayed.
1233
- */
1234
- $object = apply_filters( 'bp_get_activity_secondary_avatar_object_' . $activities_template->activity->component, $object );
1235
-
1236
- /**
1237
- * Filters the activity secondary avatar item ID.
1238
- *
1239
- * @since 1.2.10
1240
- *
1241
- * @param int $item_id ID for the secondary avatar item.
1242
- */
1243
- $item_id = apply_filters( 'bp_get_activity_secondary_avatar_item_id', $item_id );
1244
-
1245
- // If we have no item_id or object, there is no avatar to display.
1246
- if ( empty( $item_id ) || empty( $object ) ) {
1247
- return false;
1248
- }
1249
-
1250
- // Get the avatar.
1251
- $avatar = bp_core_fetch_avatar( array(
1252
- 'item_id' => $item_id,
1253
- 'object' => $object,
1254
- 'type' => $type,
1255
- 'alt' => $alt,
1256
- 'class' => $class,
1257
- 'width' => $width,
1258
- 'height' => $height,
1259
- 'email' => $email
1260
- ) );
1261
-
1262
- if ( !empty( $linked ) ) {
1263
-
1264
- /**
1265
- * Filters the secondary avatar link for current activity.
1266
- *
1267
- * @since 1.7.0
1268
- *
1269
- * @param string $link Link to wrap the avatar image in.
1270
- * @param string $component Activity component being acted on.
1271
- */
1272
- $link = apply_filters( 'bp_get_activity_secondary_avatar_link', $link, $activities_template->activity->component );
1273
-
1274
- /**
1275
- * Filters the determined avatar for the secondary activity item.
1276
- *
1277
- * @since 1.2.10
1278
- *
1279
- * @param string $avatar Formatted HTML <img> element, or raw avatar URL.
1280
- */
1281
- $avatar = apply_filters( 'bp_get_activity_secondary_avatar', $avatar );
1282
-
1283
- return sprintf( '<a href="%s" class="%s">%s</a>',
1284
- $link,
1285
- $link_class,
1286
- $avatar
1287
- );
1288
- }
1289
-
1290
- /** This filter is documented in bp-activity/bp-activity-template.php */
1291
- return apply_filters( 'bp_get_activity_secondary_avatar', $avatar );
1292
- }
1293
-
1294
- /**
1295
- * Output the activity action.
1296
- *
1297
- * @since 1.2.0
1298
- *
1299
- * @param array $args See bp_get_activity_action().
1300
- */
1301
- function bp_activity_action( $args = array() ) {
1302
- echo bp_get_activity_action( $args );
1303
- }
1304
-
1305
- /**
1306
- * Return the activity action.
1307
- *
1308
- * @since 1.2.0
1309
- *
1310
- * @global object $activities_template {@link BP_Activity_Template}
1311
- *
1312
- * @param array $args {
1313
- * @type bool $no_timestamp Whether to exclude the timestamp.
1314
- * }
1315
- *
1316
- * @return string The activity action.
1317
- */
1318
- function bp_get_activity_action( $args = array() ) {
1319
- global $activities_template;
1320
-
1321
- $r = wp_parse_args( $args, array(
1322
- 'no_timestamp' => false,
1323
- ) );
1324
-
1325
- /**
1326
- * Filters the activity action before the action is inserted as meta.
1327
- *
1328
- * @since 1.2.10
1329
- *
1330
- * @param array $value Array containing the current action, the current activity, and the $args array passed into the function.
1331
- */
1332
- $action = apply_filters_ref_array( 'bp_get_activity_action_pre_meta', array(
1333
- $activities_template->activity->action,
1334
- &$activities_template->activity,
1335
- $r
1336
- ) );
1337
-
1338
- // Prepend the activity action meta (link, time since, etc...).
1339
- if ( ! empty( $action ) && empty( $r['no_timestamp'] ) ) {
1340
- $action = bp_insert_activity_meta( $action );
1341
- }
1342
-
1343
- /**
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,
1352
- &$activities_template->activity,
1353
- $r
1354
- ) );
1355
- }
1356
-
1357
- /**
1358
- * Output the activity content body.
1359
- *
1360
- * @since 1.2.0
1361
- *
1362
- */
1363
- function bp_activity_content_body() {
1364
- echo bp_get_activity_content_body();
1365
- }
1366
-
1367
- /**
1368
- * Return the activity content body.
1369
- *
1370
- * @since 1.2.0
1371
- *
1372
- * @global object $activities_template {@link BP_Activity_Template}
1373
- *
1374
- * @return string The activity content body.
1375
- */
1376
- function bp_get_activity_content_body() {
1377
- global $activities_template;
1378
-
1379
- // Backwards compatibility if action is not being used.
1380
- if ( empty( $activities_template->activity->action ) && ! empty( $activities_template->activity->content ) ) {
1381
- $activities_template->activity->content = bp_insert_activity_meta( $activities_template->activity->content );
1382
- }
1383
-
1384
- /**
1385
- * Filters the activity content body.
1386
- *
1387
- * @since 1.2.0
1388
- *
1389
- * @param string $content Content body.
1390
- * @param object $activity Activity object. Passed by reference.
1391
- */
1392
- return apply_filters_ref_array( 'bp_get_activity_content_body', array( $activities_template->activity->content, &$activities_template->activity ) );
1393
- }
1394
-
1395
- /**
1396
- * Does the activity have content?
1397
- *
1398
- * @since 1.2.0
1399
- *
1400
- * @global object $activities_template {@link BP_Activity_Template}
1401
- *
1402
- * @return bool True if activity has content, false otherwise.
1403
- */
1404
- function bp_activity_has_content() {
1405
- global $activities_template;
1406
-
1407
- if ( ! empty( $activities_template->activity->content ) ) {
1408
- return true;
1409
- }
1410
-
1411
- return false;
1412
- }
1413
-
1414
- /**
1415
- * Output the activity content.
1416
- *
1417
- * @since 1.0.0
1418
- * @deprecated 1.5.0
1419
- *
1420
- * @todo properly deprecate this function.
1421
- *
1422
- */
1423
- function bp_activity_content() {
1424
- echo bp_get_activity_content();
1425
- }
1426
-
1427
- /**
1428
- * Return the activity content.
1429
- *
1430
- * @since 1.0.0
1431
- * @deprecated 1.5.0
1432
- *
1433
- * @todo properly deprecate this function.
1434
- *
1435
- *
1436
- * @return string The activity content.
1437
- */
1438
- function bp_get_activity_content() {
1439
-
1440
- /**
1441
- * If you want to filter activity update content, please use
1442
- * the filter 'bp_get_activity_content_body'.
1443
- *
1444
- * This function is mainly for backwards compatibility.
1445
- */
1446
- $content = bp_get_activity_action() . ' ' . bp_get_activity_content_body();
1447
- return apply_filters( 'bp_get_activity_content', $content );
1448
- }
1449
-
1450
- /**
1451
- * Attach metadata about an activity item to the activity content.
1452
- *
1453
- * This metadata includes the time since the item was posted (which will appear
1454
- * as a link to the item's permalink).
1455
- *
1456
- * @since 1.2.0
1457
- *
1458
- * @global object $activities_template {@link BP_Activity_Template}
1459
- *
1460
- * @param string $content The activity content.
1461
- * @return string The activity content with the metadata string attached.
1462
- */
1463
- function bp_insert_activity_meta( $content = '' ) {
1464
- global $activities_template;
1465
-
1466
- // Strip any legacy time since placeholders from BP 1.0-1.1.
1467
- $new_content = str_replace( '<span class="time-since">%s</span>', '', $content );
1468
-
1469
- // Get the time since this activity was recorded.
1470
- $date_recorded = bp_core_time_since( $activities_template->activity->date_recorded );
1471
-
1472
- // Set up 'time-since' <span>.
1473
- $time_since = sprintf(
1474
- '<span class="time-since" data-livestamp="%1$s">%2$s</span>',
1475
- bp_core_get_iso8601_date( $activities_template->activity->date_recorded ),
1476
- $date_recorded
1477
- );
1478
-
1479
- /**
1480
- * Filters the activity item time since markup.
1481
- *
1482
- * @since 1.2.0
1483
- *
1484
- * @param array $value Array containing the time since markup and the current activity component.
1485
- */
1486
- $time_since = apply_filters_ref_array( 'bp_activity_time_since', array(
1487
- $time_since,
1488
- &$activities_template->activity
1489
- ) );
1490
-
1491
- // Insert the permalink.
1492
- if ( ! bp_is_single_activity() ) {
1493
-
1494
- // Setup variables for activity meta.
1495
- $activity_permalink = bp_activity_get_permalink( $activities_template->activity->id, $activities_template->activity );
1496
- $activity_meta = sprintf( '%1$s <a href="%2$s" class="view activity-time-since bp-tooltip" data-bp-tooltip="%3$s">%4$s</a>',
1497
- $new_content,
1498
- $activity_permalink,
1499
- esc_attr__( 'View Discussion', 'buddypress' ),
1500
- $time_since
1501
- );
1502
-
1503
- /**
1504
- * Filters the activity permalink to be added to the activity content.
1505
- *
1506
- * @since 1.2.0
1507
- *
1508
- * @param array $value Array containing the html markup for the activity permalink, after being parsed by
1509
- * sprintf and current activity component.
1510
- */
1511
- $new_content = apply_filters_ref_array( 'bp_activity_permalink', array(
1512
- $activity_meta,
1513
- &$activities_template->activity
1514
- ) );
1515
- } else {
1516
- $new_content .= str_pad( $time_since, strlen( $time_since ) + 2, ' ', STR_PAD_BOTH );
1517
- }
1518
-
1519
- /**
1520
- * Filters the activity content after activity metadata has been attached.
1521
- *
1522
- * @since 1.2.0
1523
- *
1524
- * @param string $content Activity content with the activity metadata added.
1525
- */
1526
- return apply_filters( 'bp_insert_activity_meta', $new_content, $content );
1527
- }
1528
-
1529
- /**
1530
- * Determine if the current user can delete an activity item.
1531
- *
1532
- * @since 1.2.0
1533
- *
1534
- * @global object $activities_template {@link BP_Activity_Template}
1535
- *
1536
- * @param false|BP_Activity_Activity $activity Optional. Falls back on the current item in the loop.
1537
- * @return bool True if can delete, false otherwise.
1538
- */
1539
- function bp_activity_user_can_delete( $activity = false ) {
1540
- global $activities_template;
1541
-
1542
- // Try to use current activity if none was passed.
1543
- if ( empty( $activity ) && ! empty( $activities_template->activity ) ) {
1544
- $activity = $activities_template->activity;
1545
- }
1546
-
1547
- // If current_comment is set, we'll use that in place of the main activity.
1548
- if ( isset( $activity->current_comment ) ) {
1549
- $activity = $activity->current_comment;
1550
- }
1551
-
1552
- // Assume the user cannot delete the activity item.
1553
- $can_delete = false;
1554
-
1555
- // Only logged in users can delete activity.
1556
- if ( is_user_logged_in() ) {
1557
-
1558
- // Community moderators can always delete activity (at least for now).
1559
- if ( bp_current_user_can( 'bp_moderate' ) ) {
1560
- $can_delete = true;
1561
- }
1562
-
1563
- // Users are allowed to delete their own activity. This is actually
1564
- // quite powerful, because doing so also deletes all comments to that
1565
- // activity item. We should revisit this eventually.
1566
- if ( isset( $activity->user_id ) && ( $activity->user_id === bp_loggedin_user_id() ) ) {
1567
- $can_delete = true;
1568
- }
1569
-
1570
- // Viewing a single item, and this user is an admin of that item.
1571
- if ( bp_is_single_item() && bp_is_item_admin() ) {
1572
- $can_delete = true;
1573
- }
1574
- }
1575
-
1576
- /**
1577
- * Filters whether the current user can delete an activity item.
1578
- *
1579
- * @since 1.5.0
1580
- *
1581
- * @param bool $can_delete Whether the user can delete the item.
1582
- * @param object $activity Current activity item object.
1583
- */
1584
- return (bool) apply_filters( 'bp_activity_user_can_delete', $can_delete, $activity );
1585
- }
1586
-
1587
- /**
1588
- * Output the activity parent content.
1589
- *
1590
- * @since 1.2.0
1591
- *
1592
- * @see bp_get_activity_parent_content() for a description of arguments.
1593
- *
1594
- * @param array|string $args See {@link bp_get_activity_parent_content} for description.
1595
- */
1596
- function bp_activity_parent_content( $args = '' ) {
1597
- echo bp_get_activity_parent_content($args);
1598
- }
1599
-
1600
- /**
1601
- * Return the activity content.
1602
- *
1603
- * @since 1.2.0
1604
- *
1605
- * @global object $activities_template {@link BP_Activity_Template}
1606
- *
1607
- * @param string $args Unused. Left over from an earlier implementation.
1608
- * @return mixed False on failure, otherwise the activity parent content.
1609
- */
1610
- function bp_get_activity_parent_content( $args = '' ) {
1611
- global $activities_template;
1612
-
1613
- // Bail if no activity on no item ID.
1614
- if ( empty( $activities_template->activity ) || empty( $activities_template->activity->item_id ) ) {
1615
- return false;
1616
- }
1617
-
1618
- // Get the ID of the parent activity content.
1619
- $parent_id = $activities_template->activity->item_id;
1620
-
1621
- // Bail if no parent content.
1622
- if ( empty( $activities_template->activity_parents[ $parent_id ] ) ) {
1623
- return false;
1624
- }
1625
-
1626
- // Bail if no action.
1627
- if ( empty( $activities_template->activity_parents[ $parent_id ]->action ) ) {
1628
- return false;
1629
- }
1630
-
1631
- // Content always includes action.
1632
- $content = $activities_template->activity_parents[ $parent_id ]->action;
1633
-
1634
- // Maybe append activity content, if it exists.
1635
- if ( ! empty( $activities_template->activity_parents[ $parent_id ]->content ) ) {
1636
- $content .= ' ' . $activities_template->activity_parents[ $parent_id ]->content;
1637
- }
1638
-
1639
- // Remove the time since content for backwards compatibility.
1640
- $content = str_replace( '<span class="time-since">%s</span>', '', $content );
1641
-
1642
- // Remove images.
1643
- $content = preg_replace( '/<img[^>]*>/Ui', '', $content );
1644
-
1645
- /**
1646
- * Filters the activity parent content.
1647
- *
1648
- * @since 1.2.0
1649
- *
1650
- * @param string $content Content set to be displayed as parent content.
1651
- */
1652
- return apply_filters( 'bp_get_activity_parent_content', $content );
1653
- }
1654
-
1655
- /**
1656
- * Output the parent activity's user ID.
1657
- *
1658
- * @since 1.7.0
1659
- */
1660
- function bp_activity_parent_user_id() {
1661
- echo bp_get_activity_parent_user_id();
1662
- }
1663
-
1664
- /**
1665
- * Return the parent activity's user ID.
1666
- *
1667
- * @since 1.7.0
1668
- *
1669
- * @global BP_Activity_Template $activities_template
1670
- *
1671
- * @return bool|int False if parent activity can't be found, otherwise
1672
- * the parent activity's user ID.
1673
- */
1674
- function bp_get_activity_parent_user_id() {
1675
- global $activities_template;
1676
-
1677
- // Bail if no activity on no item ID.
1678
- if ( empty( $activities_template->activity ) || empty( $activities_template->activity->item_id ) ) {
1679
- return false;
1680
- }
1681
-
1682
- // Get the ID of the parent activity content.
1683
- $parent_id = $activities_template->activity->item_id;
1684
-
1685
- // Bail if no parent item.
1686
- if ( empty( $activities_template->activity_parents[ $parent_id ] ) ) {
1687
- return false;
1688
- }
1689
-
1690
- // Bail if no parent user ID.
1691
- if ( empty( $activities_template->activity_parents[ $parent_id ]->user_id ) ) {
1692
- return false;
1693
- }
1694
-
1695
- $retval = $activities_template->activity_parents[ $parent_id ]->user_id;
1696
-
1697
- /**
1698
- * Filters the activity parent item's user ID.
1699
- *
1700
- * @since 1.7.0
1701
- *
1702
- * @param int $retval ID for the activity parent's user.
1703
- */
1704
- return (int) apply_filters( 'bp_get_activity_parent_user_id', $retval );
1705
- }
1706
-
1707
- /**
1708
- * Output whether or not the current activity is in a current user's favorites.
1709
- *
1710
- * @since 1.2.0
1711
- *
1712
- */
1713
- function bp_activity_is_favorite() {
1714
- echo bp_get_activity_is_favorite();
1715
- }
1716
-
1717
- /**
1718
- * Return whether the current activity is in a current user's favorites.
1719
- *
1720
- * @since 1.2.0
1721
- *
1722
- * @global object $activities_template {@link BP_Activity_Template}
1723
- *
1724
- * @return bool True if user favorite, false otherwise.
1725
- */
1726
- function bp_get_activity_is_favorite() {
1727
- global $activities_template;
1728
-
1729
- /**
1730
- * Filters whether the current activity item is in the current user's favorites.
1731
- *
1732
- * @since 1.2.0
1733
- *
1734
- * @param bool $value Whether or not the current activity item is in the current user's favorites.
1735
- */
1736
- return (bool) apply_filters( 'bp_get_activity_is_favorite', in_array( $activities_template->activity->id, (array) $activities_template->my_favs ) );
1737
- }
1738
-
1739
- /**
1740
- * Output the comment markup for an activity item.
1741
- *
1742
- * @since 1.2.0
1743
- *
1744
- * @todo deprecate $args param
1745
- *
1746
- * @param array|string $args See {@link bp_activity_get_comments} for description.
1747
- */
1748
- function bp_activity_comments( $args = '' ) {
1749
- echo bp_activity_get_comments( $args );
1750
- }
1751
-
1752
- /**
1753
- * Get the comment markup for an activity item.
1754
- *
1755
- * @since 1.2.0
1756
- *
1757
- * @todo deprecate $args param
1758
- * @todo Given that checks for children already happen in bp_activity_recurse_comments(),
1759
- * this function can probably be streamlined or removed.
1760
- *
1761
- * @global object $activities_template {@link BP_Activity_Template}
1762
- *
1763
- * @param string $args Unused. Left over from an earlier implementation.
1764
- * @return bool
1765
- */
1766
- function bp_activity_get_comments( $args = '' ) {
1767
- global $activities_template;
1768
-
1769
- if ( empty( $activities_template->activity->children ) ) {
1770
- return false;
1771
- }
1772
-
1773
- bp_activity_recurse_comments( $activities_template->activity );
1774
- }
1775
-
1776
- /**
1777
- * Loops through a level of activity comments and loads the template for each.
1778
- *
1779
- * Note: The recursion itself used to happen entirely in this function. Now it is
1780
- * split between here and the comment.php template.
1781
- *
1782
- * @since 1.2.0
1783
- *
1784
- * @global object $activities_template {@link BP_Activity_Template}
1785
- *
1786
- * @param object $comment The activity object currently being recursed.
1787
- * @return bool|string
1788
- */
1789
- function bp_activity_recurse_comments( $comment ) {
1790
- global $activities_template;
1791
-
1792
- if ( empty( $comment ) ) {
1793
- return false;
1794
- }
1795
-
1796
- if ( empty( $comment->children ) ) {
1797
- return false;
1798
- }
1799
-
1800
- /**
1801
- * Filters the opening tag for the template that lists activity comments.
1802
- *
1803
- * @since 1.6.0
1804
- *
1805
- * @param string $value Opening tag for the HTML markup to use.
1806
- */
1807
- echo apply_filters( 'bp_activity_recurse_comments_start_ul', '<ul>' );
1808
- foreach ( (array) $comment->children as $comment_child ) {
1809
-
1810
- // Put the comment into the global so it's available to filters.
1811
- $activities_template->activity->current_comment = $comment_child;
1812
-
1813
- $template = bp_locate_template( 'activity/comment.php', false, false );
1814
-
1815
- // Backward compatibility. In older versions of BP, the markup was
1816
- // generated in the PHP instead of a template. This ensures that
1817
- // older themes (which are not children of bp-default and won't
1818
- // have the new template) will still work.
1819
- if ( !$template ) {
1820
- $template = buddypress()->plugin_dir . '/bp-themes/bp-default/activity/comment.php';
1821
- }
1822
-
1823
- load_template( $template, false );
1824
-
1825
- unset( $activities_template->activity->current_comment );
1826
- }
1827
-
1828
- /**
1829
- * Filters the closing tag for the template that list activity comments.
1830
- *
1831
- * @since 1.6.0
1832
- *
1833
- * @param string $value Closing tag for the HTML markup to use.
1834
- */
1835
- echo apply_filters( 'bp_activity_recurse_comments_end_ul', '</ul>' );
1836
- }
1837
-
1838
- /**
1839
- * Utility function that returns the comment currently being recursed.
1840
- *
1841
- * @since 1.5.0
1842
- *
1843
- * @global object $activities_template {@link BP_Activity_Template}
1844
- *
1845
- * @return object|bool $current_comment The activity comment currently being
1846
- * displayed. False on failure.
1847
- */
1848
- function bp_activity_current_comment() {
1849
- global $activities_template;
1850
-
1851
- $current_comment = !empty( $activities_template->activity->current_comment )
1852
- ? $activities_template->activity->current_comment
1853
- : false;
1854
-
1855
- /**
1856
- * Filters the current comment being recursed.
1857
- *
1858
- * @since 1.5.0
1859
- *
1860
- * @param object|bool $current_comment The activity comment currently being displayed. False on failure.
1861
- */
1862
- return apply_filters( 'bp_activity_current_comment', $current_comment );
1863
- }
1864
-
1865
-
1866
- /**
1867
- * Output the ID of the activity comment currently being displayed.
1868
- *
1869
- * @since 1.5.0
1870
- *
1871
- */
1872
- function bp_activity_comment_id() {
1873
- echo bp_get_activity_comment_id();
1874
- }
1875
-
1876
- /**
1877
- * Return the ID of the activity comment currently being displayed.
1878
- *
1879
- * @since 1.5.0
1880
- *
1881
- * @global object $activities_template {@link BP_Activity_Template}
1882
- *
1883
- * @return int|bool $comment_id The ID of the activity comment currently
1884
- * being displayed, false if none is found.
1885
- */
1886
- function bp_get_activity_comment_id() {
1887
- global $activities_template;
1888
-
1889
- $comment_id = isset( $activities_template->activity->current_comment->id ) ? $activities_template->activity->current_comment->id : false;
1890
-
1891
- /**
1892
- * Filters the ID of the activity comment currently being displayed.
1893
- *
1894
- * @since 1.5.0
1895
- *
1896
- * @param int|bool $comment_id ID for the comment currently being displayed.
1897
- */
1898
- return apply_filters( 'bp_activity_comment_id', $comment_id );
1899
- }
1900
-
1901
- /**
1902
- * Output the ID of the author of the activity comment currently being displayed.
1903
- *
1904
- * @since 1.5.0
1905
- *
1906
- */
1907
- function bp_activity_comment_user_id() {
1908
- echo bp_get_activity_comment_user_id();
1909
- }
1910
-
1911
- /**
1912
- * Return the ID of the author of the activity comment currently being displayed.
1913
- *
1914
- * @since 1.5.0
1915
- *
1916
- * @global object $activities_template {@link BP_Activity_Template}
1917
- *
1918
- * @return int|bool $user_id The user_id of the author of the displayed
1919
- * activity comment. False on failure.
1920
- */
1921
- function bp_get_activity_comment_user_id() {
1922
- global $activities_template;
1923
-
1924
- $user_id = isset( $activities_template->activity->current_comment->user_id ) ? $activities_template->activity->current_comment->user_id : false;
1925
-
1926
- /**
1927
- * Filters the ID of the author of the activity comment currently being displayed.
1928
- *
1929
- * @since 1.5.0
1930
- *
1931
- * @param int|bool $user_id ID for the author of the comment currently being displayed.
1932
- */
1933
- return apply_filters( 'bp_activity_comment_user_id', $user_id );
1934
- }
1935
-
1936
- /**
1937
- * Output the author link for the activity comment currently being displayed.
1938
- *
1939
- * @since 1.5.0
1940
- *
1941
- */
1942
- function bp_activity_comment_user_link() {
1943
- echo bp_get_activity_comment_user_link();
1944
- }
1945
-
1946
- /**
1947
- * Return the author link for the activity comment currently being displayed.
1948
- *
1949
- * @since 1.5.0
1950
- *
1951
- *
1952
- * @return string $user_link The URL of the activity comment author's profile.
1953
- */
1954
- function bp_get_activity_comment_user_link() {
1955
- $user_link = bp_core_get_user_domain( bp_get_activity_comment_user_id() );
1956
-
1957
- /**
1958
- * Filters the author link for the activity comment currently being displayed.
1959
- *
1960
- * @since 1.5.0
1961
- *
1962
- * @param string $user_link Link for the author of the activity comment currently being displayed.
1963
- */
1964
- return apply_filters( 'bp_activity_comment_user_link', $user_link );
1965
- }
1966
-
1967
- /**
1968
- * Output the author name for the activity comment currently being displayed.
1969
- *
1970
- * @since 1.5.0
1971
- *
1972
- */
1973
- function bp_activity_comment_name() {
1974
- echo bp_get_activity_comment_name();
1975
- }
1976
-
1977
- /**
1978
- * Return the author name for the activity comment currently being displayed.
1979
- *
1980
- * The use of the 'bp_acomment_name' filter is deprecated. Please use
1981
- * 'bp_activity_comment_name'.
1982
- *
1983
- * @since 1.5.0
1984
- *
1985
- * @global object $activities_template {@link BP_Activity_Template}
1986
- *
1987
- * @return string $name The full name of the activity comment author.
1988
- */
1989
- function bp_get_activity_comment_name() {
1990
- global $activities_template;
1991
-
1992
- if ( isset( $activities_template->activity->current_comment->user_fullname ) ) {
1993
-
1994
- $name = apply_filters( 'bp_acomment_name', $activities_template->activity->current_comment->user_fullname, $activities_template->activity->current_comment ); // Backward compatibility.
1995
- } else {
1996
- $name = $activities_template->activity->current_comment->display_name;
1997
- }
1998
-
1999
- /**
2000
- * Filters the name of the author for the activity comment.
2001
- *
2002
- * @since 1.5.0
2003
- *
2004
- * @param string $name Name to be displayed with the activity comment.
2005
- */
2006
- return apply_filters( 'bp_activity_comment_name', $name );
2007
- }
2008
-
2009
- /**
2010
- * Output the formatted date_recorded of the activity comment currently being displayed.
2011
- *
2012
- * @since 1.5.0
2013
- *
2014
- */
2015
- function bp_activity_comment_date_recorded() {
2016
- echo bp_get_activity_comment_date_recorded();
2017
- }
2018
-
2019
- /**
2020
- * Return the formatted date_recorded for the activity comment currently being displayed.
2021
- *
2022
- * @since 1.5.0
2023
- *
2024
- *
2025
- * @return string|bool $date_recorded Time since the activity was recorded,
2026
- * in the form "%s ago". False on failure.
2027
- */
2028
- function bp_get_activity_comment_date_recorded() {
2029
-
2030
- /**
2031
- * Filters the recorded date of the activity comment currently being displayed.
2032
- *
2033
- * @since 1.5.0
2034
- *
2035
- * @param string|bool Date for the activity comment currently being displayed.
2036
- */
2037
- return apply_filters( 'bp_activity_comment_date_recorded', bp_core_time_since( bp_get_activity_comment_date_recorded_raw() ) );
2038
- }
2039
-
2040
- /**
2041
- * Output the date_recorded of the activity comment currently being displayed.
2042
- *
2043
- * @since 2.3.0
2044
- *
2045
- */
2046
- function bp_activity_comment_date_recorded_raw() {
2047
- echo bp_get_activity_comment_date_recorded_raw();
2048
- }
2049
-
2050
- /**
2051
- * Return the date_recorded for the activity comment currently being displayed.
2052
- *
2053
- * @since 2.3.0
2054
- *
2055
- * @global object $activities_template {@link BP_Activity_Template}
2056
- *
2057
- * @return string|bool $date_recorded Time since the activity was recorded,
2058
- * in the form "%s ago". False on failure.
2059
- */
2060
- function bp_get_activity_comment_date_recorded_raw() {
2061
- global $activities_template;
2062
-
2063
- /**
2064
- * Filters the raw recorded date of the activity comment currently being displayed.
2065
- *
2066
- * @since 2.3.0
2067
- *
2068
- * @param string|bool Raw date for the activity comment currently being displayed.
2069
- */
2070
- return apply_filters( 'bp_activity_comment_date_recorded', $activities_template->activity->current_comment->date_recorded );
2071
- }
2072
-
2073
- /**
2074
- * Output the 'delete' URL for the activity comment currently being displayed.
2075
- *
2076
- * @since 1.5.0
2077
- *
2078
- */
2079
- function bp_activity_comment_delete_link() {
2080
- echo bp_get_activity_comment_delete_link();
2081
- }
2082
-
2083
- /**
2084
- * Gets the 'delete' URL for the activity comment currently being displayed.
2085
- *
2086
- * @since 1.5.0
2087
- *
2088
- *
2089
- * @return string $link The nonced URL for deleting the current
2090
- * activity comment.
2091
- */
2092
- function bp_get_activity_comment_delete_link() {
2093
- $link = wp_nonce_url( trailingslashit( bp_get_activity_directory_permalink() . 'delete/' . bp_get_activity_comment_id() ) . '?cid=' . bp_get_activity_comment_id(), 'bp_activity_delete_link' );
2094
-
2095
- /**
2096
- * Filters the link used for deleting the activity comment currently being displayed.
2097
- *
2098
- * @since 1.5.0
2099
- *
2100
- * @param string $link Link to use for deleting the currently displayed activity comment.
2101
- */
2102
- return apply_filters( 'bp_activity_comment_delete_link', $link );
2103
- }
2104
-
2105
- /**
2106
- * Output the content of the activity comment currently being displayed.
2107
- *
2108
- * @since 1.5.0
2109
- *
2110
- */
2111
- function bp_activity_comment_content() {
2112
- echo bp_get_activity_comment_content();
2113
- }
2114
-
2115
- /**
2116
- * Return the content of the activity comment currently being displayed.
2117
- *
2118
- * The content is run through two filters. 'bp_get_activity_content'
2119
- * will apply all filters applied to activity items in general. Use
2120
- * 'bp_activity_comment_content' to modify the content of activity
2121
- * comments only.
2122
- *
2123
- * @since 1.5.0
2124
- *
2125
- * @global object $activities_template {@link BP_Activity_Template}
2126
- *
2127
- * @return string $content The content of the current activity comment.
2128
- */
2129
- function bp_get_activity_comment_content() {
2130
- global $activities_template;
2131
-
2132
- /** This filter is documented in bp-activity/bp-activity-template.php */
2133
- $content = apply_filters( 'bp_get_activity_content', $activities_template->activity->current_comment->content );
2134
-
2135
- /**
2136
- * Filters the content of the current activity comment.
2137
- *
2138
- * @since 1.2.0
2139
- *
2140
- * @param string $content The content of the current activity comment.
2141
- */
2142
- return apply_filters( 'bp_activity_comment_content', $content );
2143
- }
2144
-
2145
- /**
2146
- * Output the activity comment count.
2147
- *
2148
- * @since 1.2.0
2149
- *
2150
- */
2151
- function bp_activity_comment_count() {
2152
- echo bp_activity_get_comment_count();
2153
- }
2154
-
2155
- /**
2156
- * Return the comment count of an activity item.
2157
- *
2158
- * @since 1.2.0
2159
- *
2160
- * @global object $activities_template {@link BP_Activity_Template}
2161
- *
2162
- * @param array|null $deprecated Deprecated.
2163
- * @return int $count The activity comment count.
2164
- */
2165
- function bp_activity_get_comment_count( $deprecated = null ) {
2166
- global $activities_template;
2167
-
2168
- // Deprecated notice about $args.
2169
- if ( ! empty( $deprecated ) ) {
2170
- _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__ ) );
2171
- }
2172
-
2173
- // Get the count using the purpose-built recursive function.
2174
- $count = ! empty( $activities_template->activity->children )
2175
- ? bp_activity_recurse_comment_count( $activities_template->activity )
2176
- : 0;
2177
-
2178
- /**
2179
- * Filters the activity comment count.
2180
- *
2181
- * @since 1.2.0
2182
- *
2183
- * @param int $count The activity comment count.
2184
- */
2185
- return apply_filters( 'bp_activity_get_comment_count', (int) $count );
2186
- }
2187
-
2188
- /**
2189
- * Return the total number of comments to the current comment.
2190
- *
2191
- * This function recursively adds the total number of comments each
2192
- * activity child has, and returns them.
2193
- *
2194
- * @since 1.2.0
2195
- *
2196
- *
2197
- * @param object $comment Activity comment object.
2198
- * @param int $count The current iteration count.
2199
- * @return int $count The activity comment count.
2200
- */
2201
- function bp_activity_recurse_comment_count( $comment, $count = 0 ) {
2202
-
2203
- // Copy the count.
2204
- $new_count = $count;
2205
-
2206
- // Loop through children and recursively count comments.
2207
- if ( ! empty( $comment->children ) ) {
2208
- foreach ( (array) $comment->children as $comment ) {
2209
- $new_count++;
2210
- $new_count = bp_activity_recurse_comment_count( $comment, $new_count );
2211
- }
2212
- }
2213
-
2214
- /**
2215
- * Filters the total number of comments for the current comment.
2216
- *
2217
- * @since 2.1.0
2218
- *
2219
- * @param int $new_count New total count for the current comment.
2220
- * @param object $comment Activity comment object.
2221
- * @param int $count Current iteration count for the current comment.
2222
- */
2223
- return apply_filters( 'bp_activity_recurse_comment_count', $new_count, $comment, $count );
2224
- }
2225
-
2226
- /**
2227
- * Output the depth of the current activity comment.
2228
- *
2229
- * @since 2.0.0
2230
- * @since 2.8.0 Added $comment as a parameter.
2231
- *
2232
- * @param object|int $comment Object of the activity comment or activity comment ID. Usually unnecessary
2233
- * when used in activity comment loop.
2234
- */
2235
- function bp_activity_comment_depth( $comment = 0 ) {
2236
- echo bp_activity_get_comment_depth( $comment );
2237
- }
2238
-
2239
- /**
2240
- * Return the current activity comment depth.
2241
- *
2242
- * @since 2.0.0
2243
- * @since 2.8.0 Added $comment as a parameter.
2244
- *
2245
- * @param object|int $comment Object of the activity comment or activity comment ID. Usually unnecessary
2246
- * when used in activity comment loop.
2247
- * @return int
2248
- */
2249
- function bp_activity_get_comment_depth( $comment = 0 ) {
2250
- $depth = 0;
2251
-
2252
- // Activity comment loop takes precedence.
2253
- if ( isset( $GLOBALS['activities_template']->activity->current_comment->depth ) ) {
2254
- $depth = $GLOBALS['activities_template']->activity->current_comment->depth;
2255
-
2256
- // Get depth for activity comment manually.
2257
- } elseif ( ! empty( $comment ) ) {
2258
- // We passed an activity ID, so fetch the activity object.
2259
- if ( is_int( $comment ) ) {
2260
- $comment = new BP_Activity_Activity( $comment );
2261
- }
2262
-
2263
- // Recurse through activity tree to find the depth.
2264
- if ( is_object( $comment ) && isset( $comment->type ) && 'activity_comment' === $comment->type ) {
2265
- // Fetch the entire root comment tree... ugh.
2266
- $comments = BP_Activity_Activity::get_activity_comments( $comment->item_id, 1, constant( 'PHP_INT_MAX' ) );
2267
-
2268
- // Recursively find our comment object from the comment tree.
2269
- $iterator = new RecursiveArrayIterator( $comments );
2270
- $recursive = new RecursiveIteratorIterator( $iterator, RecursiveIteratorIterator::SELF_FIRST );
2271
- foreach ( $recursive as $cid => $cobj ) {
2272
- // Skip items that are not a comment object.
2273
- if ( ! is_numeric( $cid ) || ! is_object( $cobj ) ) {
2274
- continue;
2275
- }
2276
-
2277
- // We found the activity comment! Set the depth.
2278
- if ( $cid === $comment->id && isset( $cobj->depth ) ) {
2279
- $depth = $cobj->depth;
2280
- break;
2281
- }
2282
- }
2283
- }
2284
- }
2285
-
2286
- /**
2287
- * Filters the comment depth of the current activity comment.
2288
- *
2289
- * @since 2.0.0
2290
- *
2291
- * @param int $depth Depth for the current activity comment.
2292
- */
2293
- return apply_filters( 'bp_activity_get_comment_depth', $depth );
2294
- }
2295
-
2296
- /**
2297
- * Output the activity comment link.
2298
- *
2299
- * @since 1.2.0
2300
- *
2301
- */
2302
- function bp_activity_comment_link() {
2303
- echo bp_get_activity_comment_link();
2304
- }
2305
-
2306
- /**
2307
- * Return the activity comment link.
2308
- *
2309
- * @since 1.2.0
2310
- *
2311
- * @global object $activities_template {@link BP_Activity_Template}
2312
- *
2313
- * @return string The activity comment link.
2314
- */
2315
- function bp_get_activity_comment_link() {
2316
- global $activities_template;
2317
-
2318
- /**
2319
- * Filters the comment link for the current activity comment.
2320
- *
2321
- * @since 1.2.0
2322
- *
2323
- * @param string $value Constructed URL parameters with activity IDs.
2324
- */
2325
- return apply_filters( 'bp_get_activity_comment_link', '?ac=' . $activities_template->activity->id . '/#ac-form-' . $activities_template->activity->id );
2326
- }
2327
-
2328
- /**
2329
- * Output the activity comment form no JavaScript display CSS.
2330
- *
2331
- * @since 1.2.0
2332
- *
2333
- */
2334
- function bp_activity_comment_form_nojs_display() {
2335
- echo bp_get_activity_comment_form_nojs_display();
2336
- }
2337
-
2338
- /**
2339
- * Return the activity comment form no JavaScript display CSS.
2340
- *
2341
- * @since 1.2.0
2342
- *
2343
- * @global object $activities_template {@link BP_Activity_Template}
2344
- *
2345
- * @return string|false The activity comment form no JavaScript
2346
- * display CSS. False on failure.
2347
- */
2348
- function bp_get_activity_comment_form_nojs_display() {
2349
- global $activities_template;
2350
-
2351
- if ( isset( $_GET['ac'] ) && ( $_GET['ac'] === ( $activities_template->activity->id . '/' ) ) ) {
2352
- return 'style="display: block"';
2353
- }
2354
-
2355
- return false;
2356
- }
2357
-
2358
- /**
2359
- * Output the activity comment form action.
2360
- *
2361
- * @since 1.2.0
2362
- *
2363
- */
2364
- function bp_activity_comment_form_action() {
2365
- echo bp_get_activity_comment_form_action();
2366
- }
2367
-
2368
- /**
2369
- * Return the activity comment form action.
2370
- *
2371
- * @since 1.2.0
2372
- *
2373
- *
2374
- * @return string The activity comment form action.
2375
- */
2376
- function bp_get_activity_comment_form_action() {
2377
-
2378
- /**
2379
- * Filters the activity comment form action URL.
2380
- *
2381
- * @since 1.2.0
2382
- *
2383
- * @param string $value URL to use in the comment form's action attribute.
2384
- */
2385
- return apply_filters( 'bp_get_activity_comment_form_action', home_url( bp_get_activity_root_slug() . '/reply/' ) );
2386
- }
2387
-
2388
- /**
2389
- * Output the activity permalink ID.
2390
- *
2391
- * @since 1.2.0
2392
- *
2393
- */
2394
- function bp_activity_permalink_id() {
2395
- echo bp_get_activity_permalink_id();
2396
- }
2397
-
2398
- /**
2399
- * Return the activity permalink ID.
2400
- *
2401
- * @since 1.2.0
2402
- *
2403
- *
2404
- * @return string The activity permalink ID.
2405
- */
2406
- function bp_get_activity_permalink_id() {
2407
-
2408
- /**
2409
- * Filters the activity action permalink ID.
2410
- *
2411
- * @since 1.2.0
2412
- *
2413
- * @param string $value Current action for the activity item.
2414
- */
2415
- return apply_filters( 'bp_get_activity_permalink_id', bp_current_action() );
2416
- }
2417
-
2418
- /**
2419
- * Output the activity thread permalink.
2420
- *
2421
- * @since 1.2.0
2422
- *
2423
- */
2424
- function bp_activity_thread_permalink() {
2425
- echo esc_url( bp_get_activity_thread_permalink() );
2426
- }
2427
-
2428
- /**
2429
- * Return the activity thread permalink.
2430
- *
2431
- * @since 1.2.0
2432
- *
2433
- *
2434
- * @return string $link The activity thread permalink.
2435
- */
2436
- function bp_get_activity_thread_permalink() {
2437
- global $activities_template;
2438
-
2439
- $link = bp_activity_get_permalink( $activities_template->activity->id, $activities_template->activity );
2440
-
2441
- /**
2442
- * Filters the activity thread permalink.
2443
- *
2444
- * @since 1.2.0
2445
- *
2446
- * @param string $link The activity thread permalink.
2447
- */
2448
- return apply_filters( 'bp_get_activity_thread_permalink', $link );
2449
- }
2450
-
2451
- /**
2452
- * Output the activity comment permalink.
2453
- *
2454
- * @since 1.8.0
2455
- *
2456
- */
2457
- function bp_activity_comment_permalink() {
2458
- echo esc_url( bp_get_activity_comment_permalink() );
2459
- }
2460
- /**
2461
- * Return the activity comment permalink.
2462
- *
2463
- * @since 1.8.0
2464
- *
2465
- * @return string $link The activity comment permalink.
2466
- */
2467
- function bp_get_activity_comment_permalink() {
2468
- global $activities_template;
2469
-
2470
- $link = bp_activity_get_permalink( $activities_template->activity->id, $activities_template->activity );
2471
-
2472
- // Used for filter below.
2473
- $comment_id = isset( $activities_template->activity->current_comment->id )
2474
- ? $activities_template->activity->current_comment->id
2475
- : 0;
2476
-
2477
- /**
2478
- * Filters the activity comment permalink.
2479
- *
2480
- * @since 1.8.0
2481
- *
2482
- * @param string $link Activity comment permalink.
2483
- * @param int $comment_id ID for the current activity comment.
2484
- */
2485
- return apply_filters( 'bp_get_activity_comment_permalink', $link, $comment_id );
2486
- }
2487
-
2488
- /**
2489
- * Output the activity favorite link.
2490
- *
2491
- * @since 1.2.0
2492
- *
2493
- */
2494
- function bp_activity_favorite_link() {
2495
- echo bp_get_activity_favorite_link();
2496
- }
2497
-
2498
- /**
2499
- * Return the activity favorite link.
2500
- *
2501
- * @since 1.2.0
2502
- *
2503
- * @global object $activities_template {@link BP_Activity_Template}
2504
- *
2505
- * @return string The activity favorite link.
2506
- */
2507
- function bp_get_activity_favorite_link() {
2508
- global $activities_template;
2509
-
2510
- /**
2511
- * Filters the activity favorite link.
2512
- *
2513
- * @since 1.2.0
2514
- *
2515
- * @param string $value Constructed link for favoriting the activity comment.
2516
- */
2517
- return apply_filters( 'bp_get_activity_favorite_link', wp_nonce_url( home_url( bp_get_activity_root_slug() . '/favorite/' . $activities_template->activity->id . '/' ), 'mark_favorite' ) );
2518
- }
2519
-
2520
- /**
2521
- * Output the activity unfavorite link.
2522
- *
2523
- * @since 1.2.0
2524
- *
2525
- */
2526
- function bp_activity_unfavorite_link() {
2527
- echo bp_get_activity_unfavorite_link();
2528
- }
2529
-
2530
- /**
2531
- * Return the activity unfavorite link.
2532
- *
2533
- * @since 1.2.0
2534
- *
2535
- * @global object $activities_template {@link BP_Activity_Template}
2536
- *
2537
- * @return string The activity unfavorite link.
2538
- */
2539
- function bp_get_activity_unfavorite_link() {
2540
- global $activities_template;
2541
-
2542
- /**
2543
- * Filters the activity unfavorite link.
2544
- *
2545
- * @since 1.2.0
2546
- *
2547
- * @param string $value Constructed link for unfavoriting the activity comment.
2548
- */
2549
- return apply_filters( 'bp_get_activity_unfavorite_link', wp_nonce_url( home_url( bp_get_activity_root_slug() . '/unfavorite/' . $activities_template->activity->id . '/' ), 'unmark_favorite' ) );
2550
- }
2551
-
2552
- /**
2553
- * Output the activity CSS class.
2554
- *
2555
- * @since 1.0.0
2556
- *
2557
- */
2558
- function bp_activity_css_class() {
2559
- echo bp_get_activity_css_class();
2560
- }
2561
-
2562
- /**
2563
- * Return the current activity item's CSS class.
2564
- *
2565
- * @since 1.0.0
2566
- *
2567
- * @global object $activities_template {@link BP_Activity_Template}
2568
- *
2569
- * @return string The activity item's CSS class.
2570
- */
2571
- function bp_get_activity_css_class() {
2572
- global $activities_template;
2573
-
2574
- /**
2575
- * Filters the available mini activity actions available as CSS classes.
2576
- *
2577
- * @since 1.2.0
2578
- *
2579
- * @param array $value Array of classes used to determine classes applied to HTML element.
2580
- */
2581
- $mini_activity_actions = apply_filters( 'bp_activity_mini_activity_types', array(
2582
- 'friendship_accepted',
2583
- 'friendship_created',
2584
- 'new_blog',
2585
- 'joined_group',
2586
- 'created_group',
2587
- 'new_member'
2588
- ) );
2589
-
2590
- $class = ' activity-item';
2591
-
2592
- if ( in_array( $activities_template->activity->type, (array) $mini_activity_actions ) || empty( $activities_template->activity->content ) ) {
2593
- $class .= ' mini';
2594
- }
2595
-
2596
- if ( bp_activity_get_comment_count() && bp_activity_can_comment() ) {
2597
- $class .= ' has-comments';
2598
- }
2599
-
2600
- /**
2601
- * Filters the determined classes to add to the HTML element.
2602
- *
2603
- * @since 1.0.0
2604
- *
2605
- * @param string $value Classes to be added to the HTML element.
2606
- */
2607
- return apply_filters( 'bp_get_activity_css_class', $activities_template->activity->component . ' ' . $activities_template->activity->type . $class );
2608
- }
2609
-
2610
- /**
2611
- * Output the activity delete link.
2612
- *
2613
- * @since 1.1.0
2614
- *
2615
- */
2616
- function bp_activity_delete_link() {
2617
- echo bp_get_activity_delete_link();
2618
- }
2619
-
2620
- /**
2621
- * Return the activity delete link.
2622
- *
2623
- * @since 1.1.0
2624
- *
2625
- * @global object $activities_template {@link BP_Activity_Template}
2626
- *
2627
- * @return string $link Activity delete link. Contains $redirect_to arg
2628
- * if on single activity page.
2629
- */
2630
- function bp_get_activity_delete_link() {
2631
-
2632
- $url = bp_get_activity_delete_url();
2633
- $class = 'delete-activity';
2634
-
2635
- // Determine if we're on a single activity page, and customize accordingly.
2636
- if ( bp_is_activity_component() && is_numeric( bp_current_action() ) ) {
2637
- $class = 'delete-activity-single';
2638
- }
2639
-
2640
- $link = '<a href="' . esc_url( $url ) . '" class="button item-button bp-secondary-action ' . $class . ' confirm" rel="nofollow">' . __( 'Delete', 'buddypress' ) . '</a>';
2641
-
2642
- /**
2643
- * Filters the activity delete link.
2644
- *
2645
- * @since 1.1.0
2646
- *
2647
- * @param string $link Activity delete HTML link.
2648
- */
2649
- return apply_filters( 'bp_get_activity_delete_link', $link );
2650
- }
2651
-
2652
- /**
2653
- * Output the URL to delete a single activity stream item.
2654
- *
2655
- * @since 2.1.0
2656
- *
2657
- */
2658
- function bp_activity_delete_url() {
2659
- echo esc_url( bp_get_activity_delete_url() );
2660
- }
2661
- /**
2662
- * Return the URL to delete a single activity item.
2663
- *
2664
- * @since 2.1.0
2665
- *
2666
- * @global object $activities_template {@link BP_Activity_Template}
2667
- *
2668
- * @return string $link Activity delete link. Contains $redirect_to arg
2669
- * if on single activity page.
2670
- */
2671
- function bp_get_activity_delete_url() {
2672
- global $activities_template;
2673
-
2674
- $url = trailingslashit( bp_get_root_domain() . '/' . bp_get_activity_root_slug() . '/delete/' . $activities_template->activity->id );
2675
-
2676
- // Determine if we're on a single activity page, and customize accordingly.
2677
- if ( bp_is_activity_component() && is_numeric( bp_current_action() ) ) {
2678
- $url = add_query_arg( array( 'redirect_to' => wp_get_referer() ), $url );
2679
- }
2680
-
2681
- $url = wp_nonce_url( $url, 'bp_activity_delete_link' );
2682
-
2683
- /**
2684
- * Filters the activity delete URL.
2685
- *
2686
- * @since 2.1.0
2687
- *
2688
- * @param string $url Activity delete URL.
2689
- */
2690
- return apply_filters( 'bp_get_activity_delete_url', $url );
2691
- }
2692
-
2693
- /**
2694
- * Output the activity latest update link.
2695
- *
2696
- * @since 1.2.0
2697
- *
2698
- * @see bp_get_activity_latest_update() for description of parameters.
2699
- *
2700
- * @param int $user_id See {@link bp_get_activity_latest_update()} for description.
2701
- */
2702
- function bp_activity_latest_update( $user_id = 0 ) {
2703
- echo bp_get_activity_latest_update( $user_id );
2704
- }
2705
-
2706
- /**
2707
- * Return the activity latest update link.
2708
- *
2709
- * @since 1.2.0
2710
- *
2711
- *
2712
- * @param int $user_id If empty, will fall back on displayed user.
2713
- * @return string|bool $latest_update The activity latest update link.
2714
- * False on failure.
2715
- */
2716
- function bp_get_activity_latest_update( $user_id = 0 ) {
2717
-
2718
- if ( empty( $user_id ) ) {
2719
- $user_id = bp_displayed_user_id();
2720
- }
2721
-
2722
- if ( bp_is_user_inactive( $user_id ) ) {
2723
- return false;
2724
- }
2725
-
2726
- if ( !$update = bp_get_user_meta( $user_id, 'bp_latest_update', true ) ) {
2727
- return false;
2728
- }
2729
-
2730
- /**
2731
- * Filters the latest update excerpt.
2732
- *
2733
- * @since 1.2.10
2734
- * @since 2.6.0 Added the `$user_id` parameter.
2735
- *
2736
- * @param string $value The excerpt for the latest update.
2737
- * @param int $user_id ID of the queried user.
2738
- */
2739
- $latest_update = apply_filters( 'bp_get_activity_latest_update_excerpt', trim( strip_tags( bp_create_excerpt( $update['content'], bp_activity_get_excerpt_length() ) ) ), $user_id );
2740
-
2741
- $latest_update = sprintf(
2742
- '%s <a href="%s">%s</a>',
2743
- $latest_update,
2744
- esc_url_raw( bp_activity_get_permalink( $update['id'] ) ),
2745
- esc_attr__( 'View', 'buddypress' )
2746
- );
2747
-
2748
- /**
2749
- * Filters the latest update excerpt with view link appended to the end.
2750
- *
2751
- * @since 1.2.0
2752
- * @since 2.6.0 Added the `$user_id` parameter.
2753
- *
2754
- * @param string $latest_update The latest update with "view" link appended to it.
2755
- * @param int $user_id ID of the queried user.
2756
- */
2757
- return apply_filters( 'bp_get_activity_latest_update', $latest_update, $user_id );
2758
- }
2759
-
2760
- /**
2761
- * Output the activity filter links.
2762
- *
2763
- * @since 1.1.0
2764
- *
2765
- * @see bp_get_activity_filter_links() for description of parameters.
2766
- *
2767
- * @param array|bool $args See {@link bp_get_activity_filter_links()} for description.
2768
- */
2769
- function bp_activity_filter_links( $args = false ) {
2770
- echo bp_get_activity_filter_links( $args );
2771
- }
2772
-
2773
- /**
2774
- * Return the activity filter links.
2775
- *
2776
- * @since 1.1.0
2777
- *
2778
- *
2779
- * @param array|bool $args {
2780
- * @type string $style The type of markup to use for the links.
2781
- * 'list', 'paragraph', or 'span'. Default: 'list'.
2782
- * }
2783
- * @return string|bool $component_links The activity filter links.
2784
- * False on failure.
2785
- */
2786
- function bp_get_activity_filter_links( $args = false ) {
2787
-
2788
- $r = wp_parse_args( $args, array(
2789
- 'style' => 'list'
2790
- ) );
2791
-
2792
- // Define local variable.
2793
- $component_links = array();
2794
-
2795
- // Fetch the names of components that have activity recorded in the DB.
2796
- $components = BP_Activity_Activity::get_recorded_components();
2797
-
2798
- if ( empty( $components ) ) {
2799
- return false;
2800
- }
2801
-
2802
- foreach ( (array) $components as $component ) {
2803
-
2804
- // Skip the activity comment filter.
2805
- if ( 'activity' == $component ) {
2806
- continue;
2807
- }
2808
-
2809
- if ( isset( $_GET['afilter'] ) && $component == $_GET['afilter'] ) {
2810
- $selected = ' class="selected"';
2811
- } else {
2812
- $selected = '';
2813
- }
2814
-
2815
- $component = esc_attr( $component );
2816
-
2817
- switch ( $r['style'] ) {
2818
- case 'list':
2819
- $tag = 'li';
2820
- $before = '<li id="afilter-' . $component . '"' . $selected . '>';
2821
- $after = '</li>';
2822
- break;
2823
- case 'paragraph':
2824
- $tag = 'p';
2825
- $before = '<p id="afilter-' . $component . '"' . $selected . '>';
2826
- $after = '</p>';
2827
- break;
2828
- case 'span':
2829
- $tag = 'span';
2830
- $before = '<span id="afilter-' . $component . '"' . $selected . '>';
2831
- $after = '</span>';
2832
- break;
2833
- }
2834
-
2835
- $link = add_query_arg( 'afilter', $component );
2836
- $link = remove_query_arg( 'acpage' , $link );
2837
-
2838
- /**
2839
- * Filters the activity filter link URL for the current activity component.
2840
- *
2841
- * @since 1.1.0
2842
- *
2843
- * @param string $link The URL for the current component.
2844
- * @param string $component The current component getting links constructed for.
2845
- */
2846
- $link = apply_filters( 'bp_get_activity_filter_link_href', $link, $component );
2847
-
2848
- $component_links[] = $before . '<a href="' . esc_url( $link ) . '">' . ucwords( $component ) . '</a>' . $after;
2849
- }
2850
-
2851
- $link = remove_query_arg( 'afilter' , $link );
2852
-
2853
- if ( isset( $_GET['afilter'] ) ) {
2854
- $component_links[] = '<' . $tag . ' id="afilter-clear"><a href="' . esc_url( $link ) . '">' . __( 'Clear Filter', 'buddypress' ) . '</a></' . $tag . '>';
2855
- }
2856
-
2857
- /**
2858
- * Filters all of the constructed filter links.
2859
- *
2860
- * @since 1.1.0
2861
- * @since 2.6.0 Added the `$r` parameter.
2862
- *
2863
- * @param string $value All of the links to be displayed to the user.
2864
- * @param array $r Array of parsed arguments.
2865
- */
2866
- return apply_filters( 'bp_get_activity_filter_links', implode( "\n", $component_links ), $r );
2867
- }
2868
-
2869
- /**
2870
- * Determine if a comment can be made on an activity item.
2871
- *
2872
- * @since 1.2.0
2873
- *
2874
- * @global object $activities_template {@link BP_Activity_Template}
2875
- *
2876
- * @return bool $can_comment True if item can receive comments.
2877
- */
2878
- function bp_activity_can_comment() {
2879
- global $activities_template;
2880
- $bp = buddypress();
2881
-
2882
- // Determine ability to comment based on activity type name.
2883
- $activity_type = bp_get_activity_type();
2884
-
2885
- // Get the 'comment-reply' support for the current activity type.
2886
- $can_comment = bp_activity_type_supports( $activity_type, 'comment-reply' );
2887
-
2888
- // Neutralize activity_comment.
2889
- if ( 'activity_comment' === $activity_type ) {
2890
- $can_comment = false;
2891
- }
2892
-
2893
- /**
2894
- * Filters whether a comment can be made on an activity item.
2895
- *
2896
- * @since 1.5.0
2897
- * @since 2.5.0 Use $activity_type instead of $activity_name for the second parameter.
2898
- *
2899
- * @param bool $can_comment Status on if activity can be commented on.
2900
- * @param string $activity_type Current activity type being checked on.
2901
- */
2902
- return apply_filters( 'bp_activity_can_comment', $can_comment, $activity_type );
2903
- }
2904
-
2905
- /**
2906
- * Determine whether a comment can be made on an activity reply item.
2907
- *
2908
- * @since 1.5.0
2909
- *
2910
- * @param bool|object $comment Activity comment.
2911
- * @return bool $can_comment True if comment can receive comments,
2912
- * otherwise false.
2913
- */
2914
- function bp_activity_can_comment_reply( $comment = false ) {
2915
-
2916
- // Assume activity can be commented on.
2917
- $can_comment = true;
2918
-
2919
- // Check that comment exists.
2920
- if ( empty( $comment ) ) {
2921
- $comment = bp_activity_current_comment();
2922
- }
2923
-
2924
- if ( ! empty( $comment ) ) {
2925
-
2926
- // Fall back on current comment in activity loop.
2927
- $comment_depth = isset( $comment->depth )
2928
- ? intval( $comment->depth )
2929
- : bp_activity_get_comment_depth( $comment );
2930
-
2931
- // Threading is turned on, so check the depth.
2932
- if ( get_option( 'thread_comments' ) ) {
2933
- $can_comment = (bool) ( $comment_depth < get_option( 'thread_comments_depth' ) );
2934
-
2935
- // No threading for comment replies if no threading for comments.
2936
- } else {
2937
- $can_comment = false;
2938
- }
2939
- }
2940
-
2941
- /**
2942
- * Filters whether a comment can be made on an activity reply item.
2943
- *
2944
- * @since 1.5.0
2945
- *
2946
- * @param bool $can_comment Status on if activity reply can be commented on.
2947
- * @param string $comment Current comment being checked on.
2948
- */
2949
- return (bool) apply_filters( 'bp_activity_can_comment_reply', $can_comment, $comment );
2950
- }
2951
-
2952
- /**
2953
- * Determine whether favorites are allowed.
2954
- *
2955
- * Defaults to true, but can be modified by plugins.
2956
- *
2957
- * @since 1.5.0
2958
- *
2959
- * @return bool True if comment can receive comments.
2960
- */
2961
- function bp_activity_can_favorite() {
2962
-
2963
- /**
2964
- * Filters whether or not users can favorite activity items.
2965
- *
2966
- * @since 1.5.0
2967
- *
2968
- * @param bool $value Whether or not favoriting is enabled.
2969
- */
2970
- return apply_filters( 'bp_activity_can_favorite', true );
2971
- }
2972
-
2973
- /**
2974
- * Output the total favorite count for a specified user.
2975
- *
2976
- * @since 1.2.0
2977
- *
2978
- * @see bp_get_total_favorite_count_for_user() for description of parameters.
2979
- *
2980
- * @param int $user_id See {@link bp_get_total_favorite_count_for_user()}.
2981
- */
2982
- function bp_total_favorite_count_for_user( $user_id = 0 ) {
2983
- echo bp_get_total_favorite_count_for_user( $user_id );
2984
- }
2985
-
2986
- /**
2987
- * Return the total favorite count for a specified user.
2988
- *
2989
- * @since 1.2.0
2990
- *
2991
- *
2992
- * @param int $user_id ID of user being queried. Default: displayed user ID.
2993
- * @return int The total favorite count for the specified user.
2994
- */
2995
- function bp_get_total_favorite_count_for_user( $user_id = 0 ) {
2996
- $retval = false;
2997
-
2998
- if ( bp_activity_can_favorite() ) {
2999
- // Default to displayed user if none is passed.
3000
- $user_id = empty( $user_id )
3001
- ? bp_displayed_user_id()
3002
- : $user_id;
3003
-
3004
- // Get user meta if user ID exists.
3005
- if ( ! empty( $user_id ) ) {
3006
- $retval = bp_activity_total_favorites_for_user( $user_id );
3007
- }
3008
- }
3009
-
3010
- /**
3011
- * Filters the total favorite count for a user.
3012
- *
3013
- * @since 1.2.0
3014
- * @since 2.6.0 Added the `$user_id` parameter.
3015
- *
3016
- * @param int|bool $retval Total favorite count for a user. False on no favorites.
3017
- * @param int $user_id ID of the queried user.
3018
- */
3019
- return apply_filters( 'bp_get_total_favorite_count_for_user', $retval, $user_id );
3020
- }
3021
-
3022
-
3023
- /**
3024
- * Output the total mention count for a specified user.
3025
- *
3026
- * @since 1.2.0
3027
- *
3028
- * @see bp_get_total_mention_count_for_user() for description of parameters.
3029
- *
3030
- * @param int $user_id See {@link bp_get_total_mention_count_for_user()}.
3031
- */
3032
- function bp_total_mention_count_for_user( $user_id = 0 ) {
3033
- echo bp_get_total_mention_count_for_user( $user_id );
3034
- }
3035
-
3036
- /**
3037
- * Return the total mention count for a specified user.
3038
- *
3039
- * @since 1.2.0
3040
- *
3041
- *
3042
- * @param int $user_id ID of user being queried. Default: displayed user ID.
3043
- * @return int The total mention count for the specified user.
3044
- */
3045
- function bp_get_total_mention_count_for_user( $user_id = 0 ) {
3046
-
3047
- // Default to displayed user if none is passed.
3048
- $user_id = empty( $user_id )
3049
- ? bp_displayed_user_id()
3050
- : $user_id;
3051
-
3052
- // Get user meta if user ID exists.
3053
- $retval = ! empty( $user_id )
3054
- ? bp_get_user_meta( $user_id, 'bp_new_mention_count', true )
3055
- : false;
3056
-
3057
- /**
3058
- * Filters the total mention count for a user.
3059
- *
3060
- * @since 1.2.0
3061
- * @since 2.6.0 Added the `$user_id` parameter.
3062
- *
3063
- * @param int|bool $retval Total mention count for a user. False on no mentions.
3064
- * @param int $user_id ID of the queried user.
3065
- */
3066
- return apply_filters( 'bp_get_total_mention_count_for_user', $retval, $user_id );
3067
- }
3068
-
3069
- /**
3070
- * Output the public message link for displayed user.
3071
- *
3072
- * @since 1.2.0
3073
- *
3074
- */
3075
- function bp_send_public_message_link() {
3076
- echo esc_url( bp_get_send_public_message_link() );
3077
- }
3078
-
3079
- /**
3080
- * Return the public message link for the displayed user.
3081
- *
3082
- * @since 1.2.0
3083
- *
3084
- *
3085
- * @return string The public message link for the displayed user.
3086
- */
3087
- function bp_get_send_public_message_link() {
3088
-
3089
- // No link if not logged in, not looking at someone else's profile.
3090
- if ( ! is_user_logged_in() || ! bp_is_user() || bp_is_my_profile() ) {
3091
- $retval = '';
3092
- } else {
3093
- $args = array( 'r' => bp_get_displayed_user_mentionname() );
3094
- $url = add_query_arg( $args, bp_get_activity_directory_permalink() );
3095
- $retval = wp_nonce_url( $url );
3096
- }
3097
-
3098
- /**
3099
- * Filters the public message link for the displayed user.
3100
- *
3101
- * @since 1.2.0
3102
- *
3103
- * @param string $retval The URL for the public message link.
3104
- */
3105
- return apply_filters( 'bp_get_send_public_message_link', $retval );
3106
- }
3107
-
3108
- /**
3109
- * Recurse through all activity comments and return the activity comment IDs.
3110
- *
3111
- * @since 2.0.0
3112
- *
3113
- * @param array $activity Array of activities generated from {@link bp_activity_get()}.
3114
- * @param array $activity_ids Used for recursion purposes in this function.
3115
- * @return array
3116
- */
3117
- function bp_activity_recurse_comments_activity_ids( $activity = array(), $activity_ids = array() ) {
3118
- if ( is_array( $activity ) && ! empty( $activity['activities'] ) ) {
3119
- $activity = $activity['activities'][0];
3120
- }
3121
-
3122
- if ( ! empty( $activity->children ) ) {
3123
- foreach ($activity->children as $child ) {
3124
- $activity_ids[] = $child->id;
3125
-
3126
- if( ! empty( $child->children ) ) {
3127
- $activity_ids = bp_activity_recurse_comments_activity_ids( $child, $activity_ids );
3128
- }
3129
- }
3130
- }
3131
-
3132
- return $activity_ids;
3133
- }
3134
-
3135
- /**
3136
- * Output the mentioned user display name.
3137
- *
3138
- * @since 1.2.0
3139
- *
3140
- * @see bp_get_mentioned_user_display_name() for description of parameters.
3141
- *
3142
- * @param int|string|bool $user_id_or_username See {@link bp_get_mentioned_user_display_name()}.
3143
- */
3144
- function bp_mentioned_user_display_name( $user_id_or_username = false ) {
3145
- echo bp_get_mentioned_user_display_name( $user_id_or_username );
3146
- }
3147
-
3148
- /**
3149
- * Returns the mentioned user display name.
3150
- *
3151
- * @since 1.2.0
3152
- *
3153
- *
3154
- * @param int|string|bool $user_id_or_username User ID or username.
3155
- * @return string The mentioned user's display name.
3156
- */
3157
- function bp_get_mentioned_user_display_name( $user_id_or_username = false ) {
3158
-
3159
- // Get user display name.
3160
- $name = bp_core_get_user_displayname( $user_id_or_username );
3161
-
3162
- // If user somehow has no name, return this really lame string.
3163
- if ( empty( $name ) ) {
3164
- $name = __( 'a user', 'buddypress' );
3165
- }
3166
-
3167
- /**
3168
- * Filters the mentioned user display name.
3169
- *
3170
- * @since 1.2.0
3171
- *
3172
- * @param string $name Display name for the mentioned user.
3173
- * @param int|string $user_id_or_username User ID or username use for query.
3174
- */
3175
- return apply_filters( 'bp_get_mentioned_user_display_name', $name, $user_id_or_username );
3176
- }
3177
-
3178
- /**
3179
- * Output button for sending a public message (an @-mention).
3180
- *
3181
- * @since 1.2.0
3182
- *
3183
- * @see bp_get_send_public_message_button() for description of parameters.
3184
- *
3185
- * @param array|string $args See {@link bp_get_send_public_message_button()}.
3186
- */
3187
- function bp_send_public_message_button( $args = '' ) {
3188
- echo bp_get_send_public_message_button( $args );
3189
- }
3190
-
3191
- /**
3192
- * Return button for sending a public message (an @-mention).
3193
- *
3194
- * @since 1.2.0
3195
- *
3196
- *
3197
- * @param array|string $args {
3198
- * All arguments are optional. See {@link BP_Button} for complete
3199
- * descriptions.
3200
- * @type string $id Default: 'public_message'.
3201
- * @type string $component Default: 'activity'.
3202
- * @type bool $must_be_logged_in Default: true.
3203
- * @type bool $block_self Default: true.
3204
- * @type string $wrapper_id Default: 'post-mention'.
3205
- * @type string $link_href Default: the public message link for
3206
- * the current member in the loop.
3207
- * @type string $link_text Default: 'Public Message'.
3208
- * @type string $link_class Default: 'activity-button mention'.
3209
- * }
3210
- * @return string The button for sending a public message.
3211
- */
3212
- function bp_get_send_public_message_button( $args = '' ) {
3213
-
3214
- $r = bp_parse_args( $args, array(
3215
- 'id' => 'public_message',
3216
- 'component' => 'activity',
3217
- 'must_be_logged_in' => true,
3218
- 'block_self' => true,
3219
- 'wrapper_id' => 'post-mention',
3220
- 'link_href' => bp_get_send_public_message_link(),
3221
- 'link_text' => __( 'Public Message', 'buddypress' ),
3222
- 'link_class' => 'activity-button mention'
3223
- ) );
3224
-
3225
- /**
3226
- * Filters the public message button HTML.
3227
- *
3228
- * @since 1.2.10
3229
- *
3230
- * @param array $r Array of arguments for the public message button HTML.
3231
- */
3232
- return bp_get_button( apply_filters( 'bp_get_send_public_message_button', $r ) );
3233
- }
3234
-
3235
- /**
3236
- * Output the activity post form action.
3237
- *
3238
- * @since 1.2.0
3239
- *
3240
- */
3241
- function bp_activity_post_form_action() {
3242
- echo bp_get_activity_post_form_action();
3243
- }
3244
-
3245
- /**
3246
- * Return the activity post form action.
3247
- *
3248
- * @since 1.2.0
3249
- *
3250
- *
3251
- * @return string The activity post form action.
3252
- */
3253
- function bp_get_activity_post_form_action() {
3254
-
3255
- /**
3256
- * Filters the action url used for the activity post form.
3257
- *
3258
- * @since 1.2.0
3259
- *
3260
- * @param string $value URL to be used for the activity post form.
3261
- */
3262
- return apply_filters( 'bp_get_activity_post_form_action', home_url( bp_get_activity_root_slug() . '/post/' ) );
3263
- }
3264
-
3265
- /**
3266
- * Echo a list of linked avatars of users who have commented on the current activity item.
3267
- *
3268
- * Use this function to easily output activity comment authors' avatars.
3269
- *
3270
- * Avatars are wrapped in <li> elements, but you've got to provide your own
3271
- * <ul> or <ol> wrapper markup.
3272
- *
3273
- * @since 1.7.0
3274
- *
3275
- * @see bp_core_fetch_avatar() for a description of arguments.
3276
- *
3277
- * @param array $args See {@link bp_core_fetch_avatar()}.
3278
- */
3279
- function bp_activity_comments_user_avatars( $args = array() ) {
3280
-
3281
- $r = bp_parse_args( $args, array(
3282
- 'height' => false,
3283
- 'html' => true,
3284
- 'type' => 'thumb',
3285
- 'width' => false,
3286
- ) );
3287
-
3288
- // Get the user IDs of everyone who has left a comment to the current activity item.
3289
- $user_ids = bp_activity_get_comments_user_ids();
3290
- $output = array();
3291
- $retval = '';
3292
-
3293
- if ( ! empty( $user_ids ) ) {
3294
- foreach ( (array) $user_ids as $user_id ) {
3295
-
3296
- // Skip an empty user ID.
3297
- if ( empty( $user_id ) ) {
3298
- continue;
3299
- }
3300
-
3301
- // Get profile link for this user.
3302
- $profile_link = bp_core_get_user_domain( $user_id );
3303
-
3304
- // Get avatar for this user.
3305
- $image_html = bp_core_fetch_avatar( array(
3306
- 'item_id' => $user_id,
3307
- 'height' => $r['height'],
3308
- 'html' => $r['html'],
3309
- 'type' => $r['type'],
3310
- 'width' => $r['width']
3311
- ) );
3312
-
3313
- // If user has link & avatar, add them to the output array.
3314
- if ( ! empty( $profile_link ) && ! empty( $image_html ) ) {
3315
- $output[] = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $profile_link ), $image_html );
3316
- }
3317
- }
3318
-
3319
- // If output array is not empty, wrap everything in some list items.
3320
- if ( ! empty( $output ) ) {
3321
- $retval = '<li>' . implode( '</li><li>', $output ) . '</li>';
3322
- }
3323
- }
3324
-
3325
- /**
3326
- * Filters the list of linked avatars for users who have commented on the current activity item.
3327
- *
3328
- * @since 1.7.0
3329
- *
3330
- * @param string $retval HTML markup for the list of avatars.
3331
- * @param array $r Array of arguments used for each avatar.
3332
- * @param array $output Array of each avatar found, before imploded into single string.
3333
- */
3334
- echo apply_filters( 'bp_activity_comments_user_avatars', $retval, $r, $output );
3335
- }
3336
-
3337
- /**
3338
- * Return the IDs of every user who's left a comment on the current activity item.
3339
- *
3340
- * @since 1.7.0
3341
- *
3342
- * @return bool|array An array of IDs, or false if none are found.
3343
- */
3344
- function bp_activity_get_comments_user_ids() {
3345
- global $activities_template;
3346
-
3347
- $user_ids = ! empty( $activities_template->activity->children )
3348
- ? (array) bp_activity_recurse_comments_user_ids( $activities_template->activity->children )
3349
- : array();
3350
-
3351
- /**
3352
- * Filters the list of user IDs for the current activity item.
3353
- *
3354
- * @since 1.7.0
3355
- *
3356
- * @param array $value Array of unique user IDs for the current activity item.
3357
- */
3358
- return apply_filters( 'bp_activity_get_comments_user_ids', array_unique( $user_ids ) );
3359
- }
3360
-
3361
- /**
3362
- * Recurse through all activity comments and collect the IDs of the users who wrote them.
3363
- *
3364
- * @since 1.7.0
3365
- *
3366
- * @param array $comments Array of {@link BP_Activity_Activity} items.
3367
- * @return array Array of user IDs.
3368
- */
3369
- function bp_activity_recurse_comments_user_ids( array $comments = array() ) {
3370
-
3371
- // Default user ID's array.
3372
- $user_ids = array();
3373
-
3374
- // Loop through comments and try to get user ID's.
3375
- if ( ! empty( $comments ) ) {
3376
- foreach ( $comments as $comment ) {
3377
-
3378
- // If a user is a spammer, their activity items will have been
3379
- // automatically marked as spam. Skip these.
3380
- if ( ! empty( $comment->is_spam ) ) {
3381
- continue;
3382
- }
3383
-
3384
- // Add user ID to array.
3385
- $user_ids[] = $comment->user_id;
3386
-
3387
- // Check for commentception.
3388
- if ( ! empty( $comment->children ) ) {
3389
- $user_ids = array_merge( $user_ids, bp_activity_recurse_comments_user_ids( $comment->children ) );
3390
- }
3391
- }
3392
- }
3393
-
3394
- /**
3395
- * Filters the list of user IDs for the current activity comment item.
3396
- *
3397
- * @since 2.1.0
3398
- *
3399
- * @param array $user_ids Array of user IDs for the current activity comment item.
3400
- * @param array $comments Array of comments being checked for user IDs.
3401
- */
3402
- return apply_filters( 'bp_activity_recurse_comments_user_ids', $user_ids, $comments );
3403
- }
3404
-
3405
- /**
3406
- * Output the mentionname for the displayed user.
3407
- *
3408
- * @since 1.9.0
3409
- */
3410
- function bp_displayed_user_mentionname() {
3411
- echo bp_get_displayed_user_mentionname();
3412
- }
3413
- /**
3414
- * Get the mentionname for the displayed user.
3415
- *
3416
- * @since 1.9.0
3417
- *
3418
- * @return string Mentionname for the displayed user, if available.
3419
- */
3420
- function bp_get_displayed_user_mentionname() {
3421
-
3422
- /**
3423
- * Filters the mentionname for the displayed user.
3424
- *
3425
- * @since 1.9.0
3426
- *
3427
- * @param string $value The mentionanme for the displayed user.
3428
- */
3429
- return apply_filters( 'bp_get_displayed_user_mentionname', bp_activity_get_user_mentionname( bp_displayed_user_id() ) );
3430
- }
3431
-
3432
- /**
3433
- * Echo a list of all registered activity types for use in dropdowns or checkbox lists.
3434
- *
3435
- * @since 1.7.0
3436
- *
3437
- * @param string $output Optional. Either 'select' or 'checkbox'. Default: 'select'.
3438
- * @param array|string $args {
3439
- * Optional extra arguments.
3440
- * @type string $checkbox_name When returning checkboxes, sets the 'name'
3441
- * attribute.
3442
- * @type array|string $selected A list of types that should be checked/
3443
- * selected.
3444
- * }
3445
- */
3446
- function bp_activity_types_list( $output = 'select', $args = '' ) {
3447
-
3448
- $args = bp_parse_args( $args, array(
3449
- 'checkbox_name' => 'bp_activity_types',
3450
- 'selected' => array(),
3451
- ) );
3452
-
3453
- $activities = bp_activity_get_types();
3454
- natsort( $activities );
3455
-
3456
- // Loop through the activity types and output markup.
3457
- foreach ( $activities as $type => $description ) {
3458
-
3459
- // See if we need to preselect the current type.
3460
- $checked = checked( true, in_array( $type, (array) $args['selected'] ), false );
3461
- $selected = selected( true, in_array( $type, (array) $args['selected'] ), false );
3462
-
3463
- // Switch output based on the element.
3464
- switch ( $output ) {
3465
- case 'select' :
3466
- printf( '<option value="%1$s" %2$s>%3$s</option>', esc_attr( $type ), $selected, esc_html( $description ) );
3467
- break;
3468
- case 'checkbox' :
3469
- printf( '<label style="" for="%1$s[]">%2$s<input type="checkbox" id="%1$s[]" name="%1$s[]" value="%3$s" %4$s/></label>', esc_attr( $args['checkbox_name'] ), esc_html( $description ), esc_attr( $args['checkbox_name'] ), esc_attr( $args['checkbox_name'] ), esc_attr( $type ), $checked );
3470
- break;
3471
- }
3472
-
3473
- /**
3474
- * Fires at the end of the listing of activity types.
3475
- *
3476
- * This is a variable action hook. The actual hook to use will depend on the output type specified.
3477
- * Two default hooks are bp_activity_types_list_select and bp_activity_types_list_checkbox.
3478
- *
3479
- * @since 1.7.0
3480
- *
3481
- * @param array $args Array of arguments passed into function.
3482
- * @param string $type Activity type being rendered in the output.
3483
- * @param string $description Description of the activity type being rendered.
3484
- */
3485
- do_action( 'bp_activity_types_list_' . $output, $args, $type, $description );
3486
- }
3487
-
3488
- // Backpat with BP-Default for dropdown boxes only.
3489
- if ( 'select' === $output ) {
3490
- do_action( 'bp_activity_filter_options' );
3491
- }
3492
- }
3493
-
3494
-
3495
- /* RSS Feed Template Tags ****************************************************/
3496
-
3497
- /**
3498
- * Output the sitewide activity feed link.
3499
- *
3500
- * @since 1.0.0
3501
- *
3502
- */
3503
- function bp_sitewide_activity_feed_link() {
3504
- echo bp_get_sitewide_activity_feed_link();
3505
- }
3506
-
3507
- /**
3508
- * Returns the sitewide activity feed link.
3509
- *
3510
- * @since 1.0.0
3511
- *
3512
- *
3513
- * @return string The sitewide activity feed link.
3514
- */
3515
- function bp_get_sitewide_activity_feed_link() {
3516
-
3517
- /**
3518
- * Filters the sidewide activity feed link.
3519
- *
3520
- * @since 1.0.0
3521
- *
3522
- * @param string $value The feed link for sitewide activity.
3523
- */
3524
- return apply_filters( 'bp_get_sitewide_activity_feed_link', bp_get_root_domain() . '/' . bp_get_activity_root_slug() . '/feed/' );
3525
- }
3526
-
3527
- /**
3528
- * Output the member activity feed link.
3529
- *
3530
- * @since 1.2.0
3531
- *
3532
- */
3533
- function bp_member_activity_feed_link() {
3534
- echo bp_get_member_activity_feed_link();
3535
- }
3536
-
3537
- /**
3538
- * Output the member activity feed link.
3539
- *
3540
- * @since 1.0.0
3541
- * @deprecated 1.2.0
3542
- *
3543
- * @todo properly deprecate in favor of bp_member_activity_feed_link().
3544
- *
3545
- */
3546
- function bp_activities_member_rss_link() { echo bp_get_member_activity_feed_link(); }
3547
-
3548
- /**
3549
- * Return the member activity feed link.
3550
- *
3551
- * @since 1.2.0
3552
- *
3553
- *
3554
- * @return string $link The member activity feed link.
3555
- */
3556
- function bp_get_member_activity_feed_link() {
3557
-
3558
- // Single member activity feed link.
3559
- if ( bp_is_profile_component() || bp_is_current_action( 'just-me' ) ) {
3560
- $link = bp_displayed_user_domain() . bp_get_activity_slug() . '/feed/';
3561
-
3562
- // Friend feed link.
3563
- } elseif ( bp_is_active( 'friends' ) && bp_is_current_action( bp_get_friends_slug() ) ) {
3564
- $link = bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_friends_slug() . '/feed/';
3565
-
3566
- // Group feed link.
3567
- } elseif ( bp_is_active( 'groups' ) && bp_is_current_action( bp_get_groups_slug() ) ) {
3568
- $link = bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_groups_slug() . '/feed/';
3569
-
3570
- // Favorites activity feed link.
3571
- } elseif ( 'favorites' === bp_current_action() ) {
3572
- $link = bp_displayed_user_domain() . bp_get_activity_slug() . '/favorites/feed/';
3573
-
3574
- // Mentions activity feed link.
3575
- } elseif ( ( 'mentions' === bp_current_action() ) && bp_activity_do_mentions() ) {
3576
- $link = bp_displayed_user_domain() . bp_get_activity_slug() . '/mentions/feed/';
3577
-
3578
- // No feed link.
3579
- } else {
3580
- $link = '';
3581
- }
3582
-
3583
- /**
3584
- * Filters the member activity feed link.
3585
- *
3586
- * @since 1.0.0
3587
- *
3588
- * @param string $link URL for the member activity feed.
3589
- */
3590
- return apply_filters( 'bp_get_activities_member_rss_link', $link );
3591
- }
3592
-
3593
- /**
3594
- * Return the member activity feed link.
3595
- *
3596
- * @since 1.0.0
3597
- * @deprecated 1.2.0
3598
- *
3599
- * @todo properly deprecate in favor of bp_get_member_activity_feed_link().
3600
- *
3601
- *
3602
- * @return string The member activity feed link.
3603
- */
3604
- function bp_get_activities_member_rss_link() { return bp_get_member_activity_feed_link(); }
3605
-
3606
-
3607
- /** Template tags for RSS feed output ****************************************/
3608
-
3609
- /**
3610
- * Outputs the activity feed item guid.
3611
- *
3612
- * @since 1.0.0
3613
- *
3614
- */
3615
- function bp_activity_feed_item_guid() {
3616
- echo bp_get_activity_feed_item_guid();
3617
- }
3618
-
3619
- /**
3620
- * Returns the activity feed item guid.
3621
- *
3622
- * @since 1.2.0
3623
- *
3624
- * @global object $activities_template {@link BP_Activity_Template}
3625
- *
3626
- * @return string The activity feed item guid.
3627
- */
3628
- function bp_get_activity_feed_item_guid() {
3629
- global $activities_template;
3630
-
3631
- /**
3632
- * Filters the activity feed item guid.
3633
- *
3634
- * @since 1.1.3
3635
- *
3636
- * @param string $value Calculated md5 value for the activity feed item.
3637
- */
3638
- return apply_filters( 'bp_get_activity_feed_item_guid', md5( $activities_template->activity->date_recorded . '-' . $activities_template->activity->content ) );
3639
- }
3640
-
3641
- /**
3642
- * Output the activity feed item title.
3643
- *
3644
- * @since 1.0.0
3645
- *
3646
- */
3647
- function bp_activity_feed_item_title() {
3648
- echo bp_get_activity_feed_item_title();
3649
- }
3650
-
3651
- /**
3652
- * Return the activity feed item title.
3653
- *
3654
- * @since 1.0.0
3655
- *
3656
- * @global object $activities_template {@link BP_Activity_Template}
3657
- *
3658
- * @return string $title The activity feed item title.
3659
- */
3660
- function bp_get_activity_feed_item_title() {
3661
- global $activities_template;
3662
-
3663
- if ( !empty( $activities_template->activity->action ) ) {
3664
- $content = $activities_template->activity->action;
3665
- } else {
3666
- $content = $activities_template->activity->content;
3667
- }
3668
-
3669
- $content = explode( '<span', $content );
3670
- $title = strip_tags( ent2ncr( trim( convert_chars( $content[0] ) ) ) );
3671
-
3672
- if ( ':' === substr( $title, -1 ) ) {
3673
- $title = substr( $title, 0, -1 );
3674
- }
3675
-
3676
- if ( 'activity_update' === $activities_template->activity->type ) {
3677
- $title .= ': ' . strip_tags( ent2ncr( trim( convert_chars( bp_create_excerpt( $activities_template->activity->content, 70, array( 'ending' => " [&#133;]" ) ) ) ) ) );
3678
- }
3679
-
3680
- /**
3681
- * Filters the activity feed item title.
3682
- *
3683
- * @since 1.0.0
3684
- *
3685
- * @param string $title The title for the activity feed item.
3686
- */
3687
- return apply_filters( 'bp_get_activity_feed_item_title', $title );
3688
- }
3689
-
3690
- /**
3691
- * Output the activity feed item link.
3692
- *
3693
- * @since 1.0.0
3694
- *
3695
- */
3696
- function bp_activity_feed_item_link() {
3697
- echo bp_get_activity_feed_item_link();
3698
- }
3699
-
3700
- /**
3701
- * Return the activity feed item link.
3702
- *
3703
- * @since 1.0.0
3704
- *
3705
- * @global object $activities_template {@link BP_Activity_Template}
3706
- *
3707
- * @return string The activity feed item link.
3708
- */
3709
- function bp_get_activity_feed_item_link() {
3710
- global $activities_template;
3711
-
3712
- $retval = ! empty( $activities_template->activity->primary_link )
3713
- ? $activities_template->activity->primary_link
3714
- : '';
3715
-
3716
- /**
3717
- * Filters the activity feed item link.
3718
- *
3719
- * @since 1.0.0
3720
- *
3721
- * @param string $retval The URL for the activity feed item.
3722
- */
3723
- return apply_filters( 'bp_get_activity_feed_item_link', $retval );
3724
- }
3725
-
3726
- /**
3727
- * Output the activity feed item date.
3728
- *
3729
- * @since 1.0.0
3730
- *
3731
- */
3732
- function bp_activity_feed_item_date() {
3733
- echo bp_get_activity_feed_item_date();
3734
- }
3735
-
3736
- /**
3737
- * Return the activity feed item date.
3738
- *
3739
- * @since 1.0.0
3740
- *
3741
- * @global object $activities_template {@link BP_Activity_Template}
3742
- *
3743
- * @return string The activity feed item date.
3744
- */
3745
- function bp_get_activity_feed_item_date() {
3746
- global $activities_template;
3747
-
3748
- $retval = ! empty( $activities_template->activity->date_recorded )
3749
- ? $activities_template->activity->date_recorded
3750
- : '';
3751
-
3752
- /**
3753
- * Filters the activity feed item date.
3754
- *
3755
- * @since 1.0.0
3756
- *
3757
- * @param string $retval The date for the activity feed item.
3758
- */
3759
- return apply_filters( 'bp_get_activity_feed_item_date', $retval );
3760
- }
3761
-
3762
- /**
3763
- * Output the activity feed item description.
3764
- *
3765
- * @since 1.0.0
3766
- *
3767
- */
3768
- function bp_activity_feed_item_description() {
3769
- echo bp_get_activity_feed_item_description();
3770
- }
3771
-
3772
- /**
3773
- * Return the activity feed item description.
3774
- *
3775
- * @since 1.0.0
3776
- *
3777
- * @global object $activities_template {@link BP_Activity_Template}
3778
- *
3779
- * @return string The activity feed item description.
3780
- */
3781
- function bp_get_activity_feed_item_description() {
3782
- global $activities_template;
3783
-
3784
- // Get the content, if exists.
3785
- $content = ! empty( $activities_template->activity->content )
3786
- ? $activities_template->activity->content
3787
- : '';
3788
-
3789
- // Perform a few string conversions on the content, if it's not empty.
3790
- if ( ! empty( $content ) ) {
3791
- $content = ent2ncr( convert_chars( str_replace( '%s', '', $content ) ) );
3792
- }
3793
-
3794
- /**
3795
- * Filters the activity feed item description.
3796
- *
3797
- * @since 1.0.0
3798
- *
3799
- * @param string $content The description for the activity feed item.
3800
- */
3801
- return apply_filters( 'bp_get_activity_feed_item_description', $content );
3802
- }
3803
-
3804
- /**
3805
- * Template tag so we can hook activity feed to <head>.
3806
- *
3807
- * @since 1.5.0
3808
- *
3809
- */
3810
- function bp_activity_sitewide_feed() {
3811
- ?>
3812
-
3813
- <link rel="alternate" type="application/rss+xml" title="<?php bloginfo( 'name' ) ?> | <?php _e( 'Site Wide Activity RSS Feed', 'buddypress' ) ?>" href="<?php bp_sitewide_activity_feed_link() ?>" />
3814
-
3815
- <?php
3816
- }
3817
- add_action( 'bp_head', 'bp_activity_sitewide_feed' );
3818
-
3819
- /**
3820
- * Display available filters depending on the scope.
3821
- *
3822
- * @since 2.1.0
3823
- *
3824
- * @param string $context The current context. 'activity', 'member',
3825
- * 'member_groups', 'group'.
3826
- */
3827
- function bp_activity_show_filters( $context = '' ) {
3828
- echo bp_get_activity_show_filters( $context );
3829
- }
3830
- /**
3831
- * Get available filters depending on the scope.
3832
- *
3833
- * @since 2.1.0
3834
- *
3835
- * @param string $context The current context. 'activity', 'member',
3836
- * 'member_groups', 'group'.
3837
- *
3838
- * @return string HTML for <option> values.
3839
- */
3840
- function bp_get_activity_show_filters( $context = '' ) {
3841
- $filters = array();
3842
- $actions = bp_activity_get_actions_for_context( $context );
3843
- foreach ( $actions as $action ) {
3844
- // Friends activity collapses two filters into one.
3845
- if ( in_array( $action['key'], array( 'friendship_accepted', 'friendship_created' ) ) ) {
3846
- $action['key'] = 'friendship_accepted,friendship_created';
3847
- }
3848
-
3849
- $filters[ $action['key'] ] = $action['label'];
3850
- }
3851
-
3852
- /**
3853
- * Filters the options available in the activity filter dropdown.
3854
- *
3855
- * @since 2.2.0
3856
- *
3857
- * @param array $filters Array of filter options for the given context, in the following format: $option_value => $option_name.
3858
- * @param string $context Context for the filter. 'activity', 'member', 'member_groups', 'group'.
3859
- */
3860
- $filters = apply_filters( 'bp_get_activity_show_filters_options', $filters, $context );
3861
-
3862
- // Build the options output.
3863
- $output = '';
3864
-
3865
- if ( ! empty( $filters ) ) {
3866
- foreach ( $filters as $value => $filter ) {
3867
- $output .= '<option value="' . esc_attr( $value ) . '">' . esc_html( $filter ) . '</option>' . "\n";
3868
- }
3869
- }
3870
-
3871
- /**
3872
- * Filters the HTML markup result for the activity filter dropdown.
3873
- *
3874
- * @since 2.1.0
3875
- *
3876
- * @param string $output HTML output for the activity filter dropdown.
3877
- * @param array $filters Array of filter options for the given context, in the following format: $option_value => $option_name.
3878
- * @param string $context Context for the filter. 'activity', 'member', 'member_groups', 'group'.
3879
- */
3880
- return apply_filters( 'bp_get_activity_show_filters', $output, $filters, $context );
3881
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/bp-activity-templatetags.php ADDED
@@ -0,0 +1,1074 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class BP_Activity_Template {
4
+ var $current_activity = -1;
5
+ var $activity_count;
6
+ var $total_activity_count;
7
+ var $activities;
8
+ var $activity;
9
+
10
+ var $in_the_loop;
11
+
12
+ var $pag_page;
13
+ var $pag_num;
14
+ var $pag_links;
15
+
16
+ var $full_name;
17
+
18
+ function bp_activity_template( $page, $per_page, $max, $include, $sort, $filter, $search_terms, $display_comments, $show_hidden ) {
19
+ global $bp;
20
+
21
+ $this->pag_page = isset( $_REQUEST['acpage'] ) ? intval( $_REQUEST['acpage'] ) : $page;
22
+ $this->pag_num = isset( $_REQUEST['num'] ) ? intval( $_REQUEST['num'] ) : $per_page;
23
+
24
+ // Check if blog/forum replies are disabled
25
+ $this->disable_blogforum_replies = $bp->site_options['bp-disable-blogforum-comments'];
26
+
27
+ // Get an array of the logged in user's favorite activities
28
+ $this->my_favs = maybe_unserialize( get_user_meta( $bp->loggedin_user->id, 'bp_favorite_activities', true ) );
29
+
30
+ // Fetch specific activity items based on ID's
31
+ if ( !empty( $include ) )
32
+ $this->activities = bp_activity_get_specific( array( 'activity_ids' => explode( ',', $include ), 'max' => $max, 'page' => $this->pag_page, 'per_page' => $this->pag_num, 'sort' => $sort, 'display_comments' => $display_comments ) );
33
+ // Fetch all activity items
34
+ else
35
+ $this->activities = bp_activity_get( array( 'display_comments' => $display_comments, 'max' => $max, 'per_page' => $this->pag_num, 'page' => $this->pag_page, 'sort' => $sort, 'search_terms' => $search_terms, 'filter' => $filter, 'show_hidden' => $show_hidden ) );
36
+
37
+ if ( !$max || $max >= (int)$this->activities['total'] )
38
+ $this->total_activity_count = (int)$this->activities['total'];
39
+ else
40
+ $this->total_activity_count = (int)$max;
41
+
42
+ $this->activities = $this->activities['activities'];
43
+
44
+ if ( $max ) {
45
+ if ( $max >= count($this->activities) ) {
46
+ $this->activity_count = count( $this->activities );
47
+ } else {
48
+ $this->activity_count = (int)$max;
49
+ }
50
+ } else {
51
+ $this->activity_count = count( $this->activities );
52
+ }
53
+
54
+ $this->full_name = $bp->displayed_user->fullname;
55
+
56
+ // Fetch parent content for activity comments so we do not have to query in the loop
57
+ foreach ( (array)$this->activities as $activity ) {
58
+ if ( 'activity_comment' != $activity->type )
59
+ continue;
60
+
61
+ $parent_ids[] = $activity->item_id;
62
+ }
63
+
64
+ if ( !empty( $parent_ids ) )
65
+ $activity_parents = bp_activity_get_specific( array( 'activity_ids' => $parent_ids ) );
66
+
67
+ if ( !empty( $activity_parents['activities'] ) ) {
68
+ foreach( $activity_parents['activities'] as $parent )
69
+ $this->activity_parents[$parent->id] = $parent;
70
+
71
+ unset( $activity_parents );
72
+ }
73
+
74
+ if ( (int)$this->total_activity_count && (int)$this->pag_num ) {
75
+ $this->pag_links = paginate_links( array(
76
+ 'base' => add_query_arg( 'acpage', '%#%' ),
77
+ 'format' => '',
78
+ 'total' => ceil( (int)$this->total_activity_count / (int)$this->pag_num ),
79
+ 'current' => (int)$this->pag_page,
80
+ 'prev_text' => '&larr;',
81
+ 'next_text' => '&rarr;',
82
+ 'mid_size' => 1
83
+ ) );
84
+ }
85
+ }
86
+
87
+ function has_activities() {
88
+ if ( $this->activity_count )
89
+ return true;
90
+
91
+ return false;
92
+ }
93
+
94
+ function next_activity() {
95
+ $this->current_activity++;
96
+ $this->activity = $this->activities[$this->current_activity];
97
+
98
+ return $this->activity;
99
+ }
100
+
101
+ function rewind_activities() {
102
+ $this->current_activity = -1;
103
+ if ( $this->activity_count > 0 ) {
104
+ $this->activity = $this->activities[0];
105
+ }
106
+ }
107
+
108
+ function user_activities() {
109
+ if ( $this->current_activity + 1 < $this->activity_count ) {
110
+ return true;
111
+ } elseif ( $this->current_activity + 1 == $this->activity_count ) {
112
+ do_action('activity_loop_end');
113
+ // Do some cleaning up after the loop
114
+ $this->rewind_activities();
115
+ }
116
+
117
+ $this->in_the_loop = false;
118
+ return false;
119
+ }
120
+
121
+ function the_activity() {
122
+ global $activity;
123
+
124
+ $this->in_the_loop = true;
125
+ $this->activity = $this->next_activity();
126
+
127
+ if ( is_array( $this->activity ) )
128
+ $this->activity = (object) $this->activity;
129
+
130
+ if ( $this->current_activity == 0 ) // loop has just started
131
+ do_action('activity_loop_start');
132
+ }
133
+ }
134
+
135
+ function bp_has_activities( $args = '' ) {
136
+ global $bp, $activities_template;
137
+
138
+ /***
139
+ * Set the defaults based on the current page. Any of these will be overridden
140
+ * if arguments are directly passed into the loop. Custom plugins should always
141
+ * pass their parameters directly to the loop.
142
+ */
143
+ $user_id = false;
144
+ $include = false;
145
+ $show_hidden = false;
146
+ $object = false;
147
+ $primary_id = false;
148
+
149
+ /* User filtering */
150
+ if ( !empty( $bp->displayed_user->id ) )
151
+ $user_id = $bp->displayed_user->id;
152
+
153
+ /* Group filtering */
154
+ if ( !empty( $bp->groups->current_group ) ) {
155
+ $object = $bp->groups->id;
156
+ $primary_id = $bp->groups->current_group->id;
157
+
158
+ if ( 'public' != $bp->groups->current_group->status && ( groups_is_user_member( $bp->loggedin_user->id, $bp->groups->current_group->id ) || $bp->loggedin_user->is_super_admin ) )
159
+ $show_hidden = true;
160
+ }
161
+
162
+ /* Support for permalinks on single item pages: /groups/my-group/activity/124/ */
163
+ if ( $bp->current_action == $bp->activity->slug )
164
+ $include = $bp->action_variables[0];
165
+
166
+ /* Note: any params used for filtering can be a single value, or multiple values comma separated. */
167
+ $defaults = array(
168
+ 'display_comments' => 'threaded', // false for none, stream/threaded - show comments in the stream or threaded under items
169
+ 'include' => $include, // pass an activity_id or string of ID's comma separated
170
+ 'sort' => 'DESC', // sort DESC or ASC
171
+ 'page' => 1, // which page to load
172
+ 'per_page' => 20, // number of items per page
173
+ 'max' => false, // max number to return
174
+ 'show_hidden' => $show_hidden, // Show activity items that are hidden site-wide?
175
+
176
+ /* Scope - pre-built activity filters for a user (friends/groups/favorites/mentions) */
177
+ 'scope' => $bp->current_action,
178
+
179
+ /* Filtering */
180
+ 'user_id' => $user_id, // user_id to filter on
181
+ 'object' => $object, // object to filter on e.g. groups, profile, status, friends
182
+ 'action' => false, // action to filter on e.g. activity_update, new_forum_post, profile_updated
183
+ 'primary_id' => $primary_id, // object ID to filter on e.g. a group_id or forum_id or blog_id etc.
184
+ 'secondary_id' => false, // secondary object ID to filter on e.g. a post_id
185
+
186
+ /* Searching */
187
+ 'search_terms' => false // specify terms to search on
188
+ );
189
+
190
+ $r = wp_parse_args( $args, $defaults );
191
+ extract( $r );
192
+
193
+ /* If you have passed a "scope" then this will override any filters you have passed. */
194
+ if ( 'just-me' == $scope || 'friends' == $scope || 'groups' == $scope || 'favorites' == $scope || 'mentions' == $scope ) {
195
+ if ( 'just-me' == $scope )
196
+ $display_comments = 'stream';
197
+
198
+ if ( $user_id = ( !empty( $bp->displayed_user->id ) ) ? $bp->displayed_user->id : $bp->loggedin_user->id ) {
199
+ $show_hidden = ( $user_id == $bp->loggedin_user->id && $scope != 'friends' ) ? 1 : 0;
200
+
201
+ switch ( $scope ) {
202
+ case 'friends':
203
+ if ( function_exists( 'friends_get_friend_user_ids' ) )
204
+ $friends = friends_get_friend_user_ids( $user_id );
205
+ if ( empty( $friends ) )
206
+ return false;
207
+
208
+ $user_id = implode( ',', (array)$friends );
209
+ break;
210
+ case 'groups':
211
+ if ( function_exists( 'groups_get_user_groups' ) ) {
212
+ $groups = groups_get_user_groups( $user_id );
213
+ if ( empty( $groups['groups'] ) )
214
+ return false;
215
+
216
+ $object = $bp->groups->id;
217
+ $primary_id = implode( ',', (array)$groups['groups'] );
218
+
219
+ $user_id = false;
220
+ }
221
+ break;
222
+ case 'favorites':
223
+ $favs = bp_activity_get_user_favorites( $user_id );
224
+ if ( empty( $favs ) )
225
+ return false;
226
+
227
+ $include = implode( ',', (array)$favs );
228
+ break;
229
+ case 'mentions':
230
+ $user_nicename = ( !empty( $bp->displayed_user->id ) ) ? $bp->displayed_user->userdata->user_nicename : $bp->loggedin_user->userdata->user_nicename;
231
+ $user_login = ( !empty( $bp->displayed_user->id ) ) ? $bp->displayed_user->userdata->user_login : $bp->loggedin_user->userdata->user_login;
232
+ $search_terms = '@' . bp_core_get_username( $user_id, $user_nicename, $user_login ) . '<'; // Start search at @ symbol and stop search at closing tag delimiter.
233
+ $display_comments = 'stream';
234
+ $user_id = false;
235
+ break;
236
+ }
237
+ }
238
+ }
239
+
240
+ if ( $max ) {
241
+ if ( $per_page > $max )
242
+ $per_page = $max;
243
+ }
244
+
245
+ /* Support for basic filters in earlier BP versions. */
246
+ $filter = false;
247
+ if ( isset( $_GET['afilter'] ) )
248
+ $filter = array( 'object' => $_GET['afilter'] );
249
+ else if ( !empty( $user_id ) || !empty( $object ) || !empty( $action ) || !empty( $primary_id ) || !empty( $secondary_id ) )
250
+ $filter = array( 'user_id' => $user_id, 'object' => $object, 'action' => $action, 'primary_id' => $primary_id, 'secondary_id' => $secondary_id );
251
+
252
+ $activities_template = new BP_Activity_Template( $page, $per_page, $max, $include, $sort, $filter, $search_terms, $display_comments, $show_hidden );
253
+
254
+ return apply_filters( 'bp_has_activities', $activities_template->has_activities(), &$activities_template );
255
+ }
256
+
257
+ function bp_activities() {
258
+ global $activities_template;
259
+ return $activities_template->user_activities();
260
+ }
261
+
262
+ function bp_the_activity() {
263
+ global $activities_template;
264
+ return $activities_template->the_activity();
265
+ }
266
+
267
+ function bp_activity_pagination_count() {
268
+ echo bp_get_activity_pagination_count();
269
+ }
270
+ function bp_get_activity_pagination_count() {
271
+ global $bp, $activities_template;
272
+
273
+ $start_num = intval( ( $activities_template->pag_page - 1 ) * $activities_template->pag_num ) + 1;
274
+ $from_num = bp_core_number_format( $start_num );
275
+ $to_num = bp_core_number_format( ( $start_num + ( $activities_template->pag_num - 1 ) > $activities_template->total_activity_count ) ? $activities_template->total_activity_count : $start_num + ( $activities_template->pag_num - 1 ) );
276
+ $total = bp_core_number_format( $activities_template->total_activity_count );
277
+
278
+ return sprintf( __( 'Viewing item %1$s to %2$s (of %3$s items)', 'buddypress' ), $from_num, $to_num, $total ) . ' &nbsp; <span class="ajax-loader"></span>';
279
+ }
280
+
281
+ function bp_activity_pagination_links() {
282
+ echo bp_get_activity_pagination_links();
283
+ }
284
+ function bp_get_activity_pagination_links() {
285
+ global $activities_template;
286
+
287
+ return apply_filters( 'bp_get_activity_pagination_links', $activities_template->pag_links );
288
+ }
289
+
290
+ function bp_activity_count() {
291
+ echo bp_get_activity_count();
292
+ }
293
+ function bp_get_activity_count() {
294
+ global $activities_template;
295
+
296
+ return apply_filters( 'bp_get_activity_count', (int)$activities_template->activity_count );
297
+ }
298
+
299
+ function bp_activity_per_page() {
300
+ echo bp_get_activity_per_page();
301
+ }
302
+ function bp_get_activity_per_page() {
303
+ global $activities_template;
304
+
305
+ return apply_filters( 'bp_get_activity_per_page', (int)$activities_template->pag_num );
306
+ }
307
+
308
+ function bp_activities_title() {
309
+ global $bp_activity_title;
310
+
311
+ echo bp_get_activities_title();
312
+ }
313
+ function bp_get_activities_title() {
314
+ global $bp_activity_title;
315
+
316
+ return apply_filters( 'bp_get_activities_title', $bp_activity_title );
317
+ }
318
+
319
+ function bp_activities_no_activity() {
320
+ global $bp_activity_no_activity;
321
+
322
+ echo bp_get_activities_no_activity();
323
+ }
324
+ function bp_get_activities_no_activity() {
325
+ global $bp_activity_no_activity;
326
+
327
+ return apply_filters( 'bp_get_activities_no_activity', $bp_activity_no_activity );
328
+ }
329
+
330
+ function bp_activity_id() {
331
+ echo bp_get_activity_id();
332
+ }
333
+ function bp_get_activity_id() {
334
+ global $activities_template;
335
+ return apply_filters( 'bp_get_activity_id', $activities_template->activity->id );
336
+ }
337
+
338
+ function bp_activity_item_id() {
339
+ echo bp_get_activity_item_id();
340
+ }
341
+ function bp_get_activity_item_id() {
342
+ global $activities_template;
343
+ return apply_filters( 'bp_get_activity_item_id', $activities_template->activity->item_id );
344
+ }
345
+
346
+ function bp_activity_secondary_item_id() {
347
+ echo bp_get_activity_secondary_item_id();
348
+ }
349
+ function bp_get_activity_secondary_item_id() {
350
+ global $activities_template;
351
+ return apply_filters( 'bp_get_activity_secondary_item_id', $activities_template->activity->secondary_item_id );
352
+ }
353
+
354
+ function bp_activity_date_recorded() {
355
+ echo bp_get_activity_date_recorded();
356
+ }
357
+ function bp_get_activity_date_recorded() {
358
+ global $activities_template;
359
+ return apply_filters( 'bp_get_activity_date_recorded', $activities_template->activity->date_recorded );
360
+ }
361
+
362
+ function bp_activity_object_name() {
363
+ echo bp_get_activity_object_name();
364
+ }
365
+ function bp_get_activity_object_name() {
366
+ global $activities_template;
367
+ return apply_filters( 'bp_get_activity_object_name', $activities_template->activity->component );
368
+ }
369
+
370
+ function bp_activity_type() {
371
+ echo bp_get_activity_type();
372
+ }
373
+ function bp_get_activity_type() {
374
+ global $activities_template;
375
+ return apply_filters( 'bp_get_activity_type', $activities_template->activity->type );
376
+ }
377
+ function bp_activity_action_name() { echo bp_activity_type(); }
378
+ function bp_get_activity_action_name() { return bp_get_activity_type(); }
379
+
380
+ function bp_activity_user_id() {
381
+ echo bp_get_activity_user_id();
382
+ }
383
+ function bp_get_activity_user_id() {
384
+ global $activities_template;
385
+ return apply_filters( 'bp_get_activity_user_id', $activities_template->activity->user_id );
386
+ }
387
+
388
+ function bp_activity_user_link() {
389
+ echo bp_get_activity_user_link();
390
+ }
391
+ function bp_get_activity_user_link() {
392
+ global $activities_template;
393
+
394
+ if ( empty( $activities_template->activity->user_id ) )
395
+ $link = $activities_template->activity->primary_link;
396
+ else
397
+ $link = bp_core_get_user_domain( $activities_template->activity->user_id, $activities_template->activity->user_nicename, $activities_template->activity->user_login );
398
+
399
+ return apply_filters( 'bp_get_activity_user_link', $link );
400
+ }
401
+
402
+ /**
403
+ * bp_activity_avatar( $args )
404
+ *
405
+ * Output the avatar of the user that performed the action
406
+ *
407
+ * @param array $args
408
+ */
409
+ function bp_activity_avatar( $args = '' ) {
410
+ echo bp_get_activity_avatar( $args );
411
+ }
412
+ /**
413
+ * bp_get_activity_avatar( $args )
414
+ *
415
+ * Return the avatar of the user that performed the action
416
+ *
417
+ * @global array $bp
418
+ * @global object $activities_template
419
+ * @param array $args optional
420
+ * @return string
421
+ */
422
+ function bp_get_activity_avatar( $args = '' ) {
423
+ global $bp, $activities_template;
424
+
425
+ $defaults = array(
426
+ 'type' => 'thumb',
427
+ 'width' => 20,
428
+ 'height' => 20,
429
+ 'class' => 'avatar',
430
+ 'alt' => __( 'Avatar', 'buddypress' ),
431
+ 'email' => false
432
+ );
433
+
434
+ $r = wp_parse_args( $args, $defaults );
435
+ extract( $r, EXTR_SKIP );
436
+
437
+ // Primary activity avatar is always a user, but can be modified via a filter
438
+ $object = apply_filters( 'bp_get_activity_avatar_object_' . $activities_template->activity->component, 'user' );
439
+ $item_id = apply_filters( 'bp_get_activity_avatar_item_id', $activities_template->activity->user_id );
440
+
441
+ // If this is a user object pass the users' email address for Gravatar so we don't have to refetch it.
442
+ if ( 'user' == $object && empty( $email ) )
443
+ $email = $activities_template->activity->user_email;
444
+
445
+ return apply_filters( 'bp_get_activity_avatar', bp_core_fetch_avatar( array( 'item_id' => $item_id, 'object' => $object, 'type' => $type, 'alt' => $alt, 'class' => $class, 'width' => $width, 'height' => $height, 'email' => $email ) ) );
446
+ }
447
+
448
+ /**
449
+ * bp_activity_secondary_avatar( $args )
450
+ *
451
+ * Output the avatar of the object that action was performed on
452
+ *
453
+ * @param array $args optional
454
+ */
455
+ function bp_activity_secondary_avatar( $args = '' ) {
456
+ echo bp_get_activity_secondary_avatar( $args );
457
+ }
458
+ /**
459
+ * bp_get_activity_secondary_avatar( $args )
460
+ *
461
+ * Return the avatar of the object that action was performed on
462
+ *
463
+ * @global array $bp
464
+ * @global object $activities_template
465
+ * @param array $args optional
466
+ * @return string
467
+ */
468
+ function bp_get_activity_secondary_avatar( $args = '' ) {
469
+ global $bp, $activities_template;
470
+
471
+ $defaults = array(
472
+ 'type' => 'thumb',
473
+ 'width' => 20,
474
+ 'height' => 20,
475
+ 'class' => 'avatar',
476
+ 'alt' => __( 'Avatar', 'buddypress' ),
477
+ 'email' => false
478
+ );
479
+
480
+ $r = wp_parse_args( $args, $defaults );
481
+ extract( $r, EXTR_SKIP );
482
+
483
+ // Set item_id and object (default to user)
484
+ switch ( $activities_template->activity->component ) {
485
+ case 'groups' :
486
+ $object = 'group';
487
+ $item_id = $activities_template->activity->item_id;
488
+ break;
489
+ case 'blogs' :
490
+ $object = 'blog';
491
+ $item_id = $activities_template->activity->item_id;
492
+ break;
493
+ case 'friends' :
494
+ $object = 'user';
495
+ $item_id = $activities_template->activity->secondary_item_id;
496
+ break;
497
+ default :
498
+ $object = 'user';
499
+ $item_id = $activities_template->activity->user_id;
500
+ $email = $activities_template->activity->user_email;
501
+ break;
502
+ }
503
+
504
+ // Allow object and item_id to be filtered
505
+ $object = apply_filters( 'bp_get_activity_secondary_avatar_object_' . $activities_template->activity->component, $object );
506
+ $item_id = apply_filters( 'bp_get_activity_secondary_avatar_item_id', $item_id );
507
+
508
+ // If we have no item_id or object, there is no avatar to display
509
+ if ( empty( $item_id ) || empty( $object ) )
510
+ return false;
511
+
512
+ return apply_filters( 'bp_get_activity_secondary_avatar', bp_core_fetch_avatar( array( 'item_id' => $item_id, 'object' => $object, 'type' => $type, 'alt' => $alt, 'class' => $class, 'width' => $width, 'height' => $height, 'email' => $email ) ) );
513
+ }
514
+
515
+ function bp_activity_action() {
516
+ echo bp_get_activity_action();
517
+ }
518
+ function bp_get_activity_action() {
519
+ global $activities_template;
520
+
521
+ $action = $activities_template->activity->action;
522
+
523
+ $action = apply_filters( 'bp_get_activity_action_pre_meta', $action, &$activities_template->activity );
524
+
525
+ if ( !empty( $action ) )
526
+ $action = bp_insert_activity_meta( $action );
527
+
528
+ return apply_filters( 'bp_get_activity_action', $action, &$activities_template->activity );
529
+ }
530
+
531
+ function bp_activity_content_body() {
532
+ echo bp_get_activity_content_body();
533
+ }
534
+ function bp_get_activity_content_body() {
535
+ global $activities_template;
536
+
537
+ /* Backwards compatibility if action is not being used */
538
+ if ( empty( $activities_template->activity->action ) && !empty( $activities_template->activity->content ) )
539
+ $activities_template->activity->content = bp_insert_activity_meta( $activities_template->activity->content );
540
+
541
+ return apply_filters( 'bp_get_activity_content_body', $activities_template->activity->content, &$activities_template->activity );
542
+ }
543
+
544
+ function bp_activity_has_content() {
545
+ global $activities_template;
546
+
547
+ if ( !empty( $activities_template->activity->content ) )
548
+ return true;
549
+
550
+ return false;
551
+ }
552
+
553
+ function bp_activity_content() {
554
+ echo bp_get_activity_content();
555
+ }
556
+ function bp_get_activity_content() {
557
+ global $activities_template;
558
+
559
+ /***
560
+ * If you want to filter activity update content, please use
561
+ * the filter 'bp_get_activity_content_body'
562
+ *
563
+ * This function is mainly for backwards comptibility.
564
+ */
565
+
566
+ $content = bp_get_activity_action() . ' ' . bp_get_activity_content_body();
567
+ return apply_filters( 'bp_get_activity_content', $content );
568
+ }
569
+
570
+ function bp_insert_activity_meta( $content ) {
571
+ global $activities_template, $bp;
572
+
573
+ /* Strip any legacy time since placeholders -- TODO: Remove this in 1.3 */
574
+ $content = str_replace( '<span class="time-since">%s</span>', '', $content );
575
+
576
+ /* Insert the time since. */
577
+ $content .= ' ' . apply_filters( 'bp_activity_time_since', '<span class="time-since">' . sprintf( __( '&nbsp; %s ago', 'buddypress' ), bp_core_time_since( $activities_template->activity->date_recorded ) ) . '</span>', &$activities_template->activity );
578
+
579
+ /* Insert the permalink */
580
+ $content .= apply_filters( 'bp_activity_permalink', ' &middot; <a href="' . bp_activity_get_permalink( $activities_template->activity->id, $activities_template->activity ) . '" class="view" title="' . __( 'View Thread / Permalink', 'buddypress' ) . '">' . __( 'View', 'buddypress' ) . '</a>', &$activities_template->activity );
581
+
582
+ /* Add the delete link if the user has permission on this item */
583
+ if ( ( is_user_logged_in() && $activities_template->activity->user_id == $bp->loggedin_user->id ) || $bp->is_item_admin || $bp->loggedin_user->is_super_admin )
584
+ $content .= apply_filters( 'bp_activity_delete_link', ' &middot; ' . bp_get_activity_delete_link(), &$activities_template->activity );
585
+
586
+ return apply_filters( 'bp_insert_activity_meta', $content );
587
+ }
588
+
589
+ function bp_activity_parent_content( $args = '' ) {
590
+ echo bp_get_activity_parent_content($args);
591
+ }
592
+ function bp_get_activity_parent_content( $args = '' ) {
593
+ global $bp, $activities_template;
594
+
595
+ $defaults = array(
596
+ 'hide_user' => false
597
+ );
598
+
599
+ $r = wp_parse_args( $args, $defaults );
600
+ extract( $r, EXTR_SKIP );
601
+
602
+ /* Get the ID of the parent activity content */
603
+ if ( !$parent_id = $activities_template->activity->item_id )
604
+ return false;
605
+
606
+ /* Get the content of the parent */
607
+ if ( empty( $activities_template->activity_parents[$parent_id] ) )
608
+ return false;
609
+
610
+ if ( empty( $activities_template->activity_parents[$parent_id]->content ) )
611
+ $content = $activities_template->activity_parents[$parent_id]->action;
612
+ else
613
+ $content = $activities_template->activity_parents[$parent_id]->action . ' ' . $activities_template->activity_parents[$parent_id]->content;
614
+
615
+ /* Remove the time since content for backwards compatibility */
616
+ $content = str_replace( '<span class="time-since">%s</span>', '', $content );
617
+
618
+ /* Remove images */
619
+ $content = preg_replace( '/<img[^>]*>/Ui', '', $content );
620
+
621
+ return apply_filters( 'bp_get_activity_parent_content', $content );
622
+ }
623
+
624
+ function bp_activity_is_favorite() {
625
+ echo bp_get_activity_is_favorite();
626
+ }
627
+ function bp_get_activity_is_favorite() {
628
+ global $bp, $activities_template;
629
+
630
+ return apply_filters( 'bp_get_activity_is_favorite', in_array( $activities_template->activity->id, (array)$activities_template->my_favs ) );
631
+ }
632
+
633
+ function bp_activity_comments( $args = '' ) {
634
+ echo bp_activity_get_comments( $args );
635
+ }
636
+ function bp_activity_get_comments( $args = '' ) {
637
+ global $activities_template, $bp;
638
+
639
+ if ( !$activities_template->activity->children )
640
+ return false;
641
+
642
+ $comments_html = bp_activity_recurse_comments( $activities_template->activity );
643
+
644
+ return apply_filters( 'bp_activity_get_comments', $comments_html );
645
+ }
646
+ /* TODO: The HTML in this function is temporary and will be moved to the template in a future version. */
647
+ function bp_activity_recurse_comments( $comment ) {
648
+ global $activities_template, $bp;
649
+
650
+ if ( !$comment->children )
651
+ return false;
652
+
653
+ $content .= '<ul>';
654
+ foreach ( (array)$comment->children as $comment ) {
655
+ if ( !$comment->user_fullname )
656
+ $comment->user_fullname = $comment->display_name;
657
+
658
+ $content .= '<li id="acomment-' . $comment->id . '">';
659
+ $content .= '<div class="acomment-avatar"><a href="' . bp_core_get_user_domain( $comment->user_id, $comment->user_nicename, $comment->user_login ) . '">' . bp_core_fetch_avatar( array( 'item_id' => $comment->user_id, 'width' => 20, 'height' => 20, 'email' => $comment->user_email ) ) . '</a></div>';
660
+ $content .= '<div class="acomment-meta"><a href="' . bp_core_get_user_domain( $comment->user_id, $comment->user_nicename, $comment->user_login ) . '">' . apply_filters( 'bp_acomment_name', $comment->user_fullname, $comment ) . '</a> &middot; ' . sprintf( __( '%s ago', 'buddypress' ), bp_core_time_since( $comment->date_recorded ) );
661
+
662
+ /* Reply link - the span is so that threaded reply links can be hidden when JS is off. */
663
+ if ( is_user_logged_in() )
664
+ $content .= '<span class="acomment-replylink"> &middot; <a href="#acomment-' . $comment->id . '" class="acomment-reply" id="acomment-reply-' . $activities_template->activity->id . '">' . __( 'Reply', 'buddypress' ) . '</a></span>';
665
+
666
+ /* Delete link */
667
+ if ( $bp->loggedin_user->is_super_admin || $bp->loggedin_user->id == $comment->user_id )
668
+ $content .= ' &middot; <a href="' . wp_nonce_url( $bp->root_domain . '/' . $bp->activity->slug . '/delete/?cid=' . $comment->id, 'bp_activity_delete_link' ) . '" class="delete acomment-delete">' . __( 'Delete', 'buddypress' ) . '</a>';
669
+
670
+ $content .= '</div>';
671
+ $content .= '<div class="acomment-content">' . apply_filters( 'bp_get_activity_content', $comment->content ) . '</div>';
672
+
673
+ $content .= bp_activity_recurse_comments( $comment );
674
+ $content .= '</li>';
675
+ }
676
+ $content .= '</ul>';
677
+
678
+ return apply_filters( 'bp_activity_recurse_comments', $content );
679
+ }
680
+
681
+ function bp_activity_comment_count() {
682
+ echo bp_activity_get_comment_count();
683
+ }
684
+ function bp_activity_get_comment_count( $args = '' ) {
685
+ global $activities_template, $bp;
686
+
687
+ if ( !$activities_template->activity->children )
688
+ return 0;
689
+
690
+ $count = bp_activity_recurse_comment_count( $activities_template->activity );
691
+
692
+ return apply_filters( 'bp_activity_get_comment_count', (int)$count );
693
+ }
694
+ function bp_activity_recurse_comment_count( $comment, $count = 0 ) {
695
+ global $activities_template, $bp;
696
+
697
+ if ( !$comment->children )
698
+ return $count;
699
+
700
+ foreach ( (array)$comment->children as $comment ) {
701
+ $count++;
702
+ $count = bp_activity_recurse_comment_count( $comment, $count );
703
+ }
704
+
705
+ return $count;
706
+ }
707
+
708
+ function bp_activity_comment_link() {
709
+ echo bp_get_activity_comment_link();
710
+ }
711
+ function bp_get_activity_comment_link() {
712
+ global $activities_template;
713
+ return apply_filters( 'bp_get_activity_comment_link', '?ac=' . $activities_template->activity->id . '/#ac-form-' . $activities_template->activity->id );
714
+ }
715
+
716
+ function bp_activity_comment_form_nojs_display() {
717
+ echo bp_get_activity_comment_form_nojs_display();
718
+ }
719
+ function bp_get_activity_comment_form_nojs_display() {
720
+ global $activities_template;
721
+ if ( $_GET['ac'] == $activities_template->activity->id . '/' )
722
+ return 'style="display: block"';
723
+
724
+ return false;
725
+ }
726
+
727
+ function bp_activity_comment_form_action() {
728
+ echo bp_get_activity_comment_form_action();
729
+ }
730
+ function bp_get_activity_comment_form_action() {
731
+ return apply_filters( 'bp_get_activity_comment_form_action', site_url( BP_ACTIVITY_SLUG . '/reply/' ) );
732
+ }
733
+
734
+ function bp_activity_permalink_id() {
735
+ echo bp_get_activity_permalink_id();
736
+ }
737
+ function bp_get_activity_permalink_id() {
738
+ global $bp;
739
+
740
+ return apply_filters( 'bp_get_activity_permalink_id', $bp->current_action );
741
+ }
742
+
743
+ function bp_activity_thread_permalink() {
744
+ echo bp_get_activity_thread_permalink();
745
+ }
746
+ function bp_get_activity_thread_permalink() {
747
+ global $bp, $activities_template;
748
+
749
+ $link = bp_activity_get_permalink( $activities_template->activity->id, $activities_template->activity );
750
+
751
+ return apply_filters( 'bp_get_activity_thread_permalink', $link );
752
+ }
753
+
754
+ function bp_activity_favorite_link() {
755
+ echo bp_get_activity_favorite_link();
756
+ }
757
+ function bp_get_activity_favorite_link() {
758
+ global $activities_template;
759
+ return apply_filters( 'bp_get_activity_favorite_link', wp_nonce_url( site_url( BP_ACTIVITY_SLUG . '/favorite/' . $activities_template->activity->id . '/' ), 'mark_favorite' ) );
760
+ }
761
+
762
+ function bp_activity_unfavorite_link() {
763
+ echo bp_get_activity_unfavorite_link();
764
+ }
765
+ function bp_get_activity_unfavorite_link() {
766
+ global $activities_template;
767
+ return apply_filters( 'bp_get_activity_unfavorite_link', wp_nonce_url( site_url( BP_ACTIVITY_SLUG . '/unfavorite/' . $activities_template->activity->id . '/' ), 'unmark_favorite' ) );
768
+ }
769
+
770
+ function bp_activity_css_class() {
771
+ echo bp_get_activity_css_class();
772
+ }
773
+ function bp_get_activity_css_class() {
774
+ global $activities_template;
775
+
776
+ $mini_activity_actions = apply_filters( 'bp_activity_mini_activity_types', array(
777
+ 'friendship_accepted',
778
+ 'friendship_created',
779
+ 'new_blog',
780
+ 'joined_group',
781
+ 'created_group',
782
+ 'new_member'
783
+ ) );
784
+
785
+ $class = '';
786
+ if ( in_array( $activities_template->activity->type, (array)$mini_activity_actions ) || empty( $activities_template->activity->content ) )
787
+ $class = ' mini';
788
+
789
+ if ( bp_activity_get_comment_count() && bp_activity_can_comment() )
790
+ $class .= ' has-comments';
791
+
792
+ return apply_filters( 'bp_get_activity_css_class', $activities_template->activity->component . ' ' . $activities_template->activity->type . $class );
793
+ }
794
+
795
+ function bp_activity_delete_link() {
796
+ echo bp_get_activity_delete_link();
797
+ }
798
+ function bp_get_activity_delete_link() {
799
+ global $activities_template, $bp;
800
+
801
+ return apply_filters( 'bp_get_activity_delete_link', '<a href="' . wp_nonce_url( $bp->root_domain . '/' . $bp->activity->slug . '/delete/' . $activities_template->activity->id, 'bp_activity_delete_link' ) . '" class="item-button delete-activity confirm">' . __( 'Delete', 'buddypress' ) . '</a>' );
802
+ }
803
+
804
+ function bp_activity_latest_update( $user_id = false ) {
805
+ echo bp_get_activity_latest_update( $user_id );
806
+ }
807
+ function bp_get_activity_latest_update( $user_id = false ) {
808
+ global $bp;
809
+
810
+ if ( !$user_id )
811
+ $user_id = $bp->displayed_user->id;
812
+
813
+ if ( !$update = get_user_meta( $user_id, 'bp_latest_update', true ) )
814
+ return false;
815
+
816
+ $latest_update = '&quot;' . apply_filters( 'bp_get_activity_latest_update_excerpt', trim( strip_tags( bp_create_excerpt( $update['content'], 40 ) ) ) ) . '&quot;';
817
+ $latest_update .= ' &middot; <a href="' . $bp->root_domain . '/' . BP_ACTIVITY_SLUG . '/p/' . $update['id'] . '/"> ' . __( 'View', 'buddypress' ) . '</a>';
818
+
819
+ return apply_filters( 'bp_get_activity_latest_update', $latest_update );
820
+ }
821
+
822
+ function bp_activity_filter_links( $args = false ) {
823
+ echo bp_get_activity_filter_links( $args );
824
+ }
825
+ function bp_get_activity_filter_links( $args = false ) {
826
+ global $activities_template, $bp;
827
+
828
+ $defaults = array(
829
+ 'style' => 'list'
830
+ );
831
+
832
+ $r = wp_parse_args( $args, $defaults );
833
+ extract( $r, EXTR_SKIP );
834
+
835
+ /* Fetch the names of components that have activity recorded in the DB */
836
+ $components = BP_Activity_Activity::get_recorded_components();
837
+
838
+ if ( !$components )
839
+ return false;
840
+
841
+ foreach ( (array) $components as $component ) {
842
+ /* Skip the activity comment filter */
843
+ if ( 'activity' == $component )
844
+ continue;
845
+
846
+ if ( isset( $_GET['afilter'] ) && $component == $_GET['afilter'] )
847
+ $selected = ' class="selected"';
848
+ else
849
+ unset($selected);
850
+
851
+ $component = esc_attr( $component );
852
+
853
+ switch ( $style ) {
854
+ case 'list':
855
+ $tag = 'li';
856
+ $before = '<li id="afilter-' . $component . '"' . $selected . '>';
857
+ $after = '</li>';
858
+ break;
859
+ case 'paragraph':
860
+ $tag = 'p';
861
+ $before = '<p id="afilter-' . $component . '"' . $selected . '>';
862
+ $after = '</p>';
863
+ break;
864
+ case 'span':
865
+ $tag = 'span';
866
+ $before = '<span id="afilter-' . $component . '"' . $selected . '>';
867
+ $after = '</span>';
868
+ break;
869
+ }
870
+
871
+ $link = add_query_arg( 'afilter', $component );
872
+ $link = remove_query_arg( 'acpage' , $link );
873
+
874
+ $link = apply_filters( 'bp_get_activity_filter_link_href', $link, $component );
875
+
876
+ /* Make sure all core internal component names are translatable */
877
+ $translatable_components = array( __( 'profile', 'buddypress'), __( 'friends', 'buddypress' ), __( 'groups', 'buddypress' ), __( 'status', 'buddypress' ), __( 'blogs', 'buddypress' ) );
878
+
879
+ $component_links[] = $before . '<a href="' . esc_attr( $link ) . '">' . ucwords( __( $component, 'buddypress' ) ) . '</a>' . $after;
880
+ }
881
+
882
+ $link = remove_query_arg( 'afilter' , $link );
883
+
884
+ if ( isset( $_GET['afilter'] ) )
885
+ $component_links[] = '<' . $tag . ' id="afilter-clear"><a href="' . esc_attr( $link ) . '"">' . __( 'Clear Filter', 'buddypress' ) . '</a></' . $tag . '>';
886
+
887
+ return apply_filters( 'bp_get_activity_filter_links', implode( "\n", $component_links ) );
888
+ }
889
+
890
+ function bp_activity_can_comment() {
891
+ global $activities_template, $bp;
892
+
893
+ if ( false === $activities_template->disable_blogforum_replies || (int)$activities_template->disable_blogforum_replies ) {
894
+ if ( 'new_blog_post' == bp_get_activity_action_name() || 'new_blog_comment' == bp_get_activity_action_name() || 'new_forum_topic' == bp_get_activity_action_name() || 'new_forum_post' == bp_get_activity_action_name() )
895
+ return false;
896
+ }
897
+
898
+ if ( 'activity_comment' == bp_get_activity_action_name() )
899
+ return false;
900
+
901
+ return true;
902
+ }
903
+
904
+ function bp_total_favorite_count_for_user( $user_id = false ) {
905
+ echo bp_get_total_favorite_count_for_user( $user_id );
906
+ }
907
+ function bp_get_total_favorite_count_for_user( $user_id = false ) {
908
+ return apply_filters( 'bp_get_total_favorite_count_for_user', bp_activity_total_favorites_for_user( $user_id ) );
909
+ }
910
+
911
+ function bp_total_mention_count_for_user( $user_id = false ) {
912
+ echo bp_get_total_favorite_count_for_user( $user_id );
913
+ }
914
+ function bp_get_total_mention_count_for_user( $user_id = false ) {
915
+ return apply_filters( 'bp_get_total_mention_count_for_user', get_user_meta( $user_id, 'bp_new_mention_count', true ) );
916
+ }
917
+
918
+ function bp_send_public_message_link() {
919
+ echo bp_get_send_public_message_link();
920
+ }
921
+ function bp_get_send_public_message_link() {
922
+ global $bp;
923
+
924
+ if ( bp_is_my_profile() || !is_user_logged_in() )
925
+ return false;
926
+
927
+ return apply_filters( 'bp_get_send_public_message_link', wp_nonce_url( $bp->loggedin_user->domain . $bp->activity->slug . '/?r=' . bp_core_get_username( $bp->displayed_user->user_id, $bp->displayed_user->userdata->user_nicename, $bp->displayed_user->userdata->user_login ) ) );
928
+ }
929
+
930
+ /**
931
+ * bp_send_public_message_button( $args )
932
+ *
933
+ * Output button for sending a public message
934
+ *
935
+ * @param array $args
936
+ */
937
+ function bp_send_public_message_button( $args = '' ) {
938
+ echo bp_get_send_public_message_button( $args );
939
+ }
940
+ /**
941
+ * bp_get_send_public_message_button( $args )
942
+ *
943
+ * Return button for sending a public message
944
+ *
945
+ * @param array $args
946
+ * @return string
947
+ */
948
+ function bp_get_send_public_message_button( $args = '' ) {
949
+ $defaults = array(
950
+ 'id' => 'public_message',
951
+ 'component' => 'activity',
952
+ 'must_be_logged_in' => true,
953
+ 'block_self' => true,
954
+ 'wrapper_id' => 'post-mention',
955
+ 'link_href' => bp_get_send_public_message_link(),
956
+ 'link_title' => __( 'Mention this user in a new public message, this will send the user a notification to get their attention.', 'buddypress' ),
957
+ 'link_text' => __( 'Mention this User', 'buddypress' )
958
+ );
959
+
960
+ $button = wp_parse_args( $args, $defaults );
961
+
962
+ // Filter and return the HTML button
963
+ return bp_get_button( apply_filters( 'bp_get_send_public_message_button', $button ) );
964
+ }
965
+
966
+ function bp_activity_post_form_action() {
967
+ echo bp_get_activity_post_form_action();
968
+ }
969
+ function bp_get_activity_post_form_action() {
970
+ return apply_filters( 'bp_get_activity_post_form_action', site_url( BP_ACTIVITY_SLUG . '/post/' ) );
971
+ }
972
+
973
+ /* RSS Feed Template Tags ***************************/
974
+
975
+ function bp_sitewide_activity_feed_link() {
976
+ echo bp_get_sitewide_activity_feed_link();
977
+ }
978
+ function bp_get_sitewide_activity_feed_link() {
979
+ global $bp;
980
+
981
+ return apply_filters( 'bp_get_sitewide_activity_feed_link', site_url( $bp->activity->slug . '/feed/' ) );
982
+ }
983
+
984
+ function bp_member_activity_feed_link() {
985
+ echo bp_get_member_activity_feed_link();
986
+ }
987
+ function bp_activities_member_rss_link() { echo bp_get_member_activity_feed_link(); }
988
+
989
+ function bp_get_member_activity_feed_link() {
990
+ global $bp;
991
+
992
+ if ( $bp->current_component == $bp->profile->slug || 'just-me' == $bp->current_action )
993
+ $link = $bp->displayed_user->domain . $bp->activity->slug . '/feed/';
994
+ else if ( 'friends' == $bp->current_action )
995
+ $link = $bp->displayed_user->domain . $bp->activity->slug . '/friends/feed/';
996
+ else if ( 'groups' == $bp->current_action )
997
+ $link = $bp->displayed_user->domain . $bp->activity->slug . '/groups/feed/';
998
+ else if ( 'favorites' == $bp->current_action )
999
+ $link = $bp->displayed_user->domain . $bp->activity->slug . '/favorites/feed/';
1000
+ else if ( 'mentions' == $bp->current_action )
1001
+ $link = $bp->displayed_user->domain . $bp->activity->slug . '/mentions/feed/';
1002
+
1003
+ return apply_filters( 'bp_get_activities_member_rss_link', $link );
1004
+ }
1005
+ function bp_get_activities_member_rss_link() { return bp_get_member_activity_feed_link(); }
1006
+
1007
+
1008
+ /* Template tags for RSS feed output */
1009
+
1010
+ function bp_activity_feed_item_guid() {
1011
+ echo bp_get_activity_feed_item_guid();
1012
+ }
1013
+ function bp_get_activity_feed_item_guid() {
1014
+ global $activities_template;
1015
+
1016
+ return apply_filters( 'bp_get_activity_feed_item_guid', md5( $activities_template->activity->date_recorded . '-' . $activities_template->activity->content ) );
1017
+ }
1018
+
1019
+ function bp_activity_feed_item_title() {
1020
+ echo bp_get_activity_feed_item_title();
1021
+ }
1022
+ function bp_get_activity_feed_item_title() {
1023
+ global $activities_template;
1024
+
1025
+ if ( !empty( $activities_template->activity->action ) )
1026
+ $content = $activities_template->activity->action;
1027
+ else
1028
+ $content = $activities_template->activity->content;
1029
+
1030
+ $content = explode( '<span', $content );
1031
+ $title = trim( strip_tags( html_entity_decode( utf8_encode( $content[0] ) ) ) );
1032
+
1033
+ if ( ':' == substr( $title, -1 ) )
1034
+ $title = substr( $title, 0, -1 );
1035
+
1036
+ if ( 'activity_update' == $activities_template->activity->type )
1037
+ $title .= ': ' . strip_tags( bp_create_excerpt( $activities_template->activity->content, 15 ) );
1038
+
1039
+ return apply_filters( 'bp_get_activity_feed_item_title', $title );
1040
+ }
1041
+
1042
+ function bp_activity_feed_item_link() {
1043
+ echo bp_get_activity_feed_item_link();
1044
+ }
1045
+ function bp_get_activity_feed_item_link() {
1046
+ global $activities_template;
1047
+
1048
+ return apply_filters( 'bp_get_activity_feed_item_link', $activities_template->activity->primary_link );
1049
+ }
1050
+
1051
+ function bp_activity_feed_item_date() {
1052
+ echo bp_get_activity_feed_item_date();
1053
+ }
1054
+ function bp_get_activity_feed_item_date() {
1055
+ global $activities_template;
1056
+
1057
+ return apply_filters( 'bp_get_activity_feed_item_date', $activities_template->activity->date_recorded );
1058
+ }
1059
+
1060
+ function bp_activity_feed_item_description() {
1061
+ echo bp_get_activity_feed_item_description();
1062
+ }
1063
+ function bp_get_activity_feed_item_description() {
1064
+ global $activities_template;
1065
+
1066
+ if ( empty( $activities_template->activity->action ) )
1067
+ $content = $activities_template->activity->content;
1068
+ else
1069
+ $content = $activities_template->activity->action . ' ' . $activities_template->activity->content;
1070
+
1071
+ return apply_filters( 'bp_get_activity_feed_item_description', html_entity_decode( str_replace( '%s', '', $content ) ) );
1072
+ }
1073
+
1074
+ ?>
bp-activity/classes/class-bp-activity-activity.php DELETED
@@ -1,1875 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Activity Classes
4
- *
5
- * @package BuddyPress
6
- * @subpackage Activity
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Database interaction class for the BuddyPress activity component.
15
- * Instance methods are available for creating/editing an activity,
16
- * static methods for querying activities.
17
- *
18
- * @since 1.0.0
19
- */
20
- class BP_Activity_Activity {
21
-
22
- /** Properties ************************************************************/
23
-
24
- /**
25
- * ID of the activity item.
26
- *
27
- * @since 1.0.0
28
- * @var int
29
- */
30
- var $id;
31
-
32
- /**
33
- * ID of the associated item.
34
- *
35
- * @since 1.0.0
36
- * @var int
37
- */
38
- var $item_id;
39
-
40
- /**
41
- * ID of the associated secondary item.
42
- *
43
- * @since 1.0.0
44
- * @var int
45
- */
46
- var $secondary_item_id;
47
-
48
- /**
49
- * ID of user associated with the activity item.
50
- *
51
- * @since 1.0.0
52
- * @var int
53
- */
54
- var $user_id;
55
-
56
- /**
57
- * The primary URL for the activity in RSS feeds.
58
- *
59
- * @since 1.0.0
60
- * @var string
61
- */
62
- var $primary_link;
63
-
64
- /**
65
- * BuddyPress component the activity item relates to.
66
- *
67
- * @since 1.2.0
68
- * @var string
69
- */
70
- var $component;
71
-
72
- /**
73
- * Activity type, eg 'new_blog_post'.
74
- *
75
- * @since 1.2.0
76
- * @var string
77
- */
78
- var $type;
79
-
80
- /**
81
- * Description of the activity, eg 'Alex updated his profile.'.
82
- *
83
- * @since 1.2.0
84
- * @var string
85
- */
86
- var $action;
87
-
88
- /**
89
- * The content of the activity item.
90
- *
91
- * @since 1.2.0
92
- * @var string
93
- */
94
- var $content;
95
-
96
- /**
97
- * The date the activity item was recorded, in 'Y-m-d h:i:s' format.
98
- *
99
- * @since 1.0.0
100
- * @var string
101
- */
102
- var $date_recorded;
103
-
104
- /**
105
- * Whether the item should be hidden in sitewide streams.
106
- *
107
- * @since 1.1.0
108
- * @var int
109
- */
110
- var $hide_sitewide = 0;
111
-
112
- /**
113
- * Node boundary start for activity or activity comment.
114
- *
115
- * @since 1.5.0
116
- * @var int
117
- */
118
- var $mptt_left;
119
-
120
- /**
121
- * Node boundary end for activity or activity comment.
122
- *
123
- * @since 1.5.0
124
- * @var int
125
- */
126
- var $mptt_right;
127
-
128
- /**
129
- * Whether this item is marked as spam.
130
- *
131
- * @since 1.6.0
132
- * @var int
133
- */
134
- var $is_spam;
135
-
136
- /**
137
- * Error holder.
138
- *
139
- * @since 2.6.0
140
- *
141
- * @var WP_Error
142
- */
143
- public $errors;
144
-
145
- /**
146
- * Error type to return. Either 'bool' or 'wp_error'.
147
- *
148
- * @since 2.6.0
149
- *
150
- * @var string
151
- */
152
- public $error_type = 'bool';
153
-
154
- /**
155
- * Constructor method.
156
- *
157
- * @since 1.5.0
158
- *
159
- * @param int|bool $id Optional. The ID of a specific activity item.
160
- */
161
- public function __construct( $id = false ) {
162
- // Instantiate errors object.
163
- $this->errors = new WP_Error;
164
-
165
- if ( !empty( $id ) ) {
166
- $this->id = (int) $id;
167
- $this->populate();
168
- }
169
- }
170
-
171
- /**
172
- * Populate the object with data about the specific activity item.
173
- *
174
- * @since 1.0.0
175
- */
176
- public function populate() {
177
- global $wpdb;
178
-
179
- $row = wp_cache_get( $this->id, 'bp_activity' );
180
-
181
- if ( false === $row ) {
182
- $bp = buddypress();
183
- $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE id = %d", $this->id ) );
184
-
185
- wp_cache_set( $this->id, $row, 'bp_activity' );
186
- }
187
-
188
- if ( empty( $row ) ) {
189
- $this->id = 0;
190
- return;
191
- }
192
-
193
- $this->id = (int) $row->id;
194
- $this->item_id = (int) $row->item_id;
195
- $this->secondary_item_id = (int) $row->secondary_item_id;
196
- $this->user_id = (int) $row->user_id;
197
- $this->primary_link = $row->primary_link;
198
- $this->component = $row->component;
199
- $this->type = $row->type;
200
- $this->action = $row->action;
201
- $this->content = $row->content;
202
- $this->date_recorded = $row->date_recorded;
203
- $this->hide_sitewide = (int) $row->hide_sitewide;
204
- $this->mptt_left = (int) $row->mptt_left;
205
- $this->mptt_right = (int) $row->mptt_right;
206
- $this->is_spam = (int) $row->is_spam;
207
-
208
- // Generate dynamic 'action' when possible.
209
- $action = bp_activity_generate_action_string( $this );
210
- if ( false !== $action ) {
211
- $this->action = $action;
212
-
213
- // If no callback is available, use the literal string from
214
- // the database row.
215
- } elseif ( ! empty( $row->action ) ) {
216
- $this->action = $row->action;
217
-
218
- // Provide a fallback to avoid PHP notices.
219
- } else {
220
- $this->action = '';
221
- }
222
- }
223
-
224
- /**
225
- * Save the activity item to the database.
226
- *
227
- * @since 1.0.0
228
- *
229
- * @return WP_Error|bool True on success.
230
- */
231
- public function save() {
232
- global $wpdb;
233
-
234
- $bp = buddypress();
235
-
236
- $this->id = apply_filters_ref_array( 'bp_activity_id_before_save', array( $this->id, &$this ) );
237
- $this->item_id = apply_filters_ref_array( 'bp_activity_item_id_before_save', array( $this->item_id, &$this ) );
238
- $this->secondary_item_id = apply_filters_ref_array( 'bp_activity_secondary_item_id_before_save', array( $this->secondary_item_id, &$this ) );
239
- $this->user_id = apply_filters_ref_array( 'bp_activity_user_id_before_save', array( $this->user_id, &$this ) );
240
- $this->primary_link = apply_filters_ref_array( 'bp_activity_primary_link_before_save', array( $this->primary_link, &$this ) );
241
- $this->component = apply_filters_ref_array( 'bp_activity_component_before_save', array( $this->component, &$this ) );
242
- $this->type = apply_filters_ref_array( 'bp_activity_type_before_save', array( $this->type, &$this ) );
243
- $this->action = apply_filters_ref_array( 'bp_activity_action_before_save', array( $this->action, &$this ) );
244
- $this->content = apply_filters_ref_array( 'bp_activity_content_before_save', array( $this->content, &$this ) );
245
- $this->date_recorded = apply_filters_ref_array( 'bp_activity_date_recorded_before_save', array( $this->date_recorded, &$this ) );
246
- $this->hide_sitewide = apply_filters_ref_array( 'bp_activity_hide_sitewide_before_save', array( $this->hide_sitewide, &$this ) );
247
- $this->mptt_left = apply_filters_ref_array( 'bp_activity_mptt_left_before_save', array( $this->mptt_left, &$this ) );
248
- $this->mptt_right = apply_filters_ref_array( 'bp_activity_mptt_right_before_save', array( $this->mptt_right, &$this ) );
249
- $this->is_spam = apply_filters_ref_array( 'bp_activity_is_spam_before_save', array( $this->is_spam, &$this ) );
250
-
251
- /**
252
- * Fires before the current activity item gets saved.
253
- *
254
- * Please use this hook to filter the properties above. Each part will be passed in.
255
- *
256
- * @since 1.0.0
257
- *
258
- * @param BP_Activity_Activity $this Current instance of the activity item being saved. Passed by reference.
259
- */
260
- do_action_ref_array( 'bp_activity_before_save', array( &$this ) );
261
-
262
- if ( 'wp_error' === $this->error_type && $this->errors->get_error_code() ) {
263
- return $this->errors;
264
- }
265
-
266
- if ( empty( $this->component ) || empty( $this->type ) ) {
267
- if ( 'bool' === $this->error_type ) {
268
- return false;
269
- } else {
270
- if ( empty( $this->component ) ) {
271
- $this->errors->add( 'bp_activity_missing_component' );
272
- } else {
273
- $this->errors->add( 'bp_activity_missing_type' );
274
- }
275
-
276
- return $this->errors;
277
- }
278
- }
279
-
280
- if ( empty( $this->primary_link ) ) {
281
- $this->primary_link = bp_loggedin_user_domain();
282
- }
283
-
284
- // If we have an existing ID, update the activity item, otherwise insert it.
285
- if ( ! empty( $this->id ) ) {
286
- $q = $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET user_id = %d, component = %s, type = %s, action = %s, content = %s, primary_link = %s, date_recorded = %s, item_id = %d, secondary_item_id = %d, hide_sitewide = %d, is_spam = %d WHERE id = %d", $this->user_id, $this->component, $this->type, $this->action, $this->content, $this->primary_link, $this->date_recorded, $this->item_id, $this->secondary_item_id, $this->hide_sitewide, $this->is_spam, $this->id );
287
- } else {
288
- $q = $wpdb->prepare( "INSERT INTO {$bp->activity->table_name} ( user_id, component, type, action, content, primary_link, date_recorded, item_id, secondary_item_id, hide_sitewide, is_spam ) VALUES ( %d, %s, %s, %s, %s, %s, %s, %d, %d, %d, %d )", $this->user_id, $this->component, $this->type, $this->action, $this->content, $this->primary_link, $this->date_recorded, $this->item_id, $this->secondary_item_id, $this->hide_sitewide, $this->is_spam );
289
- }
290
-
291
- if ( false === $wpdb->query( $q ) ) {
292
- return false;
293
- }
294
-
295
- // If this is a new activity item, set the $id property.
296
- if ( empty( $this->id ) ) {
297
- $this->id = $wpdb->insert_id;
298
-
299
- // If an existing activity item, prevent any changes to the content generating new @mention notifications.
300
- } else {
301
- add_filter( 'bp_activity_at_name_do_notifications', '__return_false' );
302
- }
303
-
304
- /**
305
- * Fires after an activity item has been saved to the database.
306
- *
307
- * @since 1.0.0
308
- *
309
- * @param BP_Activity_Activity $this Current instance of activity item being saved. Passed by reference.
310
- */
311
- do_action_ref_array( 'bp_activity_after_save', array( &$this ) );
312
-
313
- return true;
314
- }
315
-
316
- /** Static Methods ***************************************************/
317
-
318
- /**
319
- * Get activity items, as specified by parameters.
320
- *
321
- * @since 1.2.0
322
- * @since 2.4.0 Introduced the `$fields` parameter.
323
- * @since 2.9.0 Introduced the `$order_by` parameter.
324
- *
325
- * @see BP_Activity_Activity::get_filter_sql() for a description of the
326
- * 'filter' parameter.
327
- * @see WP_Meta_Query::queries for a description of the 'meta_query'
328
- * parameter format.
329
- *
330
- * @param array $args {
331
- * An array of arguments. All items are optional.
332
- * @type int $page Which page of results to fetch. Using page=1 without per_page will result
333
- * in no pagination. Default: 1.
334
- * @type int|bool $per_page Number of results per page. Default: 25.
335
- * @type int|bool $max Maximum number of results to return. Default: false (unlimited).
336
- * @type string $fields Activity fields to return. Pass 'ids' to get only the activity IDs.
337
- * 'all' returns full activity objects.
338
- * @type string $sort ASC or DESC. Default: 'DESC'.
339
- * @type string $order_by Column to order results by.
340
- * @type array $exclude Array of activity IDs to exclude. Default: false.
341
- * @type array $in Array of ids to limit query by (IN). Default: false.
342
- * @type array $meta_query Array of meta_query conditions. See WP_Meta_Query::queries.
343
- * @type array $date_query Array of date_query conditions. See first parameter of
344
- * WP_Date_Query::__construct().
345
- * @type array $filter_query Array of advanced query conditions. See BP_Activity_Query::__construct().
346
- * @type string|array $scope Pre-determined set of activity arguments.
347
- * @type array $filter See BP_Activity_Activity::get_filter_sql().
348
- * @type string $search_terms Limit results by a search term. Default: false.
349
- * @type bool $display_comments Whether to include activity comments. Default: false.
350
- * @type bool $show_hidden Whether to show items marked hide_sitewide. Default: false.
351
- * @type string $spam Spam status. Default: 'ham_only'.
352
- * @type bool $update_meta_cache Whether to pre-fetch metadata for queried activity items. Default: true.
353
- * @type string|bool $count_total If true, an additional DB query is run to count the total activity items
354
- * for the query. Default: false.
355
- * }
356
- * @return array The array returned has two keys:
357
- * - 'total' is the count of located activities
358
- * - 'activities' is an array of the located activities
359
- */
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(
368
- 0 => 'max',
369
- 1 => 'page',
370
- 2 => 'per_page',
371
- 3 => 'sort',
372
- 4 => 'search_terms',
373
- 5 => 'filter',
374
- 6 => 'display_comments',
375
- 7 => 'show_hidden',
376
- 8 => 'exclude',
377
- 9 => 'in',
378
- 10 => 'spam'
379
- );
380
-
381
- $args = bp_core_parse_args_array( $old_args_keys, func_get_args() );
382
- }
383
-
384
- $bp = buddypress();
385
- $r = wp_parse_args( $args, array(
386
- 'page' => 1, // The current page.
387
- 'per_page' => 25, // Activity items per page.
388
- 'max' => false, // Max number of items to return.
389
- 'fields' => 'all', // Fields to include.
390
- 'sort' => 'DESC', // ASC or DESC.
391
- 'order_by' => 'date_recorded', // Column to order by.
392
- 'exclude' => false, // Array of ids to exclude.
393
- 'in' => false, // Array of ids to limit query by (IN).
394
- 'meta_query' => false, // Filter by activitymeta.
395
- 'date_query' => false, // Filter by date.
396
- 'filter_query' => false, // Advanced filtering - see BP_Activity_Query.
397
- 'filter' => false, // See self::get_filter_sql().
398
- 'scope' => false, // Preset activity arguments.
399
- 'search_terms' => false, // Terms to search by.
400
- 'display_comments' => false, // Whether to include activity comments.
401
- 'show_hidden' => false, // Show items marked hide_sitewide.
402
- 'spam' => 'ham_only', // Spam status.
403
- 'update_meta_cache' => true, // Whether or not to update meta cache.
404
- 'count_total' => false, // Whether or not to use count_total.
405
- ) );
406
-
407
- // Select conditions.
408
- $select_sql = "SELECT DISTINCT a.id";
409
-
410
- $from_sql = " FROM {$bp->activity->table_name} a";
411
-
412
- $join_sql = '';
413
-
414
- // Where conditions.
415
- $where_conditions = array();
416
-
417
- // Excluded types.
418
- $excluded_types = array();
419
-
420
- // Scope takes precedence.
421
- if ( ! empty( $r['scope'] ) ) {
422
- $scope_query = self::get_scope_query_sql( $r['scope'], $r );
423
-
424
- // Add our SQL conditions if matches were found.
425
- if ( ! empty( $scope_query['sql'] ) ) {
426
- $where_conditions['scope_query_sql'] = $scope_query['sql'];
427
- }
428
-
429
- // Override some arguments if needed.
430
- if ( ! empty( $scope_query['override'] ) ) {
431
- $r = array_replace_recursive( $r, $scope_query['override'] );
432
- }
433
-
434
- // Advanced filtering.
435
- } elseif ( ! empty( $r['filter_query'] ) ) {
436
- $filter_query = new BP_Activity_Query( $r['filter_query'] );
437
- $sql = $filter_query->get_sql();
438
- if ( ! empty( $sql ) ) {
439
- $where_conditions['filter_query_sql'] = $sql;
440
- }
441
- }
442
-
443
- // Regular filtering.
444
- if ( $r['filter'] && $filter_sql = BP_Activity_Activity::get_filter_sql( $r['filter'] ) ) {
445
- $where_conditions['filter_sql'] = $filter_sql;
446
- }
447
-
448
- // Spam.
449
- if ( 'ham_only' == $r['spam'] ) {
450
- $where_conditions['spam_sql'] = 'a.is_spam = 0';
451
- } elseif ( 'spam_only' == $r['spam'] ) {
452
- $where_conditions['spam_sql'] = 'a.is_spam = 1';
453
- }
454
-
455
- // Searching.
456
- if ( $r['search_terms'] ) {
457
- $search_terms_like = '%' . bp_esc_like( $r['search_terms'] ) . '%';
458
- $where_conditions['search_sql'] = $wpdb->prepare( 'a.content LIKE %s', $search_terms_like );
459
- }
460
-
461
- // Sorting.
462
- $sort = $r['sort'];
463
- if ( $sort != 'ASC' && $sort != 'DESC' ) {
464
- $sort = 'DESC';
465
- }
466
-
467
- switch( $r['order_by'] ) {
468
- case 'id' :
469
- case 'user_id' :
470
- case 'component' :
471
- case 'type' :
472
- case 'action' :
473
- case 'content' :
474
- case 'primary_link' :
475
- case 'item_id' :
476
- case 'secondary_item_id' :
477
- case 'date_recorded' :
478
- case 'hide_sitewide' :
479
- case 'mptt_left' :
480
- case 'mptt_right' :
481
- case 'is_spam' :
482
- break;
483
-
484
- default :
485
- $r['order_by'] = 'date_recorded';
486
- break;
487
- }
488
- $order_by = 'a.' . $r['order_by'];
489
-
490
- // Hide Hidden Items?
491
- if ( ! $r['show_hidden'] ) {
492
- $where_conditions['hidden_sql'] = "a.hide_sitewide = 0";
493
- }
494
-
495
- // Exclude specified items.
496
- if ( ! empty( $r['exclude'] ) ) {
497
- $exclude = implode( ',', wp_parse_id_list( $r['exclude'] ) );
498
- $where_conditions['exclude'] = "a.id NOT IN ({$exclude})";
499
- }
500
-
501
- // The specific ids to which you want to limit the query.
502
- if ( ! empty( $r['in'] ) ) {
503
- $in = implode( ',', wp_parse_id_list( $r['in'] ) );
504
- $where_conditions['in'] = "a.id IN ({$in})";
505
- }
506
-
507
- // Process meta_query into SQL.
508
- $meta_query_sql = self::get_meta_query_sql( $r['meta_query'] );
509
-
510
- if ( ! empty( $meta_query_sql['join'] ) ) {
511
- $join_sql .= $meta_query_sql['join'];
512
- }
513
-
514
- if ( ! empty( $meta_query_sql['where'] ) ) {
515
- $where_conditions[] = $meta_query_sql['where'];
516
- }
517
-
518
- // Process date_query into SQL.
519
- $date_query_sql = self::get_date_query_sql( $r['date_query'] );
520
-
521
- if ( ! empty( $date_query_sql ) ) {
522
- $where_conditions['date'] = $date_query_sql;
523
- }
524
-
525
- // Alter the query based on whether we want to show activity item
526
- // comments in the stream like normal comments or threaded below
527
- // the activity.
528
- if ( false === $r['display_comments'] || 'threaded' === $r['display_comments'] ) {
529
- $excluded_types[] = 'activity_comment';
530
- }
531
-
532
- // Exclude 'last_activity' items unless the 'action' filter has
533
- // been explicitly set.
534
- if ( empty( $r['filter']['object'] ) ) {
535
- $excluded_types[] = 'last_activity';
536
- }
537
-
538
- // Build the excluded type sql part.
539
- if ( ! empty( $excluded_types ) ) {
540
- $not_in = "'" . implode( "', '", esc_sql( $excluded_types ) ) . "'";
541
- $where_conditions['excluded_types'] = "a.type NOT IN ({$not_in})";
542
- }
543
-
544
- /**
545
- * Filters the MySQL WHERE conditions for the Activity items get method.
546
- *
547
- * @since 1.9.0
548
- *
549
- * @param array $where_conditions Current conditions for MySQL WHERE statement.
550
- * @param array $r Parsed arguments passed into method.
551
- * @param string $select_sql Current SELECT MySQL statement at point of execution.
552
- * @param string $from_sql Current FROM MySQL statement at point of execution.
553
- * @param string $join_sql Current INNER JOIN MySQL statement at point of execution.
554
- */
555
- $where_conditions = apply_filters( 'bp_activity_get_where_conditions', $where_conditions, $r, $select_sql, $from_sql, $join_sql );
556
-
557
- // Join the where conditions together.
558
- $where_sql = 'WHERE ' . join( ' AND ', $where_conditions );
559
-
560
- /**
561
- * Filter the MySQL JOIN clause for the main activity query.
562
- *
563
- * @since 2.5.0
564
- *
565
- * @param string $join_sql JOIN clause.
566
- * @param array $r Method parameters.
567
- * @param string $select_sql Current SELECT MySQL statement.
568
- * @param string $from_sql Current FROM MySQL statement.
569
- * @param string $where_sql Current WHERE MySQL statement.
570
- */
571
- $join_sql = apply_filters( 'bp_activity_get_join_sql', $join_sql, $r, $select_sql, $from_sql, $where_sql );
572
-
573
- // Sanitize page and per_page parameters.
574
- $page = absint( $r['page'] );
575
- $per_page = absint( $r['per_page'] );
576
-
577
- $retval = array(
578
- 'activities' => null,
579
- 'total' => null,
580
- 'has_more_items' => null,
581
- );
582
-
583
- /**
584
- * Filters if BuddyPress should use legacy query structure over current structure for version 2.0+.
585
- *
586
- * It is not recommended to use the legacy structure, but allowed to if needed.
587
- *
588
- * @since 2.0.0
589
- *
590
- * @param bool $value Whether to use legacy structure or not.
591
- * @param BP_Activity_Activity $value Current method being called.
592
- * @param array $r Parsed arguments passed into method.
593
- */
594
- if ( apply_filters( 'bp_use_legacy_activity_query', false, __METHOD__, $r ) ) {
595
-
596
- // Legacy queries joined against the user table.
597
- $select_sql = "SELECT DISTINCT a.*, u.user_email, u.user_nicename, u.user_login, u.display_name";
598
- $from_sql = " FROM {$bp->activity->table_name} a LEFT JOIN {$wpdb->users} u ON a.user_id = u.ID";
599
-
600
- if ( ! empty( $page ) && ! empty( $per_page ) ) {
601
- $pag_sql = $wpdb->prepare( "LIMIT %d, %d", absint( ( $page - 1 ) * $per_page ), $per_page );
602
-
603
- /** This filter is documented in bp-activity/bp-activity-classes.php */
604
- $activities = $wpdb->get_results( apply_filters( 'bp_activity_get_user_join_filter', "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}, a.id {$sort} {$pag_sql}", $select_sql, $from_sql, $where_sql, $sort, $pag_sql ) );
605
- } else {
606
- $pag_sql = '';
607
-
608
- /**
609
- * Filters the legacy MySQL query statement so plugins can alter before results are fetched.
610
- *
611
- * @since 1.5.0
612
- *
613
- * @param string $value Concatenated MySQL statement pieces to be query results with for legacy query.
614
- * @param string $select_sql Final SELECT MySQL statement portion for legacy query.
615
- * @param string $from_sql Final FROM MySQL statement portion for legacy query.
616
- * @param string $where_sql Final WHERE MySQL statement portion for legacy query.
617
- * @param string $sort Final sort direction for legacy query.
618
- */
619
- $activities = $wpdb->get_results( apply_filters( 'bp_activity_get_user_join_filter', "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}, a.id {$sort}", $select_sql, $from_sql, $where_sql, $sort, $pag_sql ) );
620
- }
621
-
622
- // Integer casting for legacy activity query.
623
- foreach ( (array) $activities as $i => $ac ) {
624
- $activities[ $i ]->id = (int) $ac->id;
625
- $activities[ $i ]->item_id = (int) $ac->item_id;
626
- $activities[ $i ]->secondary_item_id = (int) $ac->secondary_item_id;
627
- $activities[ $i ]->user_id = (int) $ac->user_id;
628
- $activities[ $i ]->hide_sitewide = (int) $ac->hide_sitewide;
629
- $activities[ $i ]->mptt_left = (int) $ac->mptt_left;
630
- $activities[ $i ]->mptt_right = (int) $ac->mptt_right;
631
- $activities[ $i ]->is_spam = (int) $ac->is_spam;
632
- }
633
-
634
- } else {
635
- // Query first for activity IDs.
636
- $activity_ids_sql = "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY {$order_by} {$sort}, a.id {$sort}";
637
-
638
- if ( ! empty( $per_page ) && ! empty( $page ) ) {
639
- // We query for $per_page + 1 items in order to
640
- // populate the has_more_items flag.
641
- $activity_ids_sql .= $wpdb->prepare( " LIMIT %d, %d", absint( ( $page - 1 ) * $per_page ), $per_page + 1 );
642
- }
643
-
644
- /**
645
- * Filters the paged activities MySQL statement.
646
- *
647
- * @since 2.0.0
648
- *
649
- * @param string $activity_ids_sql MySQL statement used to query for Activity IDs.
650
- * @param array $r Array of arguments passed into method.
651
- */
652
- $activity_ids_sql = apply_filters( 'bp_activity_paged_activities_sql', $activity_ids_sql, $r );
653
-
654
- /*
655
- * Queries that include 'last_activity' are cached separately,
656
- * since they are generally much less long-lived.
657
- */
658
- if ( preg_match( '/a\.type NOT IN \([^\)]*\'last_activity\'[^\)]*\)/', $activity_ids_sql ) ) {
659
- $cache_group = 'bp_activity';
660
- } else {
661
- $cache_group = 'bp_activity_with_last_activity';
662
- }
663
-
664
- $cached = bp_core_get_incremented_cache( $activity_ids_sql, $cache_group );
665
- if ( false === $cached ) {
666
- $activity_ids = $wpdb->get_col( $activity_ids_sql );
667
- bp_core_set_incremented_cache( $activity_ids_sql, $cache_group, $activity_ids );
668
- } else {
669
- $activity_ids = $cached;
670
- }
671
-
672
- $retval['has_more_items'] = ! empty( $per_page ) && count( $activity_ids ) > $per_page;
673
-
674
- // If we've fetched more than the $per_page value, we
675
- // can discard the extra now.
676
- if ( ! empty( $per_page ) && count( $activity_ids ) === $per_page + 1 ) {
677
- array_pop( $activity_ids );
678
- }
679
-
680
- if ( 'ids' === $r['fields'] ) {
681
- $activities = array_map( 'intval', $activity_ids );
682
- } else {
683
- $activities = self::get_activity_data( $activity_ids );
684
- }
685
- }
686
-
687
- if ( 'ids' !== $r['fields'] ) {
688
- // Get the fullnames of users so we don't have to query in the loop.
689
- $activities = self::append_user_fullnames( $activities );
690
-
691
- // Get activity meta.
692
- $activity_ids = array();
693
- foreach ( (array) $activities as $activity ) {
694
- $activity_ids[] = $activity->id;
695
- }
696
-
697
- if ( ! empty( $activity_ids ) && $r['update_meta_cache'] ) {
698
- bp_activity_update_meta_cache( $activity_ids );
699
- }
700
-
701
- if ( $activities && $r['display_comments'] ) {
702
- $activities = BP_Activity_Activity::append_comments( $activities, $r['spam'] );
703
- }
704
-
705
- // Pre-fetch data associated with activity users and other objects.
706
- BP_Activity_Activity::prefetch_object_data( $activities );
707
-
708
- // Generate action strings.
709
- $activities = BP_Activity_Activity::generate_action_strings( $activities );
710
- }
711
-
712
- $retval['activities'] = $activities;
713
-
714
- // If $max is set, only return up to the max results.
715
- if ( ! empty( $r['count_total'] ) ) {
716
-
717
- /**
718
- * Filters the total activities MySQL statement.
719
- *
720
- * @since 1.5.0
721
- *
722
- * @param string $value MySQL statement used to query for total activities.
723
- * @param string $where_sql MySQL WHERE statement portion.
724
- * @param string $sort Sort direction for query.
725
- */
726
- $total_activities_sql = apply_filters( 'bp_activity_total_activities_sql', "SELECT count(DISTINCT a.id) FROM {$bp->activity->table_name} a {$join_sql} {$where_sql}", $where_sql, $sort );
727
- $cached = bp_core_get_incremented_cache( $total_activities_sql, $cache_group );
728
- if ( false === $cached ) {
729
- $total_activities = $wpdb->get_var( $total_activities_sql );
730
- bp_core_set_incremented_cache( $total_activities_sql, $cache_group, $total_activities );
731
- } else {
732
- $total_activities = $cached;
733
- }
734
-
735
- if ( !empty( $r['max'] ) ) {
736
- if ( (int) $total_activities > (int) $r['max'] ) {
737
- $total_activities = $r['max'];
738
- }
739
- }
740
-
741
- $retval['total'] = $total_activities;
742
- }
743
-
744
- return $retval;
745
- }
746
-
747
- /**
748
- * Convert activity IDs to activity objects, as expected in template loop.
749
- *
750
- * @since 2.0.0
751
- *
752
- * @param array $activity_ids Array of activity IDs.
753
- * @return array
754
- */
755
- protected static function get_activity_data( $activity_ids = array() ) {
756
- global $wpdb;
757
-
758
- // Bail if no activity ID's passed.
759
- if ( empty( $activity_ids ) ) {
760
- return array();
761
- }
762
-
763
- // Get BuddyPress.
764
- $bp = buddypress();
765
-
766
- $activities = array();
767
- $uncached_ids = bp_get_non_cached_ids( $activity_ids, 'bp_activity' );
768
-
769
- // Prime caches as necessary.
770
- if ( ! empty( $uncached_ids ) ) {
771
- // Format the activity ID's for use in the query below.
772
- $uncached_ids_sql = implode( ',', wp_parse_id_list( $uncached_ids ) );
773
-
774
- // Fetch data from activity table, preserving order.
775
- $queried_adata = $wpdb->get_results( "SELECT * FROM {$bp->activity->table_name} WHERE id IN ({$uncached_ids_sql})");
776
-
777
- // Put that data into the placeholders created earlier,
778
- // and add it to the cache.
779
- foreach ( (array) $queried_adata as $adata ) {
780
- wp_cache_set( $adata->id, $adata, 'bp_activity' );
781
- }
782
- }
783
-
784
- // Now fetch data from the cache.
785
- foreach ( $activity_ids as $activity_id ) {
786
- // Integer casting.
787
- $activity = wp_cache_get( $activity_id, 'bp_activity' );
788
- if ( ! empty( $activity ) ) {
789
- $activity->id = (int) $activity->id;
790
- $activity->user_id = (int) $activity->user_id;
791
- $activity->item_id = (int) $activity->item_id;
792
- $activity->secondary_item_id = (int) $activity->secondary_item_id;
793
- $activity->hide_sitewide = (int) $activity->hide_sitewide;
794
- $activity->mptt_left = (int) $activity->mptt_left;
795
- $activity->mptt_right = (int) $activity->mptt_right;
796
- $activity->is_spam = (int) $activity->is_spam;
797
- }
798
-
799
- $activities[] = $activity;
800
- }
801
-
802
- // Then fetch user data.
803
- $user_query = new BP_User_Query( array(
804
- 'user_ids' => wp_list_pluck( $activities, 'user_id' ),
805
- 'populate_extras' => false,
806
- ) );
807
-
808
- // Associated located user data with activity items.
809
- foreach ( $activities as $a_index => $a_item ) {
810
- $a_user_id = intval( $a_item->user_id );
811
- $a_user = isset( $user_query->results[ $a_user_id ] ) ? $user_query->results[ $a_user_id ] : '';
812
-
813
- if ( !empty( $a_user ) ) {
814
- $activities[ $a_index ]->user_email = $a_user->user_email;
815
- $activities[ $a_index ]->user_nicename = $a_user->user_nicename;
816
- $activities[ $a_index ]->user_login = $a_user->user_login;
817
- $activities[ $a_index ]->display_name = $a_user->display_name;
818
- }
819
- }
820
-
821
- return $activities;
822
- }
823
-
824
- /**
825
- * Append xProfile fullnames to an activity array.
826
- *
827
- * @since 2.0.0
828
- *
829
- * @param array $activities Activities array.
830
- * @return array
831
- */
832
- protected static function append_user_fullnames( $activities ) {
833
-
834
- if ( bp_is_active( 'xprofile' ) && ! empty( $activities ) ) {
835
- $activity_user_ids = wp_list_pluck( $activities, 'user_id' );
836
-
837
- if ( ! empty( $activity_user_ids ) ) {
838
- $fullnames = bp_core_get_user_displaynames( $activity_user_ids );
839
- if ( ! empty( $fullnames ) ) {
840
- foreach ( (array) $activities as $i => $activity ) {
841
- if ( ! empty( $fullnames[ $activity->user_id ] ) ) {
842
- $activities[ $i ]->user_fullname = $fullnames[ $activity->user_id ];
843
- }
844
- }
845
- }
846
- }
847
- }
848
-
849
- return $activities;
850
- }
851
-
852
- /**
853
- * Pre-fetch data for objects associated with activity items.
854
- *
855
- * Activity items are associated with users, and often with other
856
- * BuddyPress data objects. Here, we pre-fetch data about these
857
- * associated objects, so that inline lookups - done primarily when
858
- * building action strings - do not result in excess database queries.
859
- *
860
- * The only object data required for activity component activity types
861
- * (activity_update and activity_comment) is related to users, and that
862
- * info is fetched separately in BP_Activity_Activity::get_activity_data().
863
- * So this method contains nothing but a filter that allows other
864
- * components, such as bp-friends and bp-groups, to hook in and prime
865
- * their own caches at the beginning of an activity loop.
866
- *
867
- * @since 2.0.0
868
- *
869
- * @param array $activities Array of activities.
870
- * @return array $activities Array of activities.
871
- */
872
- protected static function prefetch_object_data( $activities ) {
873
-
874
- /**
875
- * Filters inside prefetch_object_data method to aid in pre-fetching object data associated with activity item.
876
- *
877
- * @since 2.0.0
878
- *
879
- * @param array $activities Array of activities.
880
- */
881
- return apply_filters( 'bp_activity_prefetch_object_data', $activities );
882
- }
883
-
884
- /**
885
- * Generate action strings for the activities located in BP_Activity_Activity::get().
886
- *
887
- * If no string can be dynamically generated for a given item
888
- * (typically because the activity type has not been properly
889
- * registered), the static 'action' value pulled from the database will
890
- * be left in place.
891
- *
892
- * @since 2.0.0
893
- *
894
- * @param array $activities Array of activities.
895
- * @return array
896
- */
897
- protected static function generate_action_strings( $activities ) {
898
- foreach ( $activities as $key => $activity ) {
899
- $generated_action = bp_activity_generate_action_string( $activity );
900
- if ( false !== $generated_action ) {
901
- $activity->action = $generated_action;
902
- }
903
-
904
- $activities[ $key ] = $activity;
905
- }
906
-
907
- return $activities;
908
- }
909
-
910
- /**
911
- * Get the SQL for the 'meta_query' param in BP_Activity_Activity::get().
912
- *
913
- * We use WP_Meta_Query to do the heavy lifting of parsing the
914
- * meta_query array and creating the necessary SQL clauses. However,
915
- * since BP_Activity_Activity::get() builds its SQL differently than
916
- * WP_Query, we have to alter the return value (stripping the leading
917
- * AND keyword from the 'where' clause).
918
- *
919
- * @since 1.8.0
920
- *
921
- * @param array $meta_query An array of meta_query filters. See the
922
- * documentation for WP_Meta_Query for details.
923
- * @return array $sql_array 'join' and 'where' clauses.
924
- */
925
- public static function get_meta_query_sql( $meta_query = array() ) {
926
- global $wpdb;
927
-
928
- $sql_array = array(
929
- 'join' => '',
930
- 'where' => '',
931
- );
932
-
933
- if ( ! empty( $meta_query ) ) {
934
- $activity_meta_query = new WP_Meta_Query( $meta_query );
935
-
936
- // WP_Meta_Query expects the table name at
937
- // $wpdb->activitymeta.
938
- $wpdb->activitymeta = buddypress()->activity->table_name_meta;
939
-
940
- $meta_sql = $activity_meta_query->get_sql( 'activity', 'a', 'id' );
941
-
942
- // Strip the leading AND - BP handles it in get().
943
- $sql_array['where'] = preg_replace( '/^\sAND/', '', $meta_sql['where'] );
944
- $sql_array['join'] = $meta_sql['join'];
945
- }
946
-
947
- return $sql_array;
948
- }
949
-
950
- /**
951
- * Get the SQL for the 'date_query' param in BP_Activity_Activity::get().
952
- *
953
- * We use BP_Date_Query, which extends WP_Date_Query, to do the heavy lifting
954
- * of parsing the date_query array and creating the necessary SQL clauses.
955
- * However, since BP_Activity_Activity::get() builds its SQL differently than
956
- * WP_Query, we have to alter the return value (stripping the leading AND
957
- * keyword from the query).
958
- *
959
- * @since 2.1.0
960
- *
961
- * @param array $date_query An array of date_query parameters. See the
962
- * documentation for the first parameter of WP_Date_Query.
963
- * @return string
964
- */
965
- public static function get_date_query_sql( $date_query = array() ) {
966
- $sql = '';
967
-
968
- // Date query.
969
- if ( ! empty( $date_query ) && is_array( $date_query ) ) {
970
- $date_query = new BP_Date_Query( $date_query, 'date_recorded' );
971
- $sql = preg_replace( '/^\sAND/', '', $date_query->get_sql() );
972
- }
973
-
974
- return $sql;
975
- }
976
-
977
- /**
978
- * Get the SQL for the 'scope' param in BP_Activity_Activity::get().
979
- *
980
- * A scope is a predetermined set of activity arguments. This method is used
981
- * to grab these activity arguments and override any existing args if needed.
982
- *
983
- * Can handle multiple scopes.
984
- *
985
- * @since 2.2.0
986
- *
987
- * @param mixed $scope The activity scope. Accepts string or array of scopes.
988
- * @param array $r Current activity arguments. Same as those of BP_Activity_Activity::get(),
989
- * but merged with defaults.
990
- * @return false|array 'sql' WHERE SQL string and 'override' activity args.
991
- */
992
- public static function get_scope_query_sql( $scope = false, $r = array() ) {
993
-
994
- // Define arrays for future use.
995
- $query_args = array();
996
- $override = array();
997
- $retval = array();
998
-
999
- // Check for array of scopes.
1000
- if ( is_array( $scope ) ) {
1001
- $scopes = $scope;
1002
-
1003
- // Explode a comma separated string of scopes.
1004
- } elseif ( is_string( $scope ) ) {
1005
- $scopes = explode( ',', $scope );
1006
- }
1007
-
1008
- // Bail if no scope passed.
1009
- if ( empty( $scopes ) ) {
1010
- return false;
1011
- }
1012
-
1013
- // Helper to easily grab the 'user_id'.
1014
- if ( ! empty( $r['filter']['user_id'] ) ) {
1015
- $r['user_id'] = $r['filter']['user_id'];
1016
- }
1017
-
1018
- // Parse each scope; yes! we handle multiples!
1019
- foreach ( $scopes as $scope ) {
1020
- $scope_args = array();
1021
-
1022
- /**
1023
- * Plugins can hook here to set their activity arguments for custom scopes.
1024
- *
1025
- * This is a dynamic filter based on the activity scope. eg:
1026
- * - 'bp_activity_set_groups_scope_args'
1027
- * - 'bp_activity_set_friends_scope_args'
1028
- *
1029
- * To see how this filter is used, plugin devs should check out:
1030
- * - bp_groups_filter_activity_scope() - used for 'groups' scope
1031
- * - bp_friends_filter_activity_scope() - used for 'friends' scope
1032
- *
1033
- * @since 2.2.0
1034
- *
1035
- * @param array {
1036
- * Activity query clauses.
1037
- * @type array {
1038
- * Activity arguments for your custom scope.
1039
- * See {@link BP_Activity_Query::_construct()} for more details.
1040
- * }
1041
- * @type array $override Optional. Override existing activity arguments passed by $r.
1042
- * }
1043
- * }
1044
- * @param array $r Current activity arguments passed in BP_Activity_Activity::get().
1045
- */
1046
- $scope_args = apply_filters( "bp_activity_set_{$scope}_scope_args", array(), $r );
1047
-
1048
- if ( ! empty( $scope_args ) ) {
1049
- // Merge override properties from other scopes
1050
- // this might be a problem...
1051
- if ( ! empty( $scope_args['override'] ) ) {
1052
- $override = array_merge( $override, $scope_args['override'] );
1053
- unset( $scope_args['override'] );
1054
- }
1055
-
1056
- // Save scope args.
1057
- if ( ! empty( $scope_args ) ) {
1058
- $query_args[] = $scope_args;
1059
- }
1060
- }
1061
- }
1062
-
1063
- if ( ! empty( $query_args ) ) {
1064
- // Set relation to OR.
1065
- $query_args['relation'] = 'OR';
1066
-
1067
- $query = new BP_Activity_Query( $query_args );
1068
- $sql = $query->get_sql();
1069
- if ( ! empty( $sql ) ) {
1070
- $retval['sql'] = $sql;
1071
- }
1072
- }
1073
-
1074
- if ( ! empty( $override ) ) {
1075
- $retval['override'] = $override;
1076
- }
1077
-
1078
- return $retval;
1079
- }
1080
-
1081
- /**
1082
- * In BuddyPress 1.2.x, this was used to retrieve specific activity stream items (for example, on an activity's permalink page).
1083
- *
1084
- * As of 1.5.x, use BP_Activity_Activity::get() with an 'in' parameter instead.
1085
- *
1086
- * @since 1.2.0
1087
- *
1088
- * @deprecated 1.5
1089
- * @deprecated Use BP_Activity_Activity::get() with an 'in' parameter instead.
1090
- *
1091
- * @param mixed $activity_ids Array or comma-separated string of activity IDs to retrieve.
1092
- * @param int|bool $max Maximum number of results to return. (Optional; default is no maximum).
1093
- * @param int $page The set of results that the user is viewing. Used in pagination. (Optional; default is 1).
1094
- * @param int $per_page Specifies how many results per page. Used in pagination. (Optional; default is 25).
1095
- * @param string $sort MySQL column sort; ASC or DESC. (Optional; default is DESC).
1096
- * @param bool $display_comments Retrieve an activity item's associated comments or not. (Optional; default is false).
1097
- * @return array
1098
- */
1099
- public static function get_specific( $activity_ids, $max = false, $page = 1, $per_page = 25, $sort = 'DESC', $display_comments = false ) {
1100
- _deprecated_function( __FUNCTION__, '1.5', 'Use BP_Activity_Activity::get() with the "in" parameter instead.' );
1101
- return BP_Activity_Activity::get( $max, $page, $per_page, $sort, false, false, $display_comments, false, false, $activity_ids );
1102
- }
1103
-
1104
- /**
1105
- * Get the first activity ID that matches a set of criteria.
1106
- *
1107
- * @since 1.2.0
1108
- *
1109
- * @todo Should parameters be optional?
1110
- *
1111
- * @param int $user_id User ID to filter by.
1112
- * @param string $component Component to filter by.
1113
- * @param string $type Activity type to filter by.
1114
- * @param int $item_id Associated item to filter by.
1115
- * @param int $secondary_item_id Secondary associated item to filter by.
1116
- * @param string $action Action to filter by.
1117
- * @param string $content Content to filter by.
1118
- * @param string $date_recorded Date to filter by.
1119
- * @return int|false Activity ID on success, false if none is found.
1120
- */
1121
- public static function get_id( $user_id, $component, $type, $item_id, $secondary_item_id, $action, $content, $date_recorded ) {
1122
- global $wpdb;
1123
-
1124
- $bp = buddypress();
1125
-
1126
- $where_args = false;
1127
-
1128
- if ( ! empty( $user_id ) ) {
1129
- $where_args[] = $wpdb->prepare( "user_id = %d", $user_id );
1130
- }
1131
-
1132
- if ( ! empty( $component ) ) {
1133
- $where_args[] = $wpdb->prepare( "component = %s", $component );
1134
- }
1135
-
1136
- if ( ! empty( $type ) ) {
1137
- $where_args[] = $wpdb->prepare( "type = %s", $type );
1138
- }
1139
-
1140
- if ( ! empty( $item_id ) ) {
1141
- $where_args[] = $wpdb->prepare( "item_id = %d", $item_id );
1142
- }
1143
-
1144
- if ( ! empty( $secondary_item_id ) ) {
1145
- $where_args[] = $wpdb->prepare( "secondary_item_id = %d", $secondary_item_id );
1146
- }
1147
-
1148
- if ( ! empty( $action ) ) {
1149
- $where_args[] = $wpdb->prepare( "action = %s", $action );
1150
- }
1151
-
1152
- if ( ! empty( $content ) ) {
1153
- $where_args[] = $wpdb->prepare( "content = %s", $content );
1154
- }
1155
-
1156
- if ( ! empty( $date_recorded ) ) {
1157
- $where_args[] = $wpdb->prepare( "date_recorded = %s", $date_recorded );
1158
- }
1159
-
1160
- if ( ! empty( $where_args ) ) {
1161
- $where_sql = 'WHERE ' . join( ' AND ', $where_args );
1162
- $result = $wpdb->get_var( "SELECT id FROM {$bp->activity->table_name} {$where_sql}" );
1163
-
1164
- return is_numeric( $result ) ? (int) $result : false;
1165
- }
1166
-
1167
- return false;
1168
- }
1169
-
1170
- /**
1171
- * Delete activity items from the database.
1172
- *
1173
- * To delete a specific activity item, pass an 'id' parameter.
1174
- * Otherwise use the filters.
1175
- *
1176
- * @since 1.2.0
1177
- *
1178
- * @param array $args {
1179
- * @int $id Optional. The ID of a specific item to delete.
1180
- * @string $action Optional. The action to filter by.
1181
- * @string $content Optional. The content to filter by.
1182
- * @string $component Optional. The component name to filter by.
1183
- * @string $type Optional. The activity type to filter by.
1184
- * @string $primary_link Optional. The primary URL to filter by.
1185
- * @int $user_id Optional. The user ID to filter by.
1186
- * @int $item_id Optional. The associated item ID to filter by.
1187
- * @int $secondary_item_id Optional. The secondary associated item ID to filter by.
1188
- * @string $date_recorded Optional. The date to filter by.
1189
- * @int $hide_sitewide Optional. Default: false.
1190
- * }
1191
- * @return array|bool An array of deleted activity IDs on success, false on failure.
1192
- */
1193
- public static function delete( $args = array() ) {
1194
- global $wpdb;
1195
-
1196
- $bp = buddypress();
1197
- $r = wp_parse_args( $args, array(
1198
- 'id' => false,
1199
- 'action' => false,
1200
- 'content' => false,
1201
- 'component' => false,
1202
- 'type' => false,
1203
- 'primary_link' => false,
1204
- 'user_id' => false,
1205
- 'item_id' => false,
1206
- 'secondary_item_id' => false,
1207
- 'date_recorded' => false,
1208
- 'hide_sitewide' => false
1209
- ) );
1210
-
1211
- // Setup empty array from where query arguments.
1212
- $where_args = array();
1213
-
1214
- // ID.
1215
- if ( ! empty( $r['id'] ) ) {
1216
- $where_args[] = $wpdb->prepare( "id = %d", $r['id'] );
1217
- }
1218
-
1219
- // User ID.
1220
- if ( ! empty( $r['user_id'] ) ) {
1221
- $where_args[] = $wpdb->prepare( "user_id = %d", $r['user_id'] );
1222
- }
1223
-
1224
- // Action.
1225
- if ( ! empty( $r['action'] ) ) {
1226
- $where_args[] = $wpdb->prepare( "action = %s", $r['action'] );
1227
- }
1228
-
1229
- // Content.
1230
- if ( ! empty( $r['content'] ) ) {
1231
- $where_args[] = $wpdb->prepare( "content = %s", $r['content'] );
1232
- }
1233
-
1234
- // Component.
1235
- if ( ! empty( $r['component'] ) ) {
1236
- $where_args[] = $wpdb->prepare( "component = %s", $r['component'] );
1237
- }
1238
-
1239
- // Type.
1240
- if ( ! empty( $r['type'] ) ) {
1241
- $where_args[] = $wpdb->prepare( "type = %s", $r['type'] );
1242
- }
1243
-
1244
- // Primary Link.
1245
- if ( ! empty( $r['primary_link'] ) ) {
1246
- $where_args[] = $wpdb->prepare( "primary_link = %s", $r['primary_link'] );
1247
- }
1248
-
1249
- // Item ID.
1250
- if ( ! empty( $r['item_id'] ) ) {
1251
- $where_args[] = $wpdb->prepare( "item_id = %d", $r['item_id'] );
1252
- }
1253
-
1254
- // Secondary item ID.
1255
- if ( ! empty( $r['secondary_item_id'] ) ) {
1256
- $where_args[] = $wpdb->prepare( "secondary_item_id = %d", $r['secondary_item_id'] );
1257
- }
1258
-
1259
- // Date Recorded.
1260
- if ( ! empty( $r['date_recorded'] ) ) {
1261
- $where_args[] = $wpdb->prepare( "date_recorded = %s", $r['date_recorded'] );
1262
- }
1263
-
1264
- // Hidden sitewide.
1265
- if ( ! empty( $r['hide_sitewide'] ) ) {
1266
- $where_args[] = $wpdb->prepare( "hide_sitewide = %d", $r['hide_sitewide'] );
1267
- }
1268
-
1269
- // Bail if no where arguments.
1270
- if ( empty( $where_args ) ) {
1271
- return false;
1272
- }
1273
-
1274
- // Join the where arguments for querying.
1275
- $where_sql = 'WHERE ' . join( ' AND ', $where_args );
1276
-
1277
- // Fetch all activities being deleted so we can perform more actions.
1278
- $activities = $wpdb->get_results( "SELECT * FROM {$bp->activity->table_name} {$where_sql}" );
1279
-
1280
- /**
1281
- * Action to allow intercepting activity items to be deleted.
1282
- *
1283
- * @since 2.3.0
1284
- *
1285
- * @param array $activities Array of activities.
1286
- * @param array $r Array of parsed arguments.
1287
- */
1288
- do_action_ref_array( 'bp_activity_before_delete', array( $activities, $r ) );
1289
-
1290
- // Attempt to delete activities from the database.
1291
- $deleted = $wpdb->query( "DELETE FROM {$bp->activity->table_name} {$where_sql}" );
1292
-
1293
- // Bail if nothing was deleted.
1294
- if ( empty( $deleted ) ) {
1295
- return false;
1296
- }
1297
-
1298
- /**
1299
- * Action to allow intercepting activity items just deleted.
1300
- *
1301
- * @since 2.3.0
1302
- *
1303
- * @param array $activities Array of activities.
1304
- * @param array $r Array of parsed arguments.
1305
- */
1306
- do_action_ref_array( 'bp_activity_after_delete', array( $activities, $r ) );
1307
-
1308
- // Pluck the activity IDs out of the $activities array.
1309
- $activity_ids = wp_parse_id_list( wp_list_pluck( $activities, 'id' ) );
1310
-
1311
- // Handle accompanying activity comments and meta deletion.
1312
- if ( ! empty( $activity_ids ) ) {
1313
-
1314
- // Delete all activity meta entries for activity items.
1315
- BP_Activity_Activity::delete_activity_meta_entries( $activity_ids );
1316
-
1317
- // Setup empty array for comments.
1318
- $comment_ids = array();
1319
-
1320
- // Loop through activity ids and attempt to delete comments.
1321
- foreach ( $activity_ids as $activity_id ) {
1322
-
1323
- // Attempt to delete comments.
1324
- $comments = BP_Activity_Activity::delete( array(
1325
- 'type' => 'activity_comment',
1326
- 'item_id' => $activity_id
1327
- ) );
1328
-
1329
- // Merge IDs together.
1330
- if ( ! empty( $comments ) ) {
1331
- $comment_ids = array_merge( $comment_ids, $comments );
1332
- }
1333
- }
1334
-
1335
- // Merge activity IDs with any deleted comment IDs.
1336
- if ( ! empty( $comment_ids ) ) {
1337
- $activity_ids = array_unique( array_merge( $activity_ids, $comment_ids ) );
1338
- }
1339
- }
1340
-
1341
- return $activity_ids;
1342
- }
1343
-
1344
- /**
1345
- * Delete the comments associated with a set of activity items.
1346
- *
1347
- * This method is no longer used by BuddyPress, and it is recommended not to
1348
- * use it going forward, and use BP_Activity_Activity::delete() instead.
1349
- *
1350
- * @since 1.2.0
1351
- *
1352
- * @deprecated 2.3.0
1353
- *
1354
- * @param array $activity_ids Activity IDs whose comments should be deleted.
1355
- * @param bool $delete_meta Should we delete the activity meta items for these comments.
1356
- * @return bool True on success.
1357
- */
1358
- public static function delete_activity_item_comments( $activity_ids = array(), $delete_meta = true ) {
1359
- global $wpdb;
1360
-
1361
- $bp = buddypress();
1362
-
1363
- $delete_meta = (bool) $delete_meta;
1364
- $activity_ids = implode( ',', wp_parse_id_list( $activity_ids ) );
1365
-
1366
- if ( $delete_meta ) {
1367
- // Fetch the activity comment IDs for our deleted activity items.
1368
- $activity_comment_ids = $wpdb->get_col( "SELECT id FROM {$bp->activity->table_name} WHERE type = 'activity_comment' AND item_id IN ({$activity_ids})" );
1369
-
1370
- if ( ! empty( $activity_comment_ids ) ) {
1371
- self::delete_activity_meta_entries( $activity_comment_ids );
1372
- }
1373
- }
1374
-
1375
- return $wpdb->query( "DELETE FROM {$bp->activity->table_name} WHERE type = 'activity_comment' AND item_id IN ({$activity_ids})" );
1376
- }
1377
-
1378
- /**
1379
- * Delete the meta entries associated with a set of activity items.
1380
- *
1381
- * @since 1.2.0
1382
- *
1383
- * @param array $activity_ids Activity IDs whose meta should be deleted.
1384
- * @return bool True on success.
1385
- */
1386
- public static function delete_activity_meta_entries( $activity_ids = array() ) {
1387
- $activity_ids = wp_parse_id_list( $activity_ids );
1388
-
1389
- foreach ( $activity_ids as $activity_id ) {
1390
- bp_activity_delete_meta( $activity_id );
1391
- }
1392
-
1393
- return true;
1394
- }
1395
-
1396
- /**
1397
- * Append activity comments to their associated activity items.
1398
- *
1399
- * @since 1.2.0
1400
- *
1401
- * @global wpdb $wpdb WordPress database object.
1402
- *
1403
- * @param array $activities Activities to fetch comments for.
1404
- * @param string $spam Optional. 'ham_only' (default), 'spam_only' or 'all'.
1405
- * @return array The updated activities with nested comments.
1406
- */
1407
- public static function append_comments( $activities, $spam = 'ham_only' ) {
1408
- $activity_comments = array();
1409
-
1410
- // Now fetch the activity comments and parse them into the correct position in the activities array.
1411
- foreach ( (array) $activities as $activity ) {
1412
- $top_level_parent_id = 'activity_comment' == $activity->type ? $activity->item_id : 0;
1413
- $activity_comments[$activity->id] = BP_Activity_Activity::get_activity_comments( $activity->id, $activity->mptt_left, $activity->mptt_right, $spam, $top_level_parent_id );
1414
- }
1415
-
1416
- // Merge the comments with the activity items.
1417
- foreach ( (array) $activities as $key => $activity ) {
1418
- if ( isset( $activity_comments[$activity->id] ) ) {
1419
- $activities[$key]->children = $activity_comments[$activity->id];
1420
- }
1421
- }
1422
-
1423
- return $activities;
1424
- }
1425
-
1426
- /**
1427
- * Get activity comments that are associated with a specific activity ID.
1428
- *
1429
- * @since 1.2.0
1430
- *
1431
- * @global wpdb $wpdb WordPress database object.
1432
- *
1433
- * @param int $activity_id Activity ID to fetch comments for.
1434
- * @param int $left Left-most node boundary.
1435
- * @param int $right Right-most node boundary.
1436
- * @param string $spam Optional. 'ham_only' (default), 'spam_only' or 'all'.
1437
- * @param int $top_level_parent_id Optional. The id of the root-level parent activity item.
1438
- * @return array The updated activities with nested comments.
1439
- */
1440
- public static function get_activity_comments( $activity_id, $left, $right, $spam = 'ham_only', $top_level_parent_id = 0 ) {
1441
- global $wpdb;
1442
-
1443
- if ( empty( $top_level_parent_id ) ) {
1444
- $top_level_parent_id = $activity_id;
1445
- }
1446
-
1447
- $comments = wp_cache_get( $activity_id, 'bp_activity_comments' );
1448
-
1449
- // We store the string 'none' to cache the fact that the
1450
- // activity item has no comments.
1451
- if ( 'none' === $comments ) {
1452
- $comments = false;
1453
-
1454
- // A true cache miss.
1455
- } elseif ( empty( $comments ) ) {
1456
-
1457
- $bp = buddypress();
1458
-
1459
- // Select the user's fullname with the query.
1460
- if ( bp_is_active( 'xprofile' ) ) {
1461
- $fullname_select = ", pd.value as user_fullname";
1462
- $fullname_from = ", {$bp->profile->table_name_data} pd ";
1463
- $fullname_where = "AND pd.user_id = a.user_id AND pd.field_id = 1";
1464
-
1465
- // Prevent debug errors.
1466
- } else {
1467
- $fullname_select = $fullname_from = $fullname_where = '';
1468
- }
1469
-
1470
- // Don't retrieve activity comments marked as spam.
1471
- if ( 'ham_only' == $spam ) {
1472
- $spam_sql = 'AND a.is_spam = 0';
1473
- } elseif ( 'spam_only' == $spam ) {
1474
- $spam_sql = 'AND a.is_spam = 1';
1475
- } else {
1476
- $spam_sql = '';
1477
- }
1478
-
1479
- // Legacy query - not recommended.
1480
-
1481
- /**
1482
- * Filters if BuddyPress should use the legacy activity query.
1483
- *
1484
- * @since 2.0.0
1485
- *
1486
- * @param bool $value Whether or not to use the legacy query.
1487
- * @param BP_Activity_Activity $value Magic method referring to currently called method.
1488
- * @param array $func_args Array of the method's argument list.
1489
- */
1490
- if ( apply_filters( 'bp_use_legacy_activity_query', false, __METHOD__, func_get_args() ) ) {
1491
-
1492
- /**
1493
- * Filters the MySQL prepared statement for the legacy activity query.
1494
- *
1495
- * @since 1.5.0
1496
- *
1497
- * @param string $value Prepared statement for the activity query.
1498
- * @param int $activity_id Activity ID to fetch comments for.
1499
- * @param int $left Left-most node boundary.
1500
- * @param int $right Right-most node boundary.
1501
- * @param string $spam_sql SQL Statement portion to differentiate between ham or spam.
1502
- */
1503
- $sql = apply_filters( 'bp_activity_comments_user_join_filter', $wpdb->prepare( "SELECT a.*, u.user_email, u.user_nicename, u.user_login, u.display_name{$fullname_select} FROM {$bp->activity->table_name} a, {$wpdb->users} u{$fullname_from} WHERE u.ID = a.user_id {$fullname_where} AND a.type = 'activity_comment' {$spam_sql} AND a.item_id = %d AND a.mptt_left > %d AND a.mptt_left < %d ORDER BY a.date_recorded ASC", $top_level_parent_id, $left, $right ), $activity_id, $left, $right, $spam_sql );
1504
-
1505
- $descendants = $wpdb->get_results( $sql );
1506
-
1507
- // We use the mptt BETWEEN clause to limit returned
1508
- // descendants to the correct part of the tree.
1509
- } else {
1510
- $sql = $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} a WHERE a.type = 'activity_comment' {$spam_sql} AND a.item_id = %d and a.mptt_left > %d AND a.mptt_left < %d ORDER BY a.date_recorded ASC", $top_level_parent_id, $left, $right );
1511
-
1512
- $descendant_ids = $wpdb->get_col( $sql );
1513
- $descendants = self::get_activity_data( $descendant_ids );
1514
- $descendants = self::append_user_fullnames( $descendants );
1515
- }
1516
-
1517
- $ref = array();
1518
-
1519
- // Loop descendants and build an assoc array.
1520
- foreach ( (array) $descendants as $d ) {
1521
- $d->children = array();
1522
-
1523
- // If we have a reference on the parent.
1524
- if ( isset( $ref[ $d->secondary_item_id ] ) ) {
1525
- $ref[ $d->secondary_item_id ]->children[ $d->id ] = $d;
1526
- $ref[ $d->id ] =& $ref[ $d->secondary_item_id ]->children[ $d->id ];
1527
-
1528
- // If we don't have a reference on the parent, put in the root level.
1529
- } else {
1530
- $comments[ $d->id ] = $d;
1531
- $ref[ $d->id ] =& $comments[ $d->id ];
1532
- }
1533
- }
1534
-
1535
- // Calculate depth for each item.
1536
- foreach ( $ref as &$r ) {
1537
- $depth = 1;
1538
- $parent_id = $r->secondary_item_id;
1539
-
1540
- while ( $parent_id !== $r->item_id ) {
1541
- $depth++;
1542
-
1543
- // When display_comments=stream, the parent comment may not be part of the
1544
- // returned results, so we manually fetch it.
1545
- if ( empty( $ref[ $parent_id ] ) ) {
1546
- $direct_parent = new BP_Activity_Activity( $parent_id );
1547
- if ( isset( $direct_parent->secondary_item_id ) ) {
1548
- // If the direct parent is not an activity update, that means we've reached
1549
- // the parent activity item (eg. new_blog_post).
1550
- if ( 'activity_update' !== $direct_parent->type ) {
1551
- $parent_id = $r->item_id;
1552
-
1553
- } else {
1554
- $parent_id = $direct_parent->secondary_item_id;
1555
- }
1556
-
1557
- } else {
1558
- // Something went wrong. Short-circuit the depth calculation.
1559
- $parent_id = $r->item_id;
1560
- }
1561
- } else {
1562
- $parent_id = $ref[ $parent_id ]->secondary_item_id;
1563
- }
1564
- }
1565
- $r->depth = $depth;
1566
- }
1567
-
1568
- // If we cache a value of false, it'll count as a cache
1569
- // miss the next time the activity comments are fetched.
1570
- // Storing the string 'none' is a hack workaround to
1571
- // avoid unnecessary queries.
1572
- if ( false === $comments ) {
1573
- $cache_value = 'none';
1574
- } else {
1575
- $cache_value = $comments;
1576
- }
1577
-
1578
- wp_cache_set( $activity_id, $cache_value, 'bp_activity_comments' );
1579
- }
1580
-
1581
- return $comments;
1582
- }
1583
-
1584
- /**
1585
- * Rebuild nested comment tree under an activity or activity comment.
1586
- *
1587
- * @since 1.2.0
1588
- *
1589
- * @global wpdb $wpdb WordPress database object.
1590
- *
1591
- * @param int $parent_id ID of an activity or activity comment.
1592
- * @param int $left Node boundary start for activity or activity comment.
1593
- * @return int Right Node boundary of activity or activity comment.
1594
- */
1595
- public static function rebuild_activity_comment_tree( $parent_id, $left = 1 ) {
1596
- global $wpdb;
1597
-
1598
- $bp = buddypress();
1599
-
1600
- // The right value of this node is the left value + 1.
1601
- $right = intval( $left + 1 );
1602
-
1603
- // Get all descendants of this node.
1604
- $comments = BP_Activity_Activity::get_child_comments( $parent_id );
1605
- $descendants = wp_list_pluck( $comments, 'id' );
1606
-
1607
- // Loop the descendants and recalculate the left and right values.
1608
- foreach ( (array) $descendants as $descendant_id ) {
1609
- $right = BP_Activity_Activity::rebuild_activity_comment_tree( $descendant_id, $right );
1610
- }
1611
-
1612
- // We've got the left value, and now that we've processed the children
1613
- // of this node we also know the right value.
1614
- if ( 1 === $left ) {
1615
- $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET mptt_left = %d, mptt_right = %d WHERE id = %d", $left, $right, $parent_id ) );
1616
- } else {
1617
- $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET mptt_left = %d, mptt_right = %d WHERE type = 'activity_comment' AND id = %d", $left, $right, $parent_id ) );
1618
- }
1619
-
1620
- // Return the right value of this node + 1.
1621
- return intval( $right + 1 );
1622
- }
1623
-
1624
- /**
1625
- * Get child comments of an activity or activity comment.
1626
- *
1627
- * @since 1.2.0
1628
- *
1629
- * @global wpdb $wpdb WordPress database object.
1630
- *
1631
- * @param int $parent_id ID of an activity or activity comment.
1632
- * @return object Numerically indexed array of child comments.
1633
- */
1634
- public static function get_child_comments( $parent_id ) {
1635
- global $wpdb;
1636
-
1637
- $bp = buddypress();
1638
-
1639
- return $wpdb->get_results( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE type = 'activity_comment' AND secondary_item_id = %d", $parent_id ) );
1640
- }
1641
-
1642
- /**
1643
- * Get a list of components that have recorded activity associated with them.
1644
- *
1645
- * @since 1.2.0
1646
- *
1647
- * @param bool $skip_last_activity If true, components will not be
1648
- * included if the only activity type associated with them is
1649
- * 'last_activity'. (Since 2.0.0, 'last_activity' is stored in
1650
- * the activity table, but these items are not full-fledged
1651
- * activity items.) Default: true.
1652
- * @return array List of component names.
1653
- */
1654
- public static function get_recorded_components( $skip_last_activity = true ) {
1655
- global $wpdb;
1656
-
1657
- $bp = buddypress();
1658
-
1659
- if ( true === $skip_last_activity ) {
1660
- $components = $wpdb->get_col( "SELECT DISTINCT component FROM {$bp->activity->table_name} WHERE action != '' AND action != 'last_activity' ORDER BY component ASC" );
1661
- } else {
1662
- $components = $wpdb->get_col( "SELECT DISTINCT component FROM {$bp->activity->table_name} ORDER BY component ASC" );
1663
- }
1664
-
1665
- return $components;
1666
- }
1667
-
1668
- /**
1669
- * Get sitewide activity items for use in an RSS feed.
1670
- *
1671
- * @since 1.0.0
1672
- *
1673
- * @param int $limit Optional. Number of items to fetch. Default: 35.
1674
- * @return array $activity_feed List of activity items, with RSS data added.
1675
- */
1676
- public static function get_sitewide_items_for_feed( $limit = 35 ) {
1677
- $activities = bp_activity_get_sitewide( array( 'max' => $limit ) );
1678
- $activity_feed = array();
1679
-
1680
- for ( $i = 0, $count = count( $activities ); $i < $count; ++$i ) {
1681
- $title = explode( '<span', $activities[$i]['content'] );
1682
- $activity_feed[$i]['title'] = trim( strip_tags( $title[0] ) );
1683
- $activity_feed[$i]['link'] = $activities[$i]['primary_link'];
1684
- $activity_feed[$i]['description'] = @sprintf( $activities[$i]['content'], '' );
1685
- $activity_feed[$i]['pubdate'] = $activities[$i]['date_recorded'];
1686
- }
1687
-
1688
- return $activity_feed;
1689
- }
1690
-
1691
- /**
1692
- * Create SQL IN clause for filter queries.
1693
- *
1694
- * @since 1.5.0
1695
- *
1696
- * @see BP_Activity_Activity::get_filter_sql()
1697
- *
1698
- * @param string $field The database field.
1699
- * @param array|bool $items The values for the IN clause, or false when none are found.
1700
- * @return string|false
1701
- */
1702
- public static function get_in_operator_sql( $field, $items ) {
1703
- global $wpdb;
1704
-
1705
- // Split items at the comma.
1706
- if ( ! is_array( $items ) ) {
1707
- $items = explode( ',', $items );
1708
- }
1709
-
1710
- // Array of prepared integers or quoted strings.
1711
- $items_prepared = array();
1712
-
1713
- // Clean up and format each item.
1714
- foreach ( $items as $item ) {
1715
- // Clean up the string.
1716
- $item = trim( $item );
1717
- // Pass everything through prepare for security and to safely quote strings.
1718
- $items_prepared[] = ( is_numeric( $item ) ) ? $wpdb->prepare( '%d', $item ) : $wpdb->prepare( '%s', $item );
1719
- }
1720
-
1721
- // Build IN operator sql syntax.
1722
- if ( count( $items_prepared ) )
1723
- return sprintf( '%s IN ( %s )', trim( $field ), implode( ',', $items_prepared ) );
1724
- else
1725
- return false;
1726
- }
1727
-
1728
- /**
1729
- * Create filter SQL clauses.
1730
- *
1731
- * @since 1.5.0
1732
- *
1733
- * @param array $filter_array {
1734
- * Fields and values to filter by.
1735
- *
1736
- * @type array|string|int $user_id User ID(s).
1737
- * @type array|string $object Corresponds to the 'component'
1738
- * column in the database.
1739
- * @type array|string $action Corresponds to the 'type' column
1740
- * in the database.
1741
- * @type array|string|int $primary_id Corresponds to the 'item_id'
1742
- * column in the database.
1743
- * @type array|string|int $secondary_id Corresponds to the
1744
- * 'secondary_item_id' column in the database.
1745
- * @type int $offset Return only those items with an ID greater
1746
- * than the offset value.
1747
- * @type string $since Return only those items that have a
1748
- * date_recorded value greater than a
1749
- * given MySQL-formatted date.
1750
- * }
1751
- * @return string The filter clause, for use in a SQL query.
1752
- */
1753
- public static function get_filter_sql( $filter_array ) {
1754
-
1755
- $filter_sql = array();
1756
-
1757
- if ( !empty( $filter_array['user_id'] ) ) {
1758
- $user_sql = BP_Activity_Activity::get_in_operator_sql( 'a.user_id', $filter_array['user_id'] );
1759
- if ( !empty( $user_sql ) )
1760
- $filter_sql[] = $user_sql;
1761
- }
1762
-
1763
- if ( !empty( $filter_array['object'] ) ) {
1764
- $object_sql = BP_Activity_Activity::get_in_operator_sql( 'a.component', $filter_array['object'] );
1765
- if ( !empty( $object_sql ) )
1766
- $filter_sql[] = $object_sql;
1767
- }
1768
-
1769
- if ( !empty( $filter_array['action'] ) ) {
1770
- $action_sql = BP_Activity_Activity::get_in_operator_sql( 'a.type', $filter_array['action'] );
1771
- if ( ! empty( $action_sql ) )
1772
- $filter_sql[] = $action_sql;
1773
- }
1774
-
1775
- if ( !empty( $filter_array['primary_id'] ) ) {
1776
- $pid_sql = BP_Activity_Activity::get_in_operator_sql( 'a.item_id', $filter_array['primary_id'] );
1777
- if ( !empty( $pid_sql ) )
1778
- $filter_sql[] = $pid_sql;
1779
- }
1780
-
1781
- if ( !empty( $filter_array['secondary_id'] ) ) {
1782
- $sid_sql = BP_Activity_Activity::get_in_operator_sql( 'a.secondary_item_id', $filter_array['secondary_id'] );
1783
- if ( !empty( $sid_sql ) )
1784
- $filter_sql[] = $sid_sql;
1785
- }
1786
-
1787
- if ( ! empty( $filter_array['offset'] ) ) {
1788
- $sid_sql = absint( $filter_array['offset'] );
1789
- $filter_sql[] = "a.id >= {$sid_sql}";
1790
- }
1791
-
1792
- if ( ! empty( $filter_array['since'] ) ) {
1793
- // Validate that this is a proper Y-m-d H:i:s date.
1794
- // Trick: parse to UNIX date then translate back.
1795
- $translated_date = date( 'Y-m-d H:i:s', strtotime( $filter_array['since'] ) );
1796
- if ( $translated_date === $filter_array['since'] ) {
1797
- $filter_sql[] = "a.date_recorded > '{$translated_date}'";
1798
- }
1799
- }
1800
-
1801
- if ( empty( $filter_sql ) )
1802
- return false;
1803
-
1804
- return join( ' AND ', $filter_sql );
1805
- }
1806
-
1807
- /**
1808
- * Get the date/time of last recorded activity.
1809
- *
1810
- * @since 1.2.0
1811
- *
1812
- * @return string ISO timestamp.
1813
- */
1814
- public static function get_last_updated() {
1815
- global $wpdb;
1816
-
1817
- $bp = buddypress();
1818
-
1819
- return $wpdb->get_var( "SELECT date_recorded FROM {$bp->activity->table_name} ORDER BY date_recorded DESC LIMIT 1" );
1820
- }
1821
-
1822
- /**
1823
- * Get favorite count for a given user.
1824
- *
1825
- * @since 1.2.0
1826
- *
1827
- * @param int $user_id The ID of the user whose favorites you're counting.
1828
- * @return int $value A count of the user's favorites.
1829
- */
1830
- public static function total_favorite_count( $user_id ) {
1831
-
1832
- // Get activities from user meta.
1833
- $favorite_activity_entries = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
1834
- if ( ! empty( $favorite_activity_entries ) ) {
1835
- return count( $favorite_activity_entries );
1836
- }
1837
-
1838
- // No favorites.
1839
- return 0;
1840
- }
1841
-
1842
- /**
1843
- * Check whether an activity item exists with a given string content.
1844
- *
1845
- * @since 1.1.0
1846
- *
1847
- * @param string $content The content to filter by.
1848
- * @return int|false The ID of the first matching item if found, otherwise false.
1849
- */
1850
- public static function check_exists_by_content( $content ) {
1851
- global $wpdb;
1852
-
1853
- $bp = buddypress();
1854
-
1855
- $result = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE content = %s", $content ) );
1856
-
1857
- return is_numeric( $result ) ? (int) $result : false;
1858
- }
1859
-
1860
- /**
1861
- * Hide all activity for a given user.
1862
- *
1863
- * @since 1.2.0
1864
- *
1865
- * @param int $user_id The ID of the user whose activity you want to mark hidden.
1866
- * @return mixed
1867
- */
1868
- public static function hide_all_for_user( $user_id ) {
1869
- global $wpdb;
1870
-
1871
- $bp = buddypress();
1872
-
1873
- return $wpdb->get_var( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET hide_sitewide = 1 WHERE user_id = %d", $user_id ) );
1874
- }
1875
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/classes/class-bp-activity-component.php DELETED
@@ -1,384 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Activity Streams Loader.
4
- *
5
- * An activity stream component, for users, groups, and site tracking.
6
- *
7
- * @package BuddyPress
8
- * @subpackage ActivityCore
9
- * @since 1.5.0
10
- */
11
-
12
- // Exit if accessed directly.
13
- defined( 'ABSPATH' ) || exit;
14
-
15
- /**
16
- * Main Activity Class.
17
- *
18
- * @since 1.5.0
19
- */
20
- class BP_Activity_Component extends BP_Component {
21
-
22
- /**
23
- * Start the activity component setup process.
24
- *
25
- * @since 1.5.0
26
- */
27
- public function __construct() {
28
- parent::start(
29
- 'activity',
30
- __( 'Activity Streams', 'buddypress' ),
31
- buddypress()->plugin_dir,
32
- array(
33
- 'adminbar_myaccount_order' => 10,
34
- 'search_query_arg' => 'activity_search',
35
- 'features' => array( 'embeds' )
36
- )
37
- );
38
- }
39
-
40
- /**
41
- * Include component files.
42
- *
43
- * @since 1.5.0
44
- *
45
- * @see BP_Component::includes() for a description of arguments.
46
- *
47
- * @param array $includes See BP_Component::includes() for a description.
48
- */
49
- public function includes( $includes = array() ) {
50
-
51
- // Files to include.
52
- $includes = array(
53
- 'cssjs',
54
- 'actions',
55
- 'screens',
56
- 'filters',
57
- 'adminbar',
58
- 'template',
59
- 'functions',
60
- 'cache'
61
- );
62
-
63
- // Notifications support.
64
- if ( bp_is_active( 'notifications' ) ) {
65
- $includes[] = 'notifications';
66
- }
67
-
68
- // Load Akismet support if Akismet is configured.
69
- $akismet_key = bp_get_option( 'wordpress_api_key' );
70
-
71
- /** This filter is documented in bp-activity/bp-activity-akismet.php */
72
- if ( defined( 'AKISMET_VERSION' ) && class_exists( 'Akismet' ) && ( ! empty( $akismet_key ) || defined( 'WPCOM_API_KEY' ) ) && apply_filters( 'bp_activity_use_akismet', bp_is_akismet_active() ) ) {
73
- $includes[] = 'akismet';
74
- }
75
-
76
- // Embeds - only applicable for WP 4.5+
77
- if ( version_compare( $GLOBALS['wp_version'], '4.5', '>=' ) && bp_is_active( $this->id, 'embeds' ) ) {
78
- $includes[] = 'embeds';
79
- }
80
-
81
- if ( is_admin() ) {
82
- $includes[] = 'admin';
83
- }
84
-
85
- parent::includes( $includes );
86
- }
87
-
88
- /**
89
- * Set up component global variables.
90
- *
91
- * The BP_ACTIVITY_SLUG constant is deprecated, and only used here for
92
- * backwards compatibility.
93
- *
94
- * @since 1.5.0
95
- *
96
- * @see BP_Component::setup_globals() for a description of arguments.
97
- *
98
- * @param array $args See BP_Component::setup_globals() for a description.
99
- */
100
- public function setup_globals( $args = array() ) {
101
- $bp = buddypress();
102
-
103
- // Define a slug, if necessary.
104
- if ( ! defined( 'BP_ACTIVITY_SLUG' ) ) {
105
- define( 'BP_ACTIVITY_SLUG', $this->id );
106
- }
107
-
108
- // Global tables for activity component.
109
- $global_tables = array(
110
- 'table_name' => $bp->table_prefix . 'bp_activity',
111
- 'table_name_meta' => $bp->table_prefix . 'bp_activity_meta',
112
- );
113
-
114
- // Metadata tables for groups component.
115
- $meta_tables = array(
116
- 'activity' => $bp->table_prefix . 'bp_activity_meta',
117
- );
118
-
119
- // Fetch the default directory title.
120
- $default_directory_titles = bp_core_get_directory_page_default_titles();
121
- $default_directory_title = $default_directory_titles[$this->id];
122
-
123
- // All globals for activity component.
124
- // Note that global_tables is included in this array.
125
- $args = array(
126
- 'slug' => BP_ACTIVITY_SLUG,
127
- 'root_slug' => isset( $bp->pages->activity->slug ) ? $bp->pages->activity->slug : BP_ACTIVITY_SLUG,
128
- 'has_directory' => true,
129
- 'directory_title' => isset( $bp->pages->activity->title ) ? $bp->pages->activity->title : $default_directory_title,
130
- 'notification_callback' => 'bp_activity_format_notifications',
131
- 'search_string' => __( 'Search Activity...', 'buddypress' ),
132
- 'global_tables' => $global_tables,
133
- 'meta_tables' => $meta_tables,
134
- );
135
-
136
- parent::setup_globals( $args );
137
- }
138
-
139
- /**
140
- * Set up component navigation.
141
- *
142
- * @since 1.5.0
143
- *
144
- * @see BP_Component::setup_nav() for a description of arguments.
145
- *
146
- * @param array $main_nav Optional. See BP_Component::setup_nav() for description.
147
- * @param array $sub_nav Optional. See BP_Component::setup_nav() for description.
148
- */
149
- public function setup_nav( $main_nav = array(), $sub_nav = array() ) {
150
-
151
- // Stop if there is no user displayed or logged in.
152
- if ( ! is_user_logged_in() && ! bp_displayed_user_id() ) {
153
- return;
154
- }
155
-
156
- // Determine user to use.
157
- if ( bp_displayed_user_domain() ) {
158
- $user_domain = bp_displayed_user_domain();
159
- } elseif ( bp_loggedin_user_domain() ) {
160
- $user_domain = bp_loggedin_user_domain();
161
- } else {
162
- return;
163
- }
164
-
165
- $slug = bp_get_activity_slug();
166
- $activity_link = trailingslashit( $user_domain . $slug );
167
-
168
- // Add 'Activity' to the main navigation.
169
- $main_nav = array(
170
- 'name' => _x( 'Activity', 'Profile activity screen nav', 'buddypress' ),
171
- 'slug' => $slug,
172
- 'position' => 10,
173
- 'screen_function' => 'bp_activity_screen_my_activity',
174
- 'default_subnav_slug' => 'just-me',
175
- 'item_css_id' => $this->id
176
- );
177
-
178
- // Add the subnav items to the activity nav item if we are using a theme that supports this.
179
- $sub_nav[] = array(
180
- 'name' => _x( 'Personal', 'Profile activity screen sub nav', 'buddypress' ),
181
- 'slug' => 'just-me',
182
- 'parent_url' => $activity_link,
183
- 'parent_slug' => $slug,
184
- 'screen_function' => 'bp_activity_screen_my_activity',
185
- 'position' => 10
186
- );
187
-
188
- // Check @mentions.
189
- if ( bp_activity_do_mentions() ) {
190
- $sub_nav[] = array(
191
- 'name' => _x( 'Mentions', 'Profile activity screen sub nav', 'buddypress' ),
192
- 'slug' => 'mentions',
193
- 'parent_url' => $activity_link,
194
- 'parent_slug' => $slug,
195
- 'screen_function' => 'bp_activity_screen_mentions',
196
- 'position' => 20,
197
- 'item_css_id' => 'activity-mentions'
198
- );
199
- }
200
-
201
- // Favorite activity items.
202
- if ( bp_activity_can_favorite() ) {
203
- $sub_nav[] = array(
204
- 'name' => _x( 'Favorites', 'Profile activity screen sub nav', 'buddypress' ),
205
- 'slug' => 'favorites',
206
- 'parent_url' => $activity_link,
207
- 'parent_slug' => $slug,
208
- 'screen_function' => 'bp_activity_screen_favorites',
209
- 'position' => 30,
210
- 'item_css_id' => 'activity-favs'
211
- );
212
- }
213
-
214
- // Additional menu if friends is active.
215
- if ( bp_is_active( 'friends' ) ) {
216
- $sub_nav[] = array(
217
- 'name' => _x( 'Friends', 'Profile activity screen sub nav', 'buddypress' ),
218
- 'slug' => bp_get_friends_slug(),
219
- 'parent_url' => $activity_link,
220
- 'parent_slug' => $slug,
221
- 'screen_function' => 'bp_activity_screen_friends',
222
- 'position' => 40,
223
- 'item_css_id' => 'activity-friends'
224
- ) ;
225
- }
226
-
227
- // Additional menu if groups is active.
228
- if ( bp_is_active( 'groups' ) ) {
229
- $sub_nav[] = array(
230
- 'name' => _x( 'Groups', 'Profile activity screen sub nav', 'buddypress' ),
231
- 'slug' => bp_get_groups_slug(),
232
- 'parent_url' => $activity_link,
233
- 'parent_slug' => $slug,
234
- 'screen_function' => 'bp_activity_screen_groups',
235
- 'position' => 50,
236
- 'item_css_id' => 'activity-groups'
237
- );
238
- }
239
-
240
- parent::setup_nav( $main_nav, $sub_nav );
241
- }
242
-
243
- /**
244
- * Set up the component entries in the WordPress Admin Bar.
245
- *
246
- * @since 1.5.0
247
- *
248
- * @see BP_Component::setup_nav() for a description of the $wp_admin_nav
249
- * parameter array.
250
- *
251
- * @param array $wp_admin_nav See BP_Component::setup_admin_bar() for a
252
- * description.
253
- */
254
- public function setup_admin_bar( $wp_admin_nav = array() ) {
255
-
256
- // Menus for logged in user.
257
- if ( is_user_logged_in() ) {
258
-
259
- // Setup the logged in user variables.
260
- $activity_link = trailingslashit( bp_loggedin_user_domain() . bp_get_activity_slug() );
261
-
262
- // Unread message count.
263
- if ( bp_activity_do_mentions() ) {
264
- $count = bp_get_total_mention_count_for_user( bp_loggedin_user_id() );
265
- if ( !empty( $count ) ) {
266
- $title = sprintf(
267
- /* translators: %s: Unread mention count for the current user */
268
- _x( 'Mentions %s', 'Toolbar Mention logged in user', 'buddypress' ),
269
- '<span class="count">' . bp_core_number_format( $count ) . '</span>'
270
- );
271
- } else {
272
- $title = _x( 'Mentions', 'Toolbar Mention logged in user', 'buddypress' );
273
- }
274
- }
275
-
276
- // Add the "Activity" sub menu.
277
- $wp_admin_nav[] = array(
278
- 'parent' => buddypress()->my_account_menu_id,
279
- 'id' => 'my-account-' . $this->id,
280
- 'title' => _x( 'Activity', 'My Account Activity sub nav', 'buddypress' ),
281
- 'href' => $activity_link
282
- );
283
-
284
- // Personal.
285
- $wp_admin_nav[] = array(
286
- 'parent' => 'my-account-' . $this->id,
287
- 'id' => 'my-account-' . $this->id . '-personal',
288
- 'title' => _x( 'Personal', 'My Account Activity sub nav', 'buddypress' ),
289
- 'href' => $activity_link,
290
- 'position' => 10
291
- );
292
-
293
- // Mentions.
294
- if ( bp_activity_do_mentions() ) {
295
- $wp_admin_nav[] = array(
296
- 'parent' => 'my-account-' . $this->id,
297
- 'id' => 'my-account-' . $this->id . '-mentions',
298
- 'title' => $title,
299
- 'href' => trailingslashit( $activity_link . 'mentions' ),
300
- 'position' => 20
301
- );
302
- }
303
-
304
- // Favorite activity items.
305
- if ( bp_activity_can_favorite() ) {
306
- $wp_admin_nav[] = array(
307
- 'parent' => 'my-account-' . $this->id,
308
- 'id' => 'my-account-' . $this->id . '-favorites',
309
- 'title' => _x( 'Favorites', 'My Account Activity sub nav', 'buddypress' ),
310
- 'href' => trailingslashit( $activity_link . 'favorites' ),
311
- 'position' => 30
312
- );
313
- }
314
-
315
- // Friends?
316
- if ( bp_is_active( 'friends' ) ) {
317
- $wp_admin_nav[] = array(
318
- 'parent' => 'my-account-' . $this->id,
319
- 'id' => 'my-account-' . $this->id . '-friends',
320
- 'title' => _x( 'Friends', 'My Account Activity sub nav', 'buddypress' ),
321
- 'href' => trailingslashit( $activity_link . bp_get_friends_slug() ),
322
- 'position' => 40
323
- );
324
- }
325
-
326
- // Groups?
327
- if ( bp_is_active( 'groups' ) ) {
328
- $wp_admin_nav[] = array(
329
- 'parent' => 'my-account-' . $this->id,
330
- 'id' => 'my-account-' . $this->id . '-groups',
331
- 'title' => _x( 'Groups', 'My Account Activity sub nav', 'buddypress' ),
332
- 'href' => trailingslashit( $activity_link . bp_get_groups_slug() ),
333
- 'position' => 50
334
- );
335
- }
336
- }
337
-
338
- parent::setup_admin_bar( $wp_admin_nav );
339
- }
340
-
341
- /**
342
- * Set up the title for pages and <title>.
343
- *
344
- * @since 1.5.0
345
- *
346
- */
347
- public function setup_title() {
348
-
349
- // Adjust title based on view.
350
- if ( bp_is_activity_component() ) {
351
- $bp = buddypress();
352
-
353
- if ( bp_is_my_profile() ) {
354
- $bp->bp_options_title = _x( 'My Activity', 'Page and <title>', 'buddypress' );
355
- } else {
356
- $bp->bp_options_avatar = bp_core_fetch_avatar( array(
357
- 'item_id' => bp_displayed_user_id(),
358
- 'type' => 'thumb',
359
- 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_get_displayed_user_fullname() )
360
- ) );
361
- $bp->bp_options_title = bp_get_displayed_user_fullname();
362
- }
363
- }
364
-
365
- parent::setup_title();
366
- }
367
-
368
- /**
369
- * Setup cache groups.
370
- *
371
- * @since 2.2.0
372
- */
373
- public function setup_cache_groups() {
374
-
375
- // Global groups.
376
- wp_cache_add_global_groups( array(
377
- 'bp_activity',
378
- 'bp_activity_comments',
379
- 'activity_meta'
380
- ) );
381
-
382
- parent::setup_cache_groups();
383
- }
384
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/classes/class-bp-activity-feed.php DELETED
@@ -1,468 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Activity Classes.
4
- *
5
- * @package BuddyPress
6
- * @subpackage ActivityFeeds
7
- * @since 1.8.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Create a RSS feed using the activity component.
15
- *
16
- * You should only construct a new feed when you've validated that you're on
17
- * the appropriate screen.
18
- *
19
- * @since 1.8.0
20
- *
21
- * See {@link bp_activity_action_sitewide_feed()} as an example.
22
- *
23
- * @param array $args {
24
- * @type string $id Required. Internal id for the feed; should be alphanumeric only.
25
- * @type string $title Optional. RSS feed title.
26
- * @type string $link Optional. Relevant link for the RSS feed.
27
- * @type string $description Optional. RSS feed description.
28
- * @type string $ttl Optional. Time-to-live. (see inline doc in constructor)
29
- * @type string $update_period Optional. Part of the syndication module.
30
- * (see inline doc in constructor for more info)
31
- * @type string $update_frequency Optional. Part of the syndication module.
32
- * (see inline doc in constructor for more info)
33
- * @type string $max Optional. Number of feed items to display.
34
- * @type array $activity_args Optional. Arguments passed to {@link bp_has_activities()}
35
- * }
36
- */
37
- class BP_Activity_Feed {
38
-
39
- /**
40
- * Holds our custom class properties.
41
- *
42
- * These variables are stored in a protected array that is magically
43
- * updated using PHP 5.2+ methods.
44
- *
45
- * @see BP_Feed::__construct() This is where $data is added.
46
- *
47
- * @since 1.8.0
48
- * @var array
49
- */
50
- protected $data;
51
-
52
- /**
53
- * Magic method for checking the existence of a certain data variable.
54
- *
55
- * @since 1.8.0
56
- *
57
- * @param string $key Property to check.
58
- * @return bool Whether or not data variable exists.
59
- */
60
- public function __isset( $key ) { return isset( $this->data[$key] ); }
61
-
62
- /**
63
- * Magic method for getting a certain data variable.
64
- *
65
- * @since 1.8.0
66
- *
67
- * @param string $key Property to get.
68
- * @return mixed Data in variable if available or null.
69
- */
70
- public function __get( $key ) { return isset( $this->data[$key] ) ? $this->data[$key] : null; }
71
-
72
- /**
73
- * Magic method for setting a certain data variable.
74
- *
75
- * @since 2.4.0
76
- *
77
- * @param string $key The property to set.
78
- * @param mixed $value The value to set.
79
- */
80
- public function __set( $key, $value ) { $this->data[$key] = $value; }
81
-
82
- /**
83
- * Constructor.
84
- *
85
- * @since 1.8.0
86
- *
87
- * @param array $args Optional.
88
- */
89
- public function __construct( $args = array() ) {
90
-
91
- /**
92
- * Filters if BuddyPress should consider feeds enabled. If disabled, it will return early.
93
- *
94
- * @since 1.8.0
95
- *
96
- * @param bool true Default true aka feeds are enabled.
97
- */
98
- if ( false === (bool) apply_filters( 'bp_activity_enable_feeds', true ) ) {
99
- global $wp_query;
100
-
101
- // Set feed flag to false.
102
- $wp_query->is_feed = false;
103
-
104
- return false;
105
- }
106
-
107
- // Setup data.
108
- $this->data = wp_parse_args( $args, array(
109
- // Internal identifier for the RSS feed - should be alphanumeric only.
110
- 'id' => '',
111
-
112
- // RSS title - should be plain-text.
113
- 'title' => '',
114
-
115
- // Relevant link for the RSS feed.
116
- 'link' => '',
117
-
118
- // RSS description - should be plain-text.
119
- 'description' => '',
120
-
121
- // Time-to-live - number of minutes to cache the data before an aggregator
122
- // requests it again. This is only acknowledged if the RSS client supports it
123
- //
124
- // See: http://www.rssboard.org/rss-profile#element-channel-ttl.
125
- // See: http://www.kbcafe.com/rss/rssfeedstate.html#ttl.
126
- 'ttl' => '30',
127
-
128
- // Syndication module - similar to ttl, but not really supported by RSS
129
- // clients
130
- //
131
- // See: http://web.resource.org/rss/1.0/modules/syndication/#description.
132
- // See: http://www.kbcafe.com/rss/rssfeedstate.html#syndicationmodule.
133
- 'update_period' => 'hourly',
134
- 'update_frequency' => 2,
135
-
136
- // Number of items to display.
137
- 'max' => 50,
138
-
139
- // Activity arguments passed to bp_has_activities().
140
- 'activity_args' => array()
141
- ) );
142
-
143
- /**
144
- * Fires before the feed is setup so plugins can modify.
145
- *
146
- * @since 1.8.0
147
- *
148
- * @param BP_Activity_Feed $this Current instance of activity feed. Passed by reference.
149
- */
150
- do_action_ref_array( 'bp_activity_feed_prefetch', array( &$this ) );
151
-
152
- // Setup class properties.
153
- $this->setup_properties();
154
-
155
- // Check if id is valid.
156
- if ( empty( $this->id ) ) {
157
- _doing_it_wrong( 'BP_Activity_Feed', __( "RSS feed 'id' must be defined", 'buddypress' ), 'BP 1.8' );
158
- return false;
159
- }
160
-
161
- /**
162
- * Fires after the feed is setup so plugins can modify.
163
- *
164
- * @since 1.8.0
165
- *
166
- * @param BP_Activity_Feed $this Current instance of activity feed. Passed by reference.
167
- */
168
- do_action_ref_array( 'bp_activity_feed_postfetch', array( &$this ) );
169
-
170
- // Setup feed hooks.
171
- $this->setup_hooks();
172
-
173
- // Output the feed.
174
- $this->output();
175
-
176
- // Kill the rest of the output.
177
- die();
178
- }
179
-
180
- /** SETUP ****************************************************************/
181
-
182
- /**
183
- * Setup and validate the class properties.
184
- *
185
- * @since 1.8.0
186
- */
187
- protected function setup_properties() {
188
- $this->id = sanitize_title( $this->id );
189
- $this->title = strip_tags( $this->title );
190
- $this->link = esc_url_raw( $this->link );
191
- $this->description = strip_tags( $this->description );
192
- $this->ttl = (int) $this->ttl;
193
- $this->update_period = strip_tags( $this->update_period );
194
- $this->update_frequency = (int) $this->update_frequency;
195
-
196
- $this->activity_args = wp_parse_args( $this->activity_args, array(
197
- 'max' => $this->max,
198
- 'per_page' => $this->max,
199
- 'display_comments' => 'stream'
200
- ) );
201
-
202
- }
203
-
204
- /**
205
- * Setup some hooks that are used in the feed.
206
- *
207
- * Currently, these hooks are used to maintain backwards compatibility with
208
- * the RSS feeds previous to BP 1.8.
209
- *
210
- * @since 1.8.0
211
- */
212
- protected function setup_hooks() {
213
- add_action( 'bp_activity_feed_rss_attributes', array( $this, 'backpat_rss_attributes' ) );
214
- add_action( 'bp_activity_feed_channel_elements', array( $this, 'backpat_channel_elements' ) );
215
- add_action( 'bp_activity_feed_item_elements', array( $this, 'backpat_item_elements' ) );
216
- }
217
-
218
- /** BACKPAT HOOKS ********************************************************/
219
-
220
- /**
221
- * Fire a hook to ensure backward compatibility for RSS attributes.
222
- *
223
- * @since 1.8.0
224
- */
225
- public function backpat_rss_attributes() {
226
-
227
- /**
228
- * Fires inside backpat_rss_attributes method for backwards compatibility related to RSS attributes.
229
- *
230
- * This hook was originally separated out for individual components but has since been abstracted into the BP_Activity_Feed class.
231
- *
232
- * @since 1.0.0
233
- */
234
- do_action( 'bp_activity_' . $this->id . '_feed' );
235
- }
236
-
237
- /**
238
- * Fire a hook to ensure backward compatibility for channel elements.
239
- *
240
- * @since 1.8.0
241
- */
242
- public function backpat_channel_elements() {
243
-
244
- /**
245
- * Fires inside backpat_channel_elements method for backwards compatibility related to RSS channel elements.
246
- *
247
- * This hook was originally separated out for individual components but has since been abstracted into the BP_Activity_Feed class.
248
- *
249
- * @since 1.0.0
250
- */
251
- do_action( 'bp_activity_' . $this->id . '_feed_head' );
252
- }
253
-
254
- /**
255
- * Fire a hook to ensure backward compatibility for item elements.
256
- *
257
- * @since 1.8.0
258
- */
259
- public function backpat_item_elements() {
260
- switch ( $this->id ) {
261
-
262
- // Sitewide and friends feeds use the 'personal' hook.
263
- case 'sitewide' :
264
- case 'friends' :
265
- $id = 'personal';
266
-
267
- break;
268
-
269
- default :
270
- $id = $this->id;
271
-
272
- break;
273
- }
274
-
275
- /**
276
- * Fires inside backpat_item_elements method for backwards compatibility related to RSS item elements.
277
- *
278
- * This hook was originally separated out for individual components but has since been abstracted into the BP_Activity_Feed class.
279
- *
280
- * @since 1.0.0
281
- */
282
- do_action( 'bp_activity_' . $id . '_feed_item' );
283
- }
284
-
285
- /** HELPERS **************************************************************/
286
-
287
- /**
288
- * Output the feed's item content.
289
- *
290
- * @since 1.8.0
291
- */
292
- protected function feed_content() {
293
- bp_activity_content_body();
294
-
295
- switch ( $this->id ) {
296
-
297
- // Also output parent activity item if we're on a specific feed.
298
- case 'favorites' :
299
- case 'friends' :
300
- case 'mentions' :
301
- case 'personal' :
302
-
303
- if ( 'activity_comment' == bp_get_activity_action_name() ) :
304
- ?>
305
- <strong><?php _e( 'In reply to', 'buddypress' ) ?></strong> -
306
- <?php bp_activity_parent_content() ?>
307
- <?php
308
- endif;
309
-
310
- break;
311
- }
312
- }
313
-
314
- /**
315
- * Sets various HTTP headers related to Content-Type and browser caching.
316
- *
317
- * Most of this class method is derived from {@link WP::send_headers()}.
318
- *
319
- * @since 1.9.0
320
- */
321
- protected function http_headers() {
322
- // Set up some additional headers if not on a directory page
323
- // this is done b/c BP uses pseudo-pages.
324
- if ( ! bp_is_directory() ) {
325
- global $wp_query;
326
-
327
- $wp_query->is_404 = false;
328
- status_header( 200 );
329
- }
330
-
331
- // Set content-type.
332
- @header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true );
333
- send_nosniff_header();
334
-
335
- // Cache-related variables.
336
- $last_modified = mysql2date( 'D, d M Y H:i:s O', bp_activity_get_last_updated(), false );
337
- $modified_timestamp = strtotime( $last_modified );
338
- $etag = md5( $last_modified );
339
-
340
- // Set cache-related headers.
341
- @header( 'Last-Modified: ' . $last_modified );
342
- @header( 'Pragma: no-cache' );
343
- @header( 'ETag: ' . '"' . $etag . '"' );
344
-
345
- // First commit of BuddyPress! (Easter egg).
346
- @header( 'Expires: Tue, 25 Mar 2008 17:13:55 GMT');
347
-
348
- // Get ETag from supported user agents.
349
- if ( isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) ) {
350
- $client_etag = wp_unslash( $_SERVER['HTTP_IF_NONE_MATCH'] );
351
-
352
- // Remove quotes from ETag.
353
- $client_etag = trim( $client_etag, '"' );
354
-
355
- // Strip suffixes from ETag if they exist (eg. "-gzip").
356
- $etag_suffix_pos = strpos( $client_etag, '-' );
357
- if ( ! empty( $etag_suffix_pos ) ) {
358
- $client_etag = substr( $client_etag, 0, $etag_suffix_pos );
359
- }
360
-
361
- // No ETag found.
362
- } else {
363
- $client_etag = false;
364
- }
365
-
366
- // Get client last modified timestamp from supported user agents.
367
- $client_last_modified = empty( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ? '' : trim( $_SERVER['HTTP_IF_MODIFIED_SINCE'] );
368
- $client_modified_timestamp = $client_last_modified ? strtotime( $client_last_modified ) : 0;
369
-
370
- // Set 304 status if feed hasn't been updated since last fetch.
371
- if ( ( $client_last_modified && $client_etag ) ?
372
- ( ( $client_modified_timestamp >= $modified_timestamp ) && ( $client_etag == $etag ) ) :
373
- ( ( $client_modified_timestamp >= $modified_timestamp ) || ( $client_etag == $etag ) ) ) {
374
- $status = 304;
375
- } else {
376
- $status = false;
377
- }
378
-
379
- // If feed hasn't changed as reported by the user agent, set 304 status header.
380
- if ( ! empty( $status ) ) {
381
- status_header( $status );
382
-
383
- // Cached response, so stop now!
384
- if ( $status == 304 ) {
385
- exit();
386
- }
387
- }
388
- }
389
-
390
- /** OUTPUT ***************************************************************/
391
-
392
- /**
393
- * Output the RSS feed.
394
- *
395
- * @since 1.8.0
396
- */
397
- protected function output() {
398
- $this->http_headers();
399
- echo '<?xml version="1.0" encoding="' . get_option( 'blog_charset' ) . '"?'.'>';
400
- ?>
401
-
402
- <rss version="2.0"
403
- xmlns:content="http://purl.org/rss/1.0/modules/content/"
404
- xmlns:atom="http://www.w3.org/2005/Atom"
405
- xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
406
- xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
407
- <?php
408
-
409
- /**
410
- * Fires at the end of the opening RSS tag for feed output so plugins can add extra attributes.
411
- *
412
- * @since 1.8.0
413
- */
414
- do_action( 'bp_activity_feed_rss_attributes' ); ?>
415
- >
416
-
417
- <channel>
418
- <title><?php echo $this->title; ?></title>
419
- <link><?php echo $this->link; ?></link>
420
- <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
421
- <description><?php echo $this->description ?></description>
422
- <lastBuildDate><?php echo mysql2date( 'D, d M Y H:i:s O', bp_activity_get_last_updated(), false ); ?></lastBuildDate>
423
- <generator>https://buddypress.org/?v=<?php bp_version(); ?></generator>
424
- <language><?php bloginfo_rss( 'language' ); ?></language>
425
- <ttl><?php echo $this->ttl; ?></ttl>
426
- <sy:updatePeriod><?php echo $this->update_period; ?></sy:updatePeriod>
427
- <sy:updateFrequency><?php echo $this->update_frequency; ?></sy:updateFrequency>
428
- <?php
429
-
430
- /**
431
- * Fires at the end of channel elements list in RSS feed so plugins can add extra channel elements.
432
- *
433
- * @since 1.8.0
434
- */
435
- do_action( 'bp_activity_feed_channel_elements' ); ?>
436
-
437
- <?php if ( bp_has_activities( $this->activity_args ) ) : ?>
438
- <?php while ( bp_activities() ) : bp_the_activity(); ?>
439
- <item>
440
- <guid isPermaLink="false"><?php bp_activity_feed_item_guid(); ?></guid>
441
- <title><?php echo stripslashes( bp_get_activity_feed_item_title() ); ?></title>
442
- <link><?php bp_activity_thread_permalink() ?></link>
443
- <pubDate><?php echo mysql2date( 'D, d M Y H:i:s O', bp_get_activity_feed_item_date(), false ); ?></pubDate>
444
-
445
- <?php if ( bp_get_activity_feed_item_description() ) : ?>
446
- <content:encoded><![CDATA[<?php $this->feed_content(); ?>]]></content:encoded>
447
- <?php endif; ?>
448
-
449
- <?php if ( bp_activity_can_comment() ) : ?>
450
- <slash:comments><?php bp_activity_comment_count(); ?></slash:comments>
451
- <?php endif; ?>
452
-
453
- <?php
454
-
455
- /**
456
- * Fires at the end of the individual RSS Item list in RSS feed so plugins can add extra item elements.
457
- *
458
- * @since 1.8.0
459
- */
460
- do_action( 'bp_activity_feed_item_elements' ); ?>
461
- </item>
462
- <?php endwhile; ?>
463
-
464
- <?php endif; ?>
465
- </channel>
466
- </rss><?php
467
- }
468
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/classes/class-bp-activity-list-table.php DELETED
@@ -1,857 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Activity component admin list table.
4
- *
5
- * Props to WordPress core for the Comments admin screen, and its contextual
6
- * help text, on which this implementation is heavily based.
7
- *
8
- * @package BuddyPress
9
- * @subpackage ActivityAdmin
10
- * @since 1.6.0
11
- */
12
-
13
- // Exit if accessed directly.
14
- defined( 'ABSPATH' ) || exit;
15
-
16
- /**
17
- * List table class for the Activity component admin page.
18
- *
19
- * @since 1.6.0
20
- */
21
- class BP_Activity_List_Table extends WP_List_Table {
22
-
23
- /**
24
- * What type of view is being displayed?
25
- *
26
- * E.g. "all", "pending", "approved", "spam"...
27
- *
28
- * @since 1.6.0
29
- * @var string $view
30
- */
31
- public $view = 'all';
32
-
33
- /**
34
- * How many activity items have been marked as spam.
35
- *
36
- * @since 1.6.0
37
- * @var int $spam_count
38
- */
39
- public $spam_count = 0;
40
-
41
- /**
42
- * Store activity-to-user-ID mappings for use in the In Response To column.
43
- *
44
- * @since 1.6.0
45
- * @var array $activity_user_id
46
- */
47
- protected $activity_user_id = array();
48
-
49
- /**
50
- * If users can comment on blog & forum activity items.
51
- *
52
- * @link https://buddypress.trac.wordpress.org/ticket/6277
53
- *
54
- * @since 2.2.2
55
- * @var bool $disable_blogforum_comments
56
- */
57
- public $disable_blogforum_comments = false;
58
-
59
- /**
60
- * Constructor.
61
- *
62
- * @since 1.6.0
63
- */
64
- public function __construct() {
65
-
66
- // See if activity commenting is enabled for blog / forum activity items.
67
- $this->disable_blogforum_comments = bp_disable_blogforum_comments();
68
-
69
- // Define singular and plural labels, as well as whether we support AJAX.
70
- parent::__construct( array(
71
- 'ajax' => false,
72
- 'plural' => 'activities',
73
- 'singular' => 'activity',
74
- 'screen' => get_current_screen(),
75
- ) );
76
- }
77
-
78
- /**
79
- * Handle filtering of data, sorting, pagination, and any other data manipulation prior to rendering.
80
- *
81
- * @since 1.6.0
82
- */
83
- function prepare_items() {
84
-
85
- // Option defaults.
86
- $filter = array();
87
- $filter_query = false;
88
- $include_id = false;
89
- $search_terms = false;
90
- $sort = 'DESC';
91
- $spam = 'ham_only';
92
-
93
- // Set current page.
94
- $page = $this->get_pagenum();
95
-
96
- // Set per page from the screen options.
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
- *
120
- * @since 2.5.0
121
- *
122
- * @param array $filter
123
- */
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',
146
- 'show_hidden' => true,
147
- 'spam' => 'spam_only',
148
- 'count_total' => 'count_query',
149
- ) );
150
- $this->spam_count = $spams['total'];
151
- unset( $spams );
152
-
153
- // Get the activities from the database.
154
- $activities = bp_activity_get( array(
155
- 'display_comments' => 'stream',
156
- 'filter' => $filter,
157
- 'in' => $include_id,
158
- 'page' => $page,
159
- 'per_page' => $per_page,
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
- ) );
167
-
168
- // If we're viewing a specific activity, flatten all activities into a single array.
169
- if ( $include_id ) {
170
- $activities['activities'] = BP_Activity_List_Table::flatten_activity_array( $activities['activities'] );
171
- $activities['total'] = count( $activities['activities'] );
172
-
173
- // Sort the array by the activity object's date_recorded value.
174
- usort( $activities['activities'], function( $a, $b ) { return $a->date_recorded > $b->date_recorded; } );
175
- }
176
-
177
- // The bp_activity_get function returns an array of objects; cast these to arrays for WP_List_Table.
178
- $new_activities = array();
179
- foreach ( $activities['activities'] as $activity_item ) {
180
- $new_activities[] = (array) $activity_item;
181
-
182
- // Build an array of activity-to-user ID mappings for better efficiency in the In Response To column.
183
- $this->activity_user_id[$activity_item->id] = $activity_item->user_id;
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(
191
- 'per_page' => $per_page,
192
- 'total_items' => $activities['total'],
193
- 'total_pages' => ceil( $activities['total'] / $per_page )
194
- ) );
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
- /**
201
- * Get an array of all the columns on the page.
202
- *
203
- * @since 1.6.0
204
- *
205
- * @return array Column headers.
206
- */
207
- function get_column_info() {
208
- $this->_column_headers = array(
209
- $this->get_columns(),
210
- array(),
211
- $this->get_sortable_columns(),
212
- $this->get_default_primary_column_name(),
213
- );
214
-
215
- return $this->_column_headers;
216
- }
217
-
218
- /**
219
- * Get name of default primary column
220
- *
221
- * @since 2.3.3
222
- *
223
- * @return string
224
- */
225
- protected function get_default_primary_column_name() {
226
- return 'author';
227
- }
228
-
229
- /**
230
- * Display a message on screen when no items are found (e.g. no search matches).
231
- *
232
- * @since 1.6.0
233
- */
234
- function no_items() {
235
- _e( 'No activities found.', 'buddypress' );
236
- }
237
-
238
- /**
239
- * Output the Activity data table.
240
- *
241
- * @since 1.6.0
242
- */
243
- function display() {
244
- $this->display_tablenav( 'top' ); ?>
245
-
246
- <h2 class="screen-reader-text"><?php
247
- /* translators: accessibility text */
248
- _e( 'Activities list', 'buddypress' );
249
- ?></h2>
250
-
251
- <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>" cellspacing="0">
252
- <thead>
253
- <tr>
254
- <?php $this->print_column_headers(); ?>
255
- </tr>
256
- </thead>
257
-
258
- <tbody id="the-comment-list">
259
- <?php $this->display_rows_or_placeholder(); ?>
260
- </tbody>
261
-
262
- <tfoot>
263
- <tr>
264
- <?php $this->print_column_headers( false ); ?>
265
- </tr>
266
- </tfoot>
267
- </table>
268
- <?php
269
-
270
- $this->display_tablenav( 'bottom' );
271
- }
272
-
273
- /**
274
- * Generate content for a single row of the table.
275
- *
276
- * @since 1.6.0
277
- *
278
- * @param object $item The current item.
279
- */
280
- function single_row( $item ) {
281
- static $even = false;
282
-
283
- if ( $even ) {
284
- $row_class = ' class="even"';
285
- } else {
286
- $row_class = ' class="alternate odd"';
287
- }
288
-
289
- if ( 'activity_comment' === $item['type'] ) {
290
- $root_id = $item['item_id'];
291
- } else {
292
- $root_id = $item['id'];
293
- }
294
-
295
- echo '<tr' . $row_class . ' id="activity-' . esc_attr( $item['id'] ) . '" data-parent_id="' . esc_attr( $item['id'] ) . '" data-root_id="' . esc_attr( $root_id ) . '">';
296
- echo $this->single_row_columns( $item );
297
- echo '</tr>';
298
-
299
- $even = ! $even;
300
- }
301
-
302
- /**
303
- * Get the list of views available on this table (e.g. "all", "spam").
304
- *
305
- * @since 1.6.0
306
- */
307
- function get_views() {
308
- $url_base = add_query_arg( array( 'page' => 'bp-activity' ), bp_get_admin_url( 'admin.php' ) ); ?>
309
-
310
- <h2 class="screen-reader-text"><?php
311
- /* translators: accessibility text */
312
- _e( 'Filter activities list', 'buddypress' );
313
- ?></h2>
314
-
315
- <ul class="subsubsub">
316
- <li class="all"><a href="<?php echo esc_url( $url_base ); ?>" class="<?php if ( 'spam' != $this->view ) echo 'current'; ?>"><?php _e( 'All', 'buddypress' ); ?></a> |</li>
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
-
321
- /**
322
- * Fires inside listing of views so plugins can add their own.
323
- *
324
- * @since 1.6.0
325
- *
326
- * @param string $url_base Current URL base for view.
327
- * @param string $view Current view being displayed.
328
- */
329
- do_action( 'bp_activity_list_table_get_views', $url_base, $this->view ); ?>
330
- </ul>
331
- <?php
332
- }
333
-
334
- /**
335
- * Get bulk actions.
336
- *
337
- * @since 1.6.0
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.
349
- *
350
- * @since 1.6.0
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
- /**
358
- * Get the table column titles.
359
- *
360
- * @since 1.6.0
361
- *
362
- * @see WP_List_Table::single_row_columns()
363
- *
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
- *
370
- * @since 2.4.0
371
- *
372
- * @param array $value Array of slugs and titles for the columns.
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' ),
380
- ) );
381
- }
382
-
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
- /**
403
- * Markup for the "filter" part of the form (i.e. which activity type to display).
404
- *
405
- * @since 1.6.0
406
- *
407
- * @param string $which 'top' or 'bottom'.
408
- */
409
- function extra_tablenav( $which ) {
410
-
411
- // Bail on bottom table nav.
412
- if ( 'bottom' === $which ) {
413
- return;
414
- }
415
-
416
- // Is any filter currently selected?
417
- $selected = ( ! empty( $_REQUEST['activity_type'] ) ) ? $_REQUEST['activity_type'] : '';
418
-
419
- // Get the actions.
420
- $activity_actions = bp_activity_get_actions(); ?>
421
-
422
- <div class="alignleft actions">
423
- <label for="activity-type" class="screen-reader-text"><?php
424
- /* translators: accessibility text */
425
- _e( 'Filter by activity type', 'buddypress' );
426
- ?></label>
427
- <select name="activity_type" id="activity-type">
428
- <option value="" <?php selected( ! $selected ); ?>><?php _e( 'View all actions', 'buddypress' ); ?></option>
429
-
430
- <?php foreach ( $activity_actions as $component => $actions ) : ?>
431
- <?php
432
- // Older avatar activity items use 'profile' for component. See r4273.
433
- if ( $component === 'profile' ) {
434
- $component = 'xprofile';
435
- }
436
-
437
- if ( bp_is_active( $component ) ) {
438
- if ( $component === 'xprofile' ) {
439
- $component_name = buddypress()->profile->name;
440
- } else {
441
- $component_name = buddypress()->$component->name;
442
- }
443
-
444
- } else {
445
- // Prevent warnings by other plugins if a component is disabled but the activity type has been registered.
446
- $component_name = ucfirst( $component );
447
- }
448
- ?>
449
-
450
- <optgroup label="<?php echo esc_html( $component_name ); ?>">
451
-
452
- <?php foreach ( $actions as $action_key => $action_values ) : ?>
453
-
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
-
461
- <?php endif; ?>
462
-
463
- <?php endforeach; ?>
464
-
465
- </optgroup>
466
-
467
- <?php endforeach; ?>
468
-
469
- </select>
470
-
471
- <?php submit_button( __( 'Filter', 'buddypress' ), 'secondary', false, false, array( 'id' => 'post-query-submit' ) ); ?>
472
- </div>
473
-
474
- <?php
475
- }
476
-
477
- /**
478
- * Override WP_List_Table::row_actions().
479
- *
480
- * Basically a duplicate of the row_actions() method, but removes the
481
- * unnecessary <button> addition.
482
- *
483
- * @since 2.3.3
484
- * @since 2.3.4 Visibility set to public for compatibility with WP < 4.0.0.
485
- *
486
- * @param array $actions The list of actions.
487
- * @param bool $always_visible Whether the actions should be always visible.
488
- * @return string
489
- */
490
- public function row_actions( $actions, $always_visible = false ) {
491
- $action_count = count( $actions );
492
- $i = 0;
493
-
494
- if ( !$action_count )
495
- return '';
496
-
497
- $out = '<div class="' . ( $always_visible ? 'row-actions visible' : 'row-actions' ) . '">';
498
- foreach ( $actions as $action => $link ) {
499
- ++$i;
500
- ( $i == $action_count ) ? $sep = '' : $sep = ' | ';
501
- $out .= "<span class='$action'>$link$sep</span>";
502
- }
503
- $out .= '</div>';
504
-
505
- return $out;
506
- }
507
-
508
- /**
509
- * Checkbox column markup.
510
- *
511
- * @since 1.6.0
512
- *
513
- * @see WP_List_Table::single_row_columns()
514
- *
515
- * @param array $item A singular item (one full row).
516
- */
517
- function column_cb( $item ) {
518
- /* translators: accessibility text */
519
- printf( '<label class="screen-reader-text" for="aid-%1$d">' . __( 'Select activity item %1$d', 'buddypress' ) . '</label><input type="checkbox" name="aid[]" value="%1$d" id="aid-%1$d" />', $item['id'] );
520
- }
521
-
522
- /**
523
- * Author column markup.
524
- *
525
- * @since 1.6.0
526
- *
527
- * @see WP_List_Table::single_row_columns()
528
- *
529
- * @param array $item A singular item (one full row).
530
- */
531
- function column_author( $item ) {
532
- echo '<strong>' . get_avatar( $item['user_id'], '32' ) . ' ' . bp_core_get_userlink( $item['user_id'] ) . '</strong>';
533
- }
534
-
535
- /**
536
- * Action column markup.
537
- *
538
- * @since 2.0.0
539
- *
540
- * @see WP_List_Table::single_row_columns()
541
- *
542
- * @param array $item A singular item (one full row).
543
- */
544
- function column_action( $item ) {
545
- $actions = bp_activity_admin_get_activity_actions();
546
-
547
- if ( isset( $actions[ $item['type'] ] ) ) {
548
- echo $actions[ $item['type'] ];
549
- } else {
550
- printf( __( 'Unregistered action - %s', 'buddypress' ), $item['type'] );
551
- }
552
- }
553
-
554
- /**
555
- * Content column, and "quick admin" rollover actions.
556
- *
557
- * Called "comment" in the CSS so we can re-use some WP core CSS.
558
- *
559
- * @since 1.6.0
560
- *
561
- * @see WP_List_Table::single_row_columns()
562
- *
563
- * @param array $item A singular item (one full row).
564
- */
565
- function column_comment( $item ) {
566
- // Determine what type of item (row) we're dealing with.
567
- if ( $item['is_spam'] )
568
- $item_status = 'spam';
569
- else
570
- $item_status = 'all';
571
-
572
- // Preorder items: Reply | Edit | Spam | Delete Permanently.
573
- $actions = array(
574
- 'reply' => '',
575
- 'edit' => '',
576
- 'spam' => '', 'unspam' => '',
577
- 'delete' => '',
578
- );
579
-
580
- // Build actions URLs.
581
- $base_url = bp_get_admin_url( 'admin.php?page=bp-activity&amp;aid=' . $item['id'] );
582
- $spam_nonce = esc_html( '_wpnonce=' . wp_create_nonce( 'spam-activity_' . $item['id'] ) );
583
-
584
- $delete_url = $base_url . "&amp;action=delete&amp;$spam_nonce";
585
- $edit_url = $base_url . '&amp;action=edit';
586
- $ham_url = $base_url . "&amp;action=ham&amp;$spam_nonce";
587
- $spam_url = $base_url . "&amp;action=spam&amp;$spam_nonce";
588
-
589
- // Rollover actions.
590
- // Reply - JavaScript only; implemented by AJAX.
591
- if ( 'spam' != $item_status ) {
592
- if ( $this->can_comment( $item ) ) {
593
- $actions['reply'] = sprintf( '<a href="#" class="reply hide-if-no-js">%s</a>', __( 'Reply', 'buddypress' ) );
594
- } else {
595
- $actions['reply'] = sprintf( '<span class="form-input-tip">%s</span>', __( 'Replies disabled', 'buddypress' ) );
596
- }
597
-
598
- // Edit.
599
- $actions['edit'] = sprintf( '<a href="%s">%s</a>', $edit_url, __( 'Edit', 'buddypress' ) );
600
- }
601
-
602
- // Spam/unspam.
603
- if ( 'spam' == $item_status )
604
- $actions['unspam'] = sprintf( '<a href="%s">%s</a>', $ham_url, __( 'Not Spam', 'buddypress' ) );
605
- else
606
- $actions['spam'] = sprintf( '<a href="%s">%s</a>', $spam_url, __( 'Spam', 'buddypress' ) );
607
-
608
- // Delete.
609
- $actions['delete'] = sprintf( '<a href="%s" onclick="%s">%s</a>', $delete_url, "javascript:return confirm('" . esc_js( __( 'Are you sure?', 'buddypress' ) ) . "'); ", __( 'Delete Permanently', 'buddypress' ) );
610
-
611
- // Start timestamp.
612
- echo '<div class="submitted-on">';
613
-
614
- /**
615
- * Filters available actions for plugins to alter.
616
- *
617
- * @since 1.6.0
618
- *
619
- * @param array $actions Array of available actions user could use.
620
- * @param array $item Current item being added to page.
621
- */
622
- $actions = apply_filters( 'bp_activity_admin_comment_row_actions', array_filter( $actions ), $item );
623
-
624
- printf(
625
- /* translators: %s: activity date and time */
626
- __( 'Submitted on %s', 'buddypress' ),
627
- sprintf(
628
- '<a href="%1$s">%2$s</a>',
629
- bp_activity_get_permalink( $item['id'] ),
630
- sprintf(
631
- /* translators: 1: activity date, 2: activity time */
632
- __( '%1$s at %2$s', 'buddypress' ),
633
- date_i18n( bp_get_option( 'date_format' ), strtotime( $item['date_recorded'] ) ),
634
- get_date_from_gmt( $item['date_recorded'], bp_get_option( 'time_format' ) )
635
- )
636
- )
637
- );
638
-
639
- // End timestamp.
640
- echo '</div>';
641
-
642
- // Get activity content - if not set, use the action.
643
- if ( ! empty( $item['content'] ) ) {
644
- $activity = new BP_Activity_Activity( $item['id'] );
645
-
646
- /** This filter is documented in bp-activity/bp-activity-template.php */
647
- $content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $item['content'], &$activity ) );
648
- } else {
649
- /**
650
- * Filters current activity item action.
651
- *
652
- * @since 1.2.0
653
- *
654
- * @var array $item Array index holding current activity item action.
655
- */
656
- $content = apply_filters_ref_array( 'bp_get_activity_action', array( $item['action'] ) );
657
- }
658
-
659
- /**
660
- * Filter here to add extra output to the activity content into the Administration.
661
- *
662
- * @since 2.4.0
663
- *
664
- * @param string $content The activity content.
665
- * @param array $item The activity object converted into an array.
666
- */
667
- echo apply_filters( 'bp_activity_admin_comment_content', $content, $item ) . ' ' . $this->row_actions( $actions );
668
- }
669
-
670
- /**
671
- * "In response to" column markup.
672
- *
673
- * @since 1.6.0
674
- *
675
- * @see WP_List_Table::single_row_columns()
676
- *
677
- * @param array $item A singular item (one full row).
678
- */
679
- function column_response( $item ) {
680
-
681
- // Is $item is a root activity?
682
- ?>
683
-
684
- <div class="response-links">
685
-
686
- <?php
687
- // Activity permalink.
688
- $activity_permalink = '';
689
- if ( ! $item['is_spam'] ) {
690
- $activity_permalink = '<a href="' . bp_activity_get_permalink( $item['id'], (object) $item ) . '" class="comments-view-item-link">' . __( 'View Activity', 'buddypress' ) . '</a>';
691
- }
692
-
693
- /**
694
- * Filters default list of default root activity types.
695
- *
696
- * @since 1.6.0
697
- *
698
- * @param array $value Array of default activity types.
699
- * @param array $item Current item being displayed.
700
- */
701
- if ( empty( $item['item_id'] ) || ! in_array( $item['type'], apply_filters( 'bp_activity_admin_root_activity_types', array( 'activity_comment' ), $item ) ) ) {
702
- echo $activity_permalink;
703
-
704
- $comment_count = !empty( $item['children'] ) ? bp_activity_recurse_comment_count( (object) $item ) : 0;
705
- $root_activity_url = bp_get_admin_url( 'admin.php?page=bp-activity&amp;aid=' . $item['id'] );
706
-
707
- // If the activity has comments, display a link to the activity's permalink, with its comment count in a speech bubble.
708
- if ( $comment_count ) {
709
- printf( '<a href="%1$s" class="post-com-count post-com-count-approved"><span class="comment-count comment-count-approved">%2$s</span></a>', esc_url( $root_activity_url ), number_format_i18n( $comment_count ) );
710
- }
711
-
712
- // For non-root activities, display a link to the replied-to activity's author's profile.
713
- } else {
714
- echo '<strong>' . get_avatar( $this->get_activity_user_id( $item['item_id'] ), '32' ) . ' ' . bp_core_get_userlink( $this->get_activity_user_id( $item['item_id'] ) ) . '</strong><br />';
715
- echo $activity_permalink;
716
- }
717
- ?>
718
-
719
- </div>
720
-
721
- <?php
722
- }
723
-
724
- /**
725
- * Allow plugins to add their custom column.
726
- *
727
- * @since 2.4.0
728
- *
729
- * @param array $item Information about the current row.
730
- * @param string $column_name The column name.
731
- * @return string
732
- */
733
- public function column_default( $item = array(), $column_name = '' ) {
734
-
735
- /**
736
- * Filters a string to allow plugins to add custom column content.
737
- *
738
- * @since 2.4.0
739
- *
740
- * @param string $value Empty string.
741
- * @param string $column_name Name of the column being rendered.
742
- * @param array $item The current activity item in the loop.
743
- */
744
- return apply_filters( 'bp_activity_admin_get_custom_column', '', $column_name, $item );
745
- }
746
-
747
- /**
748
- * Get the user id associated with a given activity item.
749
- *
750
- * Wraps bp_activity_get_specific(), with some additional logic for
751
- * avoiding duplicate queries.
752
- *
753
- * @since 1.6.0
754
- *
755
- * @param int $activity_id Activity ID to retrieve User ID for.
756
- * @return int User ID of the activity item in question.
757
- */
758
- protected function get_activity_user_id( $activity_id ) {
759
- // If there is an existing activity/user ID mapping, just return the user ID.
760
- if ( ! empty( $this->activity_user_id[$activity_id] ) ) {
761
- return $this->activity_user_id[$activity_id];
762
-
763
- /*
764
- * We don't have a mapping. This means the $activity_id is not on the current
765
- * page of results, so fetch its details from the database.
766
- */
767
- } else {
768
- $activity = bp_activity_get_specific( array( 'activity_ids' => $activity_id, 'show_hidden' => true, 'spam' => 'all', ) );
769
-
770
- /*
771
- * If, somehow, the referenced activity has been deleted, leaving its associated
772
- * activities as orphans, use the logged in user's ID to avoid errors.
773
- */
774
- if ( empty( $activity['activities'] ) )
775
- return bp_loggedin_user_id();
776
-
777
- // Store the new activity/user ID mapping for any later re-use.
778
- $this->activity_user_id[ $activity['activities'][0]->id ] = $activity['activities'][0]->user_id;
779
-
780
- // Return the user ID.
781
- return $activity['activities'][0]->user_id;
782
- }
783
- }
784
-
785
- /**
786
- * Checks if an activity item can be replied to.
787
- *
788
- * This method merges functionality from {@link bp_activity_can_comment()} and
789
- * {@link bp_blogs_disable_activity_commenting()}. This is done because the activity
790
- * list table doesn't use a BuddyPress activity loop, which prevents those
791
- * functions from working as intended.
792
- *
793
- * @since 2.0.0
794
- * @since 2.5.0 Include Post type activities types
795
- *
796
- * @param array $item An array version of the BP_Activity_Activity object.
797
- * @return bool $can_comment
798
- */
799
- protected function can_comment( $item ) {
800
- $can_comment = bp_activity_type_supports( $item['type'], 'comment-reply' );
801
-
802
- if ( ! $this->disable_blogforum_comments && bp_is_active( 'blogs' ) ) {
803
- $parent_activity = false;
804
-
805
- if ( bp_activity_type_supports( $item['type'], 'post-type-comment-tracking' ) ) {
806
- $parent_activity = (object) $item;
807
- } elseif ( 'activity_comment' === $item['type'] ) {
808
- $parent_activity = new BP_Activity_Activity( $item['item_id'] );
809
- $can_comment = bp_activity_can_comment_reply( (object) $item );
810
- }
811
-
812
- if ( isset( $parent_activity->type ) && bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' ) ) {
813
- // Fetch blog post comment depth and if the blog post's comments are open.
814
- bp_blogs_setup_activity_loop_globals( $parent_activity );
815
-
816
- $can_comment = bp_blogs_can_comment_reply( true, $item );
817
- }
818
- }
819
-
820
- /**
821
- * Filters if an activity item can be commented on or not.
822
- *
823
- * @since 2.0.0
824
- * @since 2.5.0 Add a second parameter to include the activity item into the filter.
825
- *
826
- * @param bool $can_comment Whether an activity item can be commented on or not.
827
- * @param array $item An array version of the BP_Activity_Activity object.
828
- */
829
- return apply_filters( 'bp_activity_list_table_can_comment', $can_comment, $item );
830
- }
831
-
832
- /**
833
- * Flatten the activity array.
834
- *
835
- * In some cases, BuddyPress gives us a structured tree of activity
836
- * items plus their comments. This method converts it to a flat array.
837
- *
838
- * @since 1.6.0
839
- *
840
- * @param array $tree Source array.
841
- * @return array Flattened array.
842
- */
843
- public static function flatten_activity_array( $tree ){
844
- foreach ( (array) $tree as $node ) {
845
- if ( isset( $node->children ) ) {
846
-
847
- foreach ( BP_Activity_List_Table::flatten_activity_array( $node->children ) as $child ) {
848
- $tree[] = $child;
849
- }
850
-
851
- unset( $node->children );
852
- }
853
- }
854
-
855
- return $tree;
856
- }
857
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/classes/class-bp-activity-oembed-extension.php DELETED
@@ -1,329 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Activity Classes.
4
- *
5
- * @package BuddyPress
6
- * @subpackage Embeds
7
- */
8
-
9
- // Exit if accessed directly.
10
- defined( 'ABSPATH' ) || exit;
11
-
12
- /**
13
- * oEmbed handler to respond and render single activity items.
14
- *
15
- * @since 2.6.0
16
- */
17
- class BP_Activity_oEmbed_Extension extends BP_Core_oEmbed_Extension {
18
- /**
19
- * Custom oEmbed slug endpoint.
20
- *
21
- * @since 2.6.0
22
- *
23
- * @var string
24
- */
25
- public $slug_endpoint = 'activity';
26
-
27
- /**
28
- * Custom hooks.
29
- *
30
- * @since 2.6.0
31
- */
32
- protected function custom_hooks() {
33
- add_action( 'oembed_dataparse', array( $this, 'use_custom_iframe_sandbox_attribute' ), 20, 3 );
34
- add_action( 'embed_content_meta', array( $this, 'embed_comments_button' ), 5 );
35
- add_action( 'get_template_part_assets/embeds/header', array( $this, 'on_activity_header' ), 10, 2 );
36
-
37
- add_filter( 'bp_activity_embed_html', array( $this, 'modify_iframe' ) );
38
- }
39
-
40
- /**
41
- * Add custom endpoint arguments.
42
- *
43
- * Currently, includes 'hide_media'.
44
- *
45
- * @since 2.6.0
46
- *
47
- * @return array
48
- */
49
- protected function set_route_args() {
50
- return array(
51
- 'hide_media' => array(
52
- 'default' => false,
53
- 'sanitize_callback' => 'wp_validate_boolean'
54
- )
55
- );
56
- }
57
-
58
- /**
59
- * Output our custom embed template part.
60
- *
61
- * @since 2.6.0
62
- */
63
- protected function content() {
64
- bp_get_asset_template_part( 'embeds/activity' );
65
- }
66
-
67
- /**
68
- * Check if we're on our single activity page.
69
- *
70
- * @since 2.6.0
71
- *
72
- * @return bool
73
- */
74
- protected function is_page() {
75
- return bp_is_single_activity();
76
- }
77
-
78
- /**
79
- * Validates the URL to determine if the activity item is valid.
80
- *
81
- * @since 2.6.0
82
- *
83
- * @param string $url The URL to check.
84
- * @return int|bool Activity ID on success; boolean false on failure.
85
- */
86
- protected function validate_url_to_item_id( $url ) {
87
- if ( bp_core_enable_root_profiles() ) {
88
- $domain = bp_get_root_domain();
89
- } else {
90
- $domain = bp_get_members_directory_permalink();
91
- }
92
-
93
- // Check the URL to see if this is a single activity URL.
94
- if ( 0 !== strpos( $url, $domain ) ) {
95
- return false;
96
- }
97
-
98
- // Check for activity slug.
99
- if ( false === strpos( $url, '/' . bp_get_activity_slug() . '/' ) ) {
100
- return false;
101
- }
102
-
103
- // Do more checks.
104
- $url = trim( untrailingslashit( $url ) );
105
-
106
- // Grab the activity ID.
107
- $activity_id = (int) substr(
108
- $url,
109
- strrpos( $url, '/' ) + 1
110
- );
111
-
112
- if ( ! empty( $activity_id ) ) {
113
- // Check if activity item still exists.
114
- $activity = new BP_Activity_Activity( $activity_id );
115
-
116
- // Okay, we're good to go!
117
- if ( ! empty( $activity->component ) && 0 === (int) $activity->is_spam ) {
118
- return $activity_id;
119
- }
120
- }
121
-
122
- return false;
123
- }
124
-
125
- /**
126
- * Sets the oEmbed response data for our activity item.
127
- *
128
- * @since 2.6.0
129
- *
130
- * @param int $item_id The activity ID.
131
- * @return array
132
- */
133
- protected function set_oembed_response_data( $item_id ) {
134
- $activity = new BP_Activity_Activity( $item_id );
135
-
136
- return array(
137
- 'content' => $activity->content,
138
- 'title' => __( 'Activity', 'buddypress' ),
139
- 'author_name' => bp_core_get_user_displayname( $activity->user_id ),
140
- 'author_url' => bp_core_get_user_domain( $activity->user_id ),
141
-
142
- // Custom identifier.
143
- 'x_buddypress' => 'activity'
144
- );
145
- }
146
-
147
- /**
148
- * Sets a custom <blockquote> for our oEmbed fallback HTML.
149
- *
150
- * @since 2.6.0
151
- *
152
- * @param int $item_id The activity ID.
153
- * @return string
154
- */
155
- protected function set_fallback_html( $item_id ) {
156
- $activity = new BP_Activity_Activity( $item_id );
157
- $mentionname = bp_activity_do_mentions() ? ' (@' . bp_activity_get_user_mentionname( $activity->user_id ) . ')' : '';
158
- $date = date_i18n( get_option( 'date_format' ), strtotime( $activity->date_recorded ) );
159
-
160
- // Make sure we can use some activity functions that depend on the loop.
161
- $GLOBALS['activities_template'] = new stdClass;
162
- $GLOBALS['activities_template']->activity = $activity;
163
-
164
- // 'wp-embedded-content' CSS class is necessary due to how the embed JS works.
165
- $blockquote = sprintf( '<blockquote class="wp-embedded-content bp-activity-item">%1$s%2$s %3$s</blockquote>',
166
- bp_activity_get_embed_excerpt( $activity->content ),
167
- '- ' . bp_core_get_user_displayname( $activity->user_id ) . $mentionname,
168
- '<a href="' . esc_url( bp_activity_get_permalink( $item_id ) ) . '">' . $date . '</a>'
169
- );
170
-
171
- // Clean up.
172
- unset( $GLOBALS['activities_template'] );
173
-
174
- /**
175
- * Filters the fallback HTML used when embedding a BP activity item.
176
- *
177
- * @since 2.6.0
178
- *
179
- * @param string $blockquote Current fallback HTML
180
- * @param BP_Activity_Activity $activity Activity object
181
- */
182
- return apply_filters( 'bp_activity_embed_fallback_html', $blockquote, $activity );
183
- }
184
-
185
- /**
186
- * Sets a custom <iframe> title for our oEmbed item.
187
- *
188
- * @since 2.6.0
189
- *
190
- * @param int $item_id The activity ID
191
- * @return string
192
- */
193
- protected function set_iframe_title( $item_id ) {
194
- return __( 'Embedded Activity Item', 'buddypress' );
195
- }
196
-
197
- /**
198
- * Use our custom <iframe> sandbox attribute in our oEmbed response.
199
- *
200
- * WordPress sets the <iframe> sandbox attribute to 'allow-scripts' regardless
201
- * of whatever the oEmbed response is in {@link wp_filter_oembed_result()}. We
202
- * need to add back our custom sandbox value so links will work.
203
- *
204
- * @since 2.6.0
205
- *
206
- * @see BP_Activity_Component::modify_iframe() where our custom sandbox value is set.
207
- *
208
- * @param string $result The oEmbed HTML result.
209
- * @param object $data A data object result from an oEmbed provider.
210
- * @param string $url The URL of the content to be embedded.
211
- * @return string
212
- */
213
- public function use_custom_iframe_sandbox_attribute( $result, $data, $url ) {
214
- // Make sure we are on a BuddyPress activity oEmbed request.
215
- if ( false === isset( $data->x_buddypress ) || 'activity' !== $data->x_buddypress ) {
216
- return $result;
217
- }
218
-
219
- // Get unfiltered sandbox attribute from our own oEmbed response.
220
- $sandbox_pos = strpos( $data->html, 'sandbox=' ) + 9;
221
- $sandbox = substr( $data->html, $sandbox_pos, strpos( $data->html, '"', $sandbox_pos ) - $sandbox_pos );
222
-
223
- // Replace only if our sandbox attribute contains 'allow-top-navigation'.
224
- if ( false !== strpos( $sandbox, 'allow-top-navigation' ) ) {
225
- $result = str_replace( ' sandbox="allow-scripts"', " sandbox=\"{$sandbox}\"", $result );
226
-
227
- // Also remove 'security' attribute; this is only used for IE < 10.
228
- $result = str_replace( 'security="restricted"', "", $result );
229
- }
230
-
231
- return $result;
232
- }
233
-
234
- /**
235
- * Modify various IFRAME-related items if embeds are allowed.
236
- *
237
- * HTML modified:
238
- * - Add sandbox="allow-top-navigation" attribute. This allows links to work
239
- * within the iframe sandbox attribute.
240
- *
241
- * JS modified:
242
- * - Remove IFRAME height restriction of 1000px. Fixes long embed items being
243
- * truncated.
244
- *
245
- * @since 2.6.0
246
- *
247
- * @param string $retval Current embed HTML.
248
- * @return string
249
- */
250
- public function modify_iframe( $retval ) {
251
- // Add 'allow-top-navigation' to allow links to be clicked.
252
- $retval = str_replace( 'sandbox="', 'sandbox="allow-top-navigation ', $retval );
253
-
254
- // See /wp-includes/js/wp-embed.js.
255
- if ( SCRIPT_DEBUG ) {
256
- // Removes WP's hardcoded IFRAME height restriction.
257
- $retval = str_replace( 'height = 1000;', 'height = height;', $retval );
258
-
259
- // This is for the WP build minified version.
260
- } else {
261
- $retval = str_replace( 'g=1e3', 'g=g', $retval );
262
- }
263
-
264
- return $retval;
265
- }
266
-
267
- /**
268
- * Do stuff when our oEmbed activity header template part is loading.
269
- *
270
- * Currently, removes wpautop() from the bp_activity_action() function.
271
- *
272
- * @since 2.6.0
273
- *
274
- * @param string $slug Template part slug requested.
275
- * @param string $name Template part name requested.
276
- */
277
- public function on_activity_header( $slug, $name ) {
278
- if ( false === $this->is_page() || 'activity' !== $name ) {
279
- return;
280
- }
281
-
282
- remove_filter( 'bp_get_activity_action', 'wpautop' );
283
- }
284
-
285
- /**
286
- * Prints the markup for the activity embed comments button.
287
- *
288
- * Basically a copy of {@link print_embed_comments_button()}, but modified for
289
- * the BP activity component.
290
- *
291
- * @since 2.6.0
292
- */
293
- public function embed_comments_button() {
294
- if ( ! did_action( 'bp_embed_content' ) || ! bp_is_single_activity() ) {
295
- return;
296
- }
297
-
298
- // Make sure our custom permalink shows up in the 'WordPress Embed' block.
299
- add_filter( 'the_permalink', array( $this, 'filter_embed_url' ) );
300
-
301
- // Only show comment bubble if we have some activity comments.
302
- $count = bp_activity_get_comment_count();
303
- if ( empty( $count ) ) {
304
- return;
305
- }
306
- ?>
307
-
308
- <div class="wp-embed-comments">
309
- <a href="<?php bp_activity_thread_permalink(); ?>">
310
- <span class="dashicons dashicons-admin-comments"></span>
311
- <?php
312
- printf(
313
- _n(
314
- /* translators: accessibility text */
315
- '%s <span class="screen-reader-text">Comment</span>',
316
- /* translators: accessibility text */
317
- '%s <span class="screen-reader-text">Comments</span>',
318
- $count,
319
- 'buddypress'
320
- ),
321
- number_format_i18n( $count )
322
- );
323
- ?>
324
- </a>
325
- </div>
326
-
327
- <?php
328
- }
329
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/classes/class-bp-activity-query.php DELETED
@@ -1,247 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Activity Classes
4
- *
5
- * @package BuddyPress
6
- * @subpackage ActivityQuery
7
- * @since 2.2.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Class for generating the WHERE SQL clause for advanced activity fetching.
15
- *
16
- * This is notably used in {@link BP_Activity_Activity::get()} with the
17
- * 'filter_query' parameter.
18
- *
19
- * @since 2.2.0
20
- */
21
- class BP_Activity_Query extends BP_Recursive_Query {
22
- /**
23
- * Array of activity queries.
24
- *
25
- * See {@see BP_Activity_Query::__construct()} for information on query arguments.
26
- *
27
- * @since 2.2.0
28
- * @var array
29
- */
30
- public $queries = array();
31
-
32
- /**
33
- * Table alias.
34
- *
35
- * @since 2.2.0
36
- * @var string
37
- */
38
- public $table_alias = '';
39
-
40
- /**
41
- * Supported DB columns.
42
- *
43
- * See the 'wp_bp_activity' DB table schema.
44
- *
45
- * @since 2.2.0
46
- * @var array
47
- */
48
- public $db_columns = array(
49
- 'id', 'user_id', 'component', 'type', 'action', 'content',
50
- 'item_id', 'secondary_item_id', 'hide_sitewide', 'is_spam',
51
- );
52
-
53
- /**
54
- * Constructor.
55
- *
56
- * @since 2.2.0
57
- *
58
- * @param array $query {
59
- * Array of query clauses.
60
- * @type array {
61
- * @type string $column Required. The column to query against. Basically, any DB column in the main
62
- * 'wp_bp_activity' table.
63
- * @type string $value Required. Value to filter by.
64
- * @type string $compare Optional. The comparison operator. Default '='.
65
- * Accepts '=', '!=', '>', '>=', '<', '<=', 'IN', 'NOT IN', 'LIKE',
66
- * 'NOT LIKE', BETWEEN', 'NOT BETWEEN', 'REGEXP', 'NOT REGEXP', 'RLIKE'.
67
- * @type string $relation Optional. The boolean relationship between the activity queries.
68
- * Accepts 'OR', 'AND'. Default 'AND'.
69
- * @type array {
70
- * Optional. Another fully-formed activity query. See parameters above.
71
- * }
72
- * }
73
- * }
74
- */
75
- public function __construct( $query = array() ) {
76
- if ( ! is_array( $query ) ) {
77
- return;
78
- }
79
-
80
- $this->queries = $this->sanitize_query( $query );
81
- }
82
-
83
- /**
84
- * Generates WHERE SQL clause to be appended to a main query.
85
- *
86
- * @since 2.2.0
87
- *
88
- * @param string $alias An existing table alias that is compatible with the current query clause.
89
- * Default: 'a'. BP_Activity_Activity::get() uses 'a', so we default to that.
90
- * @return string SQL fragment to append to the main WHERE clause.
91
- */
92
- public function get_sql( $alias = 'a' ) {
93
- if ( ! empty( $alias ) ) {
94
- $this->table_alias = sanitize_title( $alias );
95
- }
96
-
97
- $sql = $this->get_sql_clauses();
98
-
99
- // We only need the 'where' clause.
100
- //
101
- // Also trim trailing "AND" clause from parent BP_Recursive_Query class
102
- // since it's not necessary for our needs.
103
- return preg_replace( '/^\sAND/', '', $sql['where'] );
104
- }
105
-
106
- /**
107
- * Generate WHERE clauses for a first-order clause.
108
- *
109
- * @since 2.2.0
110
- *
111
- * @param array $clause Array of arguments belonging to the clause.
112
- * @param array $parent_query Parent query to which the clause belongs.
113
- * @return array {
114
- * @type array $where Array of subclauses for the WHERE statement.
115
- * @type array $join Empty array. Not used.
116
- * }
117
- */
118
- protected function get_sql_for_clause( $clause, $parent_query ) {
119
- global $wpdb;
120
-
121
- $sql_chunks = array(
122
- 'where' => array(),
123
- 'join' => array(),
124
- );
125
-
126
- $column = isset( $clause['column'] ) ? $this->validate_column( $clause['column'] ) : '';
127
- $value = isset( $clause['value'] ) ? $clause['value'] : '';
128
- if ( empty( $column ) || ! isset( $clause['value'] ) ) {
129
- return $sql_chunks;
130
- }
131
-
132
- if ( isset( $clause['compare'] ) ) {
133
- $clause['compare'] = strtoupper( $clause['compare'] );
134
- } else {
135
- $clause['compare'] = isset( $clause['value'] ) && is_array( $clause['value'] ) ? 'IN' : '=';
136
- }
137
-
138
- // Default 'compare' to '=' if no valid operator is found.
139
- if ( ! in_array( $clause['compare'], array(
140
- '=', '!=', '>', '>=', '<', '<=',
141
- 'LIKE', 'NOT LIKE',
142
- 'IN', 'NOT IN',
143
- 'BETWEEN', 'NOT BETWEEN',
144
- 'REGEXP', 'NOT REGEXP', 'RLIKE'
145
- ) ) ) {
146
- $clause['compare'] = '=';
147
- }
148
-
149
- $compare = $clause['compare'];
150
-
151
- $alias = ! empty( $this->table_alias ) ? "{$this->table_alias}." : '';
152
-
153
- // Next, Build the WHERE clause.
154
- $where = '';
155
-
156
- // Value.
157
- if ( isset( $clause['value'] ) ) {
158
- if ( in_array( $compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) {
159
- if ( ! is_array( $value ) ) {
160
- $value = preg_split( '/[,\s]+/', $value );
161
- }
162
- }
163
-
164
- // Tinyint.
165
- if ( ! empty( $column ) && true === in_array( $column, array( 'hide_sitewide', 'is_spam' ) ) ) {
166
- $sql_chunks['where'][] = $wpdb->prepare( "{$alias}{$column} = %d", $value );
167
-
168
- } else {
169
- switch ( $compare ) {
170
- // IN uses different syntax.
171
- case 'IN' :
172
- case 'NOT IN' :
173
- $in_sql = BP_Activity_Activity::get_in_operator_sql( "{$alias}{$column}", $value );
174
-
175
- // 'NOT IN' operator is as easy as a string replace!
176
- if ( 'NOT IN' === $compare ) {
177
- $in_sql = str_replace( 'IN', 'NOT IN', $in_sql );
178
- }
179
-
180
- $sql_chunks['where'][] = $in_sql;
181
- break;
182
-
183
- case 'BETWEEN' :
184
- case 'NOT BETWEEN' :
185
- $value = array_slice( $value, 0, 2 );
186
- $where = $wpdb->prepare( '%s AND %s', $value );
187
- break;
188
-
189
- case 'LIKE' :
190
- case 'NOT LIKE' :
191
- $value = '%' . bp_esc_like( $value ) . '%';
192
- $where = $wpdb->prepare( '%s', $value );
193
- break;
194
-
195
- default :
196
- $where = $wpdb->prepare( '%s', $value );
197
- break;
198
-
199
- }
200
- }
201
-
202
- if ( $where ) {
203
- $sql_chunks['where'][] = "{$alias}{$column} {$compare} {$where}";
204
- }
205
- }
206
-
207
- /*
208
- * Multiple WHERE clauses should be joined in parentheses.
209
- */
210
- if ( 1 < count( $sql_chunks['where'] ) ) {
211
- $sql_chunks['where'] = array( '( ' . implode( ' AND ', $sql_chunks['where'] ) . ' )' );
212
- }
213
-
214
- return $sql_chunks;
215
- }
216
-
217
- /**
218
- * Determine whether a clause is first-order.
219
- *
220
- * @since 2.2.0
221
- *
222
- * @param array $query Clause to check.
223
- * @return bool
224
- */
225
- protected function is_first_order_clause( $query ) {
226
- return isset( $query['column'] ) || isset( $query['value'] );
227
- }
228
-
229
- /**
230
- * Validates a column name parameter.
231
- *
232
- * Column names are checked against a whitelist of known tables.
233
- * See {@link BP_Activity_Query::db_tables}.
234
- *
235
- * @since 2.2.0
236
- *
237
- * @param string $column The user-supplied column name.
238
- * @return string A validated column name value.
239
- */
240
- public function validate_column( $column = '' ) {
241
- if ( in_array( $column, $this->db_columns ) ) {
242
- return $column;
243
- } else {
244
- return '';
245
- }
246
- }
247
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/classes/class-bp-activity-template.php DELETED
@@ -1,408 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Activity Template.
4
- *
5
- * @package BuddyPress
6
- * @subpackage ActivityTemplate
7
- * @since 1.5.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * The main activity template loop class.
15
- *
16
- * This is responsible for loading a group of activity items and displaying them.
17
- *
18
- * @since 1.0.0
19
- */
20
- class BP_Activity_Template {
21
-
22
- /**
23
- * The loop iterator.
24
- *
25
- * @since 1.0.0
26
- * @var int
27
- */
28
- public $current_activity = -1;
29
-
30
- /**
31
- * The activity count.
32
- *
33
- * @since 1.0.0
34
- * @var int
35
- */
36
- public $activity_count;
37
-
38
- /**
39
- * The total activity count.
40
- *
41
- * @since 1.0.0
42
- * @var int
43
- */
44
- public $total_activity_count;
45
-
46
- /**
47
- * Array of activities located by the query.
48
- *
49
- * @since 1.0.0
50
- * @var array
51
- */
52
- public $activities;
53
-
54
- /**
55
- * The activity object currently being iterated on.
56
- *
57
- * @since 1.0.0
58
- * @var object
59
- */
60
- public $activity;
61
-
62
- /**
63
- * A flag for whether the loop is currently being iterated.
64
- *
65
- * @since 1.0.0
66
- * @var bool
67
- */
68
- public $in_the_loop;
69
-
70
- /**
71
- * URL parameter key for activity pagination. Default: 'acpage'.
72
- *
73
- * @since 2.1.0
74
- * @var string
75
- */
76
- public $pag_arg;
77
-
78
- /**
79
- * The page number being requested.
80
- *
81
- * @since 1.0.0
82
- * @var int
83
- */
84
- public $pag_page;
85
-
86
- /**
87
- * The number of items being requested per page.
88
- *
89
- * @since 1.0.0
90
- * @var int
91
- */
92
- public $pag_num;
93
-
94
- /**
95
- * An HTML string containing pagination links.
96
- *
97
- * @since 1.0.0
98
- * @var string
99
- */
100
- public $pag_links;
101
-
102
- /**
103
- * The displayed user's full name.
104
- *
105
- * @since 1.0.0
106
- * @var string
107
- */
108
- public $full_name;
109
-
110
- /**
111
- * Constructor method.
112
- *
113
- * The arguments passed to this class constructor are of the same
114
- * format as {@link BP_Activity_Activity::get()}.
115
- *
116
- * @since 1.5.0
117
- *
118
- * @see BP_Activity_Activity::get() for a description of the argument
119
- * structure, as well as default values.
120
- *
121
- * @param array $args {
122
- * Array of arguments. Supports all arguments from
123
- * BP_Activity_Activity::get(), as well as 'page_arg' and
124
- * 'include'. Default values for 'per_page' and 'display_comments'
125
- * differ from the originating function, and are described below.
126
- * @type string $page_arg The string used as a query parameter in
127
- * pagination links. Default: 'acpage'.
128
- * @type array|bool $include Pass an array of activity IDs to
129
- * retrieve only those items, or false to noop the 'include'
130
- * parameter. 'include' differs from 'in' in that 'in' forms
131
- * an IN clause that works in conjunction with other filters
132
- * passed to the function, while 'include' is interpreted as
133
- * an exact list of items to retrieve, which skips all other
134
- * filter-related parameters. Default: false.
135
- * @type int|bool $per_page Default: 20.
136
- * @type string|bool $display_comments Default: 'threaded'.
137
- * }
138
- */
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(
147
- 0 => 'page',
148
- 1 => 'per_page',
149
- 2 => 'max',
150
- 3 => 'include',
151
- 4 => 'sort',
152
- 5 => 'filter',
153
- 6 => 'search_terms',
154
- 7 => 'display_comments',
155
- 8 => 'show_hidden',
156
- 9 => 'exclude',
157
- 10 => 'in',
158
- 11 => 'spam',
159
- 12 => 'page_arg'
160
- );
161
-
162
- $args = bp_core_parse_args_array( $old_args_keys, func_get_args() );
163
- }
164
-
165
- $defaults = array(
166
- 'page' => 1,
167
- 'per_page' => 20,
168
- 'page_arg' => 'acpage',
169
- 'max' => false,
170
- 'fields' => 'all',
171
- 'count_total' => false,
172
- 'sort' => false,
173
- 'include' => false,
174
- 'exclude' => false,
175
- 'in' => false,
176
- 'filter' => false,
177
- 'scope' => false,
178
- 'search_terms' => false,
179
- 'meta_query' => false,
180
- 'date_query' => false,
181
- 'filter_query' => false,
182
- 'display_comments' => 'threaded',
183
- 'show_hidden' => false,
184
- 'spam' => 'ham_only',
185
- 'update_meta_cache' => true,
186
- );
187
- $r = wp_parse_args( $args, $defaults );
188
- extract( $r );
189
-
190
- $this->pag_arg = sanitize_key( $r['page_arg'] );
191
- $this->pag_page = bp_sanitize_pagination_arg( $this->pag_arg, $r['page'] );
192
- $this->pag_num = bp_sanitize_pagination_arg( 'num', $r['per_page'] );
193
-
194
- // Check if blog/forum replies are disabled.
195
- $this->disable_blogforum_replies = (bool) bp_core_get_root_option( 'bp-disable-blogforum-comments' );
196
-
197
- // Get an array of the logged in user's favorite activities.
198
- $this->my_favs = bp_get_user_meta( bp_loggedin_user_id(), 'bp_favorite_activities', true );
199
-
200
- // Fetch specific activity items based on ID's.
201
- if ( !empty( $include ) ) {
202
- $this->activities = bp_activity_get_specific( array(
203
- 'activity_ids' => explode( ',', $include ),
204
- 'max' => $max,
205
- 'count_total' => $count_total,
206
- 'page' => $this->pag_page,
207
- 'per_page' => $this->pag_num,
208
- 'sort' => $sort,
209
- 'display_comments' => $display_comments,
210
- 'show_hidden' => $show_hidden,
211
- 'spam' => $spam,
212
- 'update_meta_cache' => $update_meta_cache,
213
- ) );
214
-
215
- // Fetch all activity items.
216
- } else {
217
- $this->activities = bp_activity_get( array(
218
- 'display_comments' => $display_comments,
219
- 'max' => $max,
220
- 'count_total' => $count_total,
221
- 'per_page' => $this->pag_num,
222
- 'page' => $this->pag_page,
223
- 'sort' => $sort,
224
- 'search_terms' => $search_terms,
225
- 'meta_query' => $meta_query,
226
- 'date_query' => $date_query,
227
- 'filter_query' => $filter_query,
228
- 'filter' => $filter,
229
- 'scope' => $scope,
230
- 'show_hidden' => $show_hidden,
231
- 'exclude' => $exclude,
232
- 'in' => $in,
233
- 'spam' => $spam,
234
- 'update_meta_cache' => $update_meta_cache,
235
- ) );
236
- }
237
-
238
- // The total_activity_count property will be set only if a
239
- // 'count_total' query has taken place.
240
- if ( ! is_null( $this->activities['total'] ) ) {
241
- if ( ! $max || $max >= (int) $this->activities['total'] ) {
242
- $this->total_activity_count = (int) $this->activities['total'];
243
- } else {
244
- $this->total_activity_count = (int) $max;
245
- }
246
- }
247
-
248
- $this->has_more_items = $this->activities['has_more_items'];
249
-
250
- $this->activities = $this->activities['activities'];
251
-
252
- if ( $max ) {
253
- if ( $max >= count($this->activities) ) {
254
- $this->activity_count = count( $this->activities );
255
- } else {
256
- $this->activity_count = (int) $max;
257
- }
258
- } else {
259
- $this->activity_count = count( $this->activities );
260
- }
261
-
262
- $this->full_name = bp_get_displayed_user_fullname();
263
-
264
- // Fetch parent content for activity comments so we do not have to query in the loop.
265
- foreach ( (array) $this->activities as $activity ) {
266
- if ( 'activity_comment' != $activity->type ) {
267
- continue;
268
- }
269
-
270
- $parent_ids[] = $activity->item_id;
271
- }
272
-
273
- if ( !empty( $parent_ids ) ) {
274
- $activity_parents = bp_activity_get_specific( array( 'activity_ids' => $parent_ids ) );
275
- }
276
-
277
- if ( !empty( $activity_parents['activities'] ) ) {
278
- foreach( $activity_parents['activities'] as $parent ) {
279
- $this->activity_parents[$parent->id] = $parent;
280
- }
281
-
282
- unset( $activity_parents );
283
- }
284
-
285
- if ( (int) $this->total_activity_count && (int) $this->pag_num ) {
286
- $this->pag_links = paginate_links( array(
287
- 'base' => add_query_arg( $this->pag_arg, '%#%' ),
288
- 'format' => '',
289
- 'total' => ceil( (int) $this->total_activity_count / (int) $this->pag_num ),
290
- 'current' => (int) $this->pag_page,
291
- 'prev_text' => _x( '&larr;', 'Activity pagination previous text', 'buddypress' ),
292
- 'next_text' => _x( '&rarr;', 'Activity pagination next text', 'buddypress' ),
293
- 'mid_size' => 1,
294
- 'add_args' => array(),
295
- ) );
296
- }
297
- }
298
-
299
- /**
300
- * Whether there are activity items available in the loop.
301
- *
302
- * @since 1.0.0
303
- *
304
- * @see bp_has_activities()
305
- *
306
- * @return bool True if there are items in the loop, otherwise false.
307
- */
308
- function has_activities() {
309
- if ( $this->activity_count ) {
310
- return true;
311
- }
312
-
313
- return false;
314
- }
315
-
316
- /**
317
- * Set up the next activity item and iterate index.
318
- *
319
- * @since 1.0.0
320
- *
321
- * @return object The next activity item to iterate over.
322
- */
323
- public function next_activity() {
324
- $this->current_activity++;
325
- $this->activity = $this->activities[ $this->current_activity ];
326
-
327
- return $this->activity;
328
- }
329
-
330
- /**
331
- * Rewind the posts and reset post index.
332
- *
333
- * @since 1.0.0
334
- */
335
- public function rewind_activities() {
336
- $this->current_activity = -1;
337
- if ( $this->activity_count > 0 ) {
338
- $this->activity = $this->activities[0];
339
- }
340
- }
341
-
342
- /**
343
- * Whether there are activity items left in the loop to iterate over.
344
- *
345
- * This method is used by {@link bp_activities()} as part of the while loop
346
- * that controls iteration inside the activities loop, eg:
347
- * while ( bp_activities() ) { ...
348
- *
349
- * @since 1.0.0
350
- *
351
- * @see bp_activities()
352
- *
353
- * @return bool True if there are more activity items to show,
354
- * otherwise false.
355
- */
356
- public function user_activities() {
357
- if ( ( $this->current_activity + 1 ) < $this->activity_count ) {
358
- return true;
359
- } elseif ( ( $this->current_activity + 1 ) == $this->activity_count ) {
360
-
361
- /**
362
- * Fires right before the rewinding of activity posts.
363
- *
364
- * @since 1.1.0
365
- */
366
- do_action( 'activity_loop_end' );
367
-
368
- // Do some cleaning up after the loop.
369
- $this->rewind_activities();
370
- }
371
-
372
- $this->in_the_loop = false;
373
-
374
- return false;
375
- }
376
-
377
- /**
378
- * Set up the current activity item inside the loop.
379
- *
380
- * Used by {@link bp_the_activity()} to set up the current activity item
381
- * data while looping, so that template tags used during that iteration
382
- * make reference to the current activity item.
383
- *
384
- * @since 1.0.0
385
- *
386
- * @see bp_the_activity()
387
- */
388
- public function the_activity() {
389
-
390
- $this->in_the_loop = true;
391
- $this->activity = $this->next_activity();
392
-
393
- if ( is_array( $this->activity ) ) {
394
- $this->activity = (object) $this->activity;
395
- }
396
-
397
- // Loop has just started.
398
- if ( $this->current_activity == 0 ) {
399
-
400
- /**
401
- * Fires if the current activity item is the first in the activity loop.
402
- *
403
- * @since 1.1.0
404
- */
405
- do_action('activity_loop_start');
406
- }
407
- }
408
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/classes/class-bp-activity-theme-compat.php DELETED
@@ -1,180 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Activity Theme Compatibility.
4
- *
5
- * @package BuddyPress
6
- * @since 1.7.0
7
- */
8
-
9
- // Exit if accessed directly.
10
- defined( 'ABSPATH' ) || exit;
11
-
12
- /**
13
- * The main theme compat class for BuddyPress Activity.
14
- *
15
- * This class sets up the necessary theme compatibility actions to safely output
16
- * activity template parts to the_title and the_content areas of a theme.
17
- *
18
- * @since 1.7.0
19
- */
20
- class BP_Activity_Theme_Compat {
21
-
22
- /**
23
- * Set up the activity component theme compatibility.
24
- *
25
- * @since 1.7.0
26
- */
27
- public function __construct() {
28
- add_action( 'bp_setup_theme_compat', array( $this, 'is_activity' ) );
29
- }
30
-
31
- /**
32
- * Set up the theme compatibility hooks, if we're looking at an activity page.
33
- *
34
- * @since 1.7.0
35
- */
36
- public function is_activity() {
37
-
38
- // Bail if not looking at a group.
39
- if ( ! bp_is_activity_component() )
40
- return;
41
-
42
- // Activity Directory.
43
- if ( ! bp_displayed_user_id() && ! bp_current_action() ) {
44
- bp_update_is_directory( true, 'activity' );
45
-
46
- /** This action is documented in bp-activity/bp-activity-screens.php */
47
- do_action( 'bp_activity_screen_index' );
48
-
49
- add_filter( 'bp_get_buddypress_template', array( $this, 'directory_template_hierarchy' ) );
50
- add_action( 'bp_template_include_reset_dummy_post_data', array( $this, 'directory_dummy_post' ) );
51
- add_filter( 'bp_replace_the_content', array( $this, 'directory_content' ) );
52
-
53
- // Single activity.
54
- } elseif ( bp_is_single_activity() ) {
55
- add_filter( 'bp_get_buddypress_template', array( $this, 'single_template_hierarchy' ) );
56
- add_action( 'bp_template_include_reset_dummy_post_data', array( $this, 'single_dummy_post' ) );
57
- add_filter( 'bp_replace_the_content', array( $this, 'single_dummy_content' ) );
58
- }
59
- }
60
-
61
- /** Directory *************************************************************/
62
-
63
- /**
64
- * Add template hierarchy to theme compat for the activity directory page.
65
- *
66
- * This is to mirror how WordPress has {@link https://codex.wordpress.org/Template_Hierarchy template hierarchy}.
67
- *
68
- * @since 1.8.0
69
- *
70
- * @param string $templates The templates from bp_get_theme_compat_templates().
71
- * @return array $templates Array of custom templates to look for.
72
- */
73
- public function directory_template_hierarchy( $templates ) {
74
-
75
- /**
76
- * Filters the template hierarchy for the activity directory page.
77
- *
78
- * @since 1.8.0
79
- *
80
- * @param array $index-directory Array holding template names to be merged into template list.
81
- */
82
- $new_templates = apply_filters( 'bp_template_hierarchy_activity_directory', array(
83
- 'activity/index-directory.php'
84
- ) );
85
-
86
- // Merge new templates with existing stack
87
- // @see bp_get_theme_compat_templates().
88
- $templates = array_merge( (array) $new_templates, $templates );
89
-
90
- return $templates;
91
- }
92
-
93
- /**
94
- * Update the global $post with directory data.
95
- *
96
- * @since 1.7.0
97
- */
98
- public function directory_dummy_post() {
99
- bp_theme_compat_reset_post( array(
100
- 'ID' => 0,
101
- 'post_title' => bp_get_directory_title( 'activity' ),
102
- 'post_author' => 0,
103
- 'post_date' => 0,
104
- 'post_content' => '',
105
- 'post_type' => 'page',
106
- 'post_status' => 'publish',
107
- 'is_page' => true,
108
- 'comment_status' => 'closed'
109
- ) );
110
- }
111
-
112
- /**
113
- * Filter the_content with the groups index template part.
114
- *
115
- * @since 1.7.0
116
- */
117
- public function directory_content() {
118
- return bp_buffer_template_part( 'activity/index', null, false );
119
- }
120
-
121
- /** Single ****************************************************************/
122
-
123
- /**
124
- * Add custom template hierarchy to theme compat for activity permalink pages.
125
- *
126
- * This is to mirror how WordPress has {@link https://codex.wordpress.org/Template_Hierarchy template hierarchy}.
127
- *
128
- * @since 1.8.0
129
- *
130
- * @param string $templates The templates from bp_get_theme_compat_templates().
131
- * @return array $templates Array of custom templates to look for.
132
- */
133
- public function single_template_hierarchy( $templates ) {
134
-
135
- /**
136
- * Filters the template hierarchy for the activity permalink pages.
137
- *
138
- * @since 1.8.0
139
- *
140
- * @param array $index Array holding template names to be merged into template list.
141
- */
142
- $new_templates = apply_filters( 'bp_template_hierarchy_activity_single_item', array(
143
- 'activity/single/index.php'
144
- ) );
145
-
146
- // Merge new templates with existing stack
147
- // @see bp_get_theme_compat_templates().
148
- $templates = array_merge( (array) $new_templates, $templates );
149
-
150
- return $templates;
151
- }
152
-
153
- /**
154
- * Update the global $post with the displayed user's data.
155
- *
156
- * @since 1.7.0
157
- */
158
- public function single_dummy_post() {
159
- bp_theme_compat_reset_post( array(
160
- 'ID' => 0,
161
- 'post_title' => __( 'Activity', 'buddypress' ),
162
- 'post_author' => 0,
163
- 'post_date' => 0,
164
- 'post_content' => '',
165
- 'post_type' => 'page',
166
- 'post_status' => 'publish',
167
- 'is_page' => true,
168
- 'comment_status' => 'closed'
169
- ) );
170
- }
171
-
172
- /**
173
- * Filter the_content with the members' activity permalink template part.
174
- *
175
- * @since 1.7.0
176
- */
177
- public function single_dummy_content() {
178
- return bp_buffer_template_part( 'activity/single/home', null, false );
179
- }
180
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/classes/class-bp-akismet.php DELETED
@@ -1,651 +0,0 @@
1
- <?php
2
- /**
3
- * Akismet support for BuddyPress' Activity Stream.
4
- *
5
- * @package BuddyPress
6
- * @subpackage ActivityAkismet
7
- * @since 1.6.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Akismet support for the Activity component.
15
- *
16
- * @since 1.6.0
17
- * @since 2.3.0 We only support Akismet 3+.
18
- */
19
- class BP_Akismet {
20
-
21
- /**
22
- * The activity last marked as spam.
23
- *
24
- * @since 1.6.0
25
- * @var BP_Activity_Activity
26
- */
27
- protected $last_activity = null;
28
-
29
- /**
30
- * Constructor.
31
- *
32
- * @since 1.6.0
33
- */
34
- public function __construct() {
35
- $this->setup_actions();
36
- }
37
-
38
- /**
39
- * Hook Akismet into the activity stream.
40
- *
41
- * @since 1.6.0
42
- */
43
- protected function setup_actions() {
44
- // Add nonces to activity stream lists.
45
- add_action( 'bp_after_activity_post_form', array( $this, 'add_activity_stream_nonce' ) );
46
- add_action( 'bp_activity_entry_comments', array( $this, 'add_activity_stream_nonce' ) );
47
-
48
- // Add a "mark as spam" button to individual activity items.
49
- add_action( 'bp_activity_entry_meta', array( $this, 'add_activity_spam_button' ) );
50
- add_action( 'bp_activity_comment_options', array( $this, 'add_activity_comment_spam_button' ) );
51
-
52
- // Check activity for spam.
53
- add_action( 'bp_activity_before_save', array( $this, 'check_activity' ), 4, 1 );
54
-
55
- // Tidy up member's latest (activity) update.
56
- add_action( 'bp_activity_posted_update', array( $this, 'check_member_activity_update' ), 1, 3 );
57
-
58
- // Hooks to extend Activity core spam/ham functions for Akismet.
59
- add_action( 'bp_activity_mark_as_spam', array( $this, 'mark_as_spam' ), 10, 2 );
60
- add_action( 'bp_activity_mark_as_ham', array( $this, 'mark_as_ham' ), 10, 2 );
61
-
62
- // Hook into the Activity wp-admin screen.
63
- add_action( 'bp_activity_admin_comment_row_actions', array( $this, 'comment_row_action' ), 10, 2 );
64
- add_action( 'bp_activity_admin_load', array( $this, 'add_history_metabox' ) );
65
- }
66
-
67
- /**
68
- * Add a history item to the hover links in an activity's row.
69
- *
70
- * This function lifted with love from the Akismet WordPress plugin's
71
- * akismet_comment_row_action() function. Thanks!
72
- *
73
- * @since 1.6.0
74
- *
75
- * @param array $actions The hover links.
76
- * @param array $activity The activity for the current row being processed.
77
- * @return array The hover links.
78
- */
79
- function comment_row_action( $actions, $activity ) {
80
- $akismet_result = bp_activity_get_meta( $activity['id'], '_bp_akismet_result' );
81
- $user_result = bp_activity_get_meta( $activity['id'], '_bp_akismet_user_result' );
82
- $desc = '';
83
-
84
- if ( !$user_result || $user_result == $akismet_result ) {
85
- // Show the original Akismet result if the user hasn't overridden it, or if their decision was the same.
86
- if ( 'true' == $akismet_result && $activity['is_spam'] )
87
- $desc = __( 'Flagged as spam by Akismet', 'buddypress' );
88
-
89
- elseif ( 'false' == $akismet_result && !$activity['is_spam'] )
90
- $desc = __( 'Cleared by Akismet', 'buddypress' );
91
-
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.
102
- if ( $akismet_result ) {
103
- $b = array();
104
- foreach ( $actions as $k => $item ) {
105
- $b[ $k ] = $item;
106
- if ( $k == 'edit' )
107
- $b['history'] = '<a href="' . esc_url( bp_get_admin_url( 'admin.php?page=bp-activity&amp;action=edit&aid=' . $activity['id'] ) ) . '#bp_activity_history"> '. __( 'History', 'buddypress' ) . '</a>';
108
- }
109
-
110
- $actions = $b;
111
- }
112
-
113
- if ( $desc )
114
- echo '<span class="akismet-status"><a href="' . esc_url( bp_get_admin_url( 'admin.php?page=bp-activity&amp;action=edit&aid=' . $activity['id'] ) ) . '#bp_activity_history">' . htmlspecialchars( $desc ) . '</a></span>';
115
-
116
- /**
117
- * Filters the list of actions for the current activity's row.
118
- *
119
- * @since 1.6.0
120
- *
121
- * @param array $actions Array of available actions for the current activity item's row.
122
- */
123
- return apply_filters( 'bp_akismet_comment_row_action', $actions );
124
- }
125
-
126
- /**
127
- * Generate nonces for activity forms.
128
- *
129
- * These nonces appear in the member profile status form, as well as in
130
- * the reply form of each activity item. The nonces are, in turn, used
131
- * by Akismet to help detect spam activity.
132
- *
133
- * @since 1.6.0
134
- *
135
- * @see https://plugins.trac.wordpress.org/ticket/1232
136
- */
137
- public function add_activity_stream_nonce() {
138
- $form_id = '_bp_as_nonce';
139
- $value = '_bp_as_nonce_' . bp_loggedin_user_id();
140
-
141
- // If we're in the activity stream loop, we can use the current item's ID to make the nonce unique.
142
- if ( 'bp_activity_entry_comments' == current_filter() ) {
143
- $form_id .= '_' . bp_get_activity_id();
144
- $value .= '_' . bp_get_activity_id();
145
- }
146
-
147
- wp_nonce_field( $value, $form_id, false );
148
- }
149
-
150
- /**
151
- * Clean up the bp_latest_update usermeta in case of spamming.
152
- *
153
- * Run just after an update is posted, this method check to see whether
154
- * the newly created update has been marked as spam by Akismet. If so,
155
- * the cached update is cleared from the user's 'bp_latest_update'
156
- * usermeta, ensuring that it won't appear in the member header and
157
- * elsewhere in the theme.
158
- *
159
- * This can't be done in BP_Akismet::check_activity() due to the
160
- * default AJAX implementation; see bp_dtheme_post_update().
161
- *
162
- * @since 1.6.0
163
- *
164
- * @see bp_dtheme_post_update()
165
- *
166
- * @param string $content Activity update text.
167
- * @param int $user_id User ID.
168
- * @param int $activity_id Activity ID.
169
- */
170
- public function check_member_activity_update( $content, $user_id, $activity_id ) {
171
- // By default, only handle activity updates and activity comments.
172
- if ( empty( $this->last_activity ) || !in_array( $this->last_activity->type, BP_Akismet::get_activity_types() ) )
173
- return;
174
-
175
- // Was this $activity_id just marked as spam? If not, bail out.
176
- if ( !$this->last_activity->id || $activity_id != $this->last_activity->id || 'false' == $this->last_activity->akismet_submission['bp_as_result'] )
177
- return;
178
-
179
- // It was, so delete the member's latest activity update.
180
- bp_delete_user_meta( $user_id, 'bp_latest_update' );
181
- }
182
-
183
- /**
184
- * Adds a "mark as spam" button to each activity item for site admins.
185
- *
186
- * This function is intended to be used inside the activity stream loop.
187
- *
188
- * @since 1.6.0
189
- */
190
- public function add_activity_spam_button() {
191
- if ( !bp_activity_user_can_mark_spam() )
192
- return;
193
-
194
- // By default, only handle activity updates and activity comments.
195
- if ( !in_array( bp_get_activity_type(), BP_Akismet::get_activity_types() ) )
196
- return;
197
-
198
- bp_button(
199
- array(
200
- 'block_self' => false,
201
- 'component' => 'activity',
202
- 'id' => 'activity_make_spam_' . bp_get_activity_id(),
203
- 'link_class' => 'bp-secondary-action spam-activity confirm button item-button',
204
- 'link_href' => wp_nonce_url( bp_get_root_domain() . '/' . bp_get_activity_slug() . '/spam/' . bp_get_activity_id() . '/', 'bp_activity_akismet_spam_' . bp_get_activity_id() ),
205
- 'link_text' => __( 'Spam', 'buddypress' ),
206
- 'wrapper' => false,
207
- )
208
- );
209
- }
210
-
211
- /**
212
- * Adds a "mark as spam" button to each activity COMMENT item for site admins.
213
- *
214
- * This function is intended to be used inside the activity stream loop.
215
- *
216
- * @since 1.6.0
217
- */
218
- public function add_activity_comment_spam_button() {
219
- if ( !bp_activity_user_can_mark_spam() )
220
- return;
221
-
222
- // By default, only handle activity updates and activity comments.
223
- $current_comment = bp_activity_current_comment();
224
- if ( empty( $current_comment ) || !in_array( $current_comment->type, BP_Akismet::get_activity_types() ) )
225
- return;
226
-
227
- bp_button(
228
- array(
229
- 'block_self' => false,
230
- 'component' => 'activity',
231
- 'id' => 'activity_make_spam_' . bp_get_activity_comment_id(),
232
- 'link_class' => 'bp-secondary-action spam-activity-comment confirm',
233
- 'link_href' => wp_nonce_url( bp_get_root_domain() . '/' . bp_get_activity_slug() . '/spam/' . bp_get_activity_comment_id() . '/?cid=' . bp_get_activity_comment_id(), 'bp_activity_akismet_spam_' . bp_get_activity_comment_id() ),
234
- 'link_text' => __( 'Spam', 'buddypress' ),
235
- 'wrapper' => false,
236
- )
237
- );
238
- }
239
-
240
- /**
241
- * Get a filterable list of activity types that Akismet should automatically check for spam.
242
- *
243
- * @since 1.6.0
244
- *
245
- * @static
246
- *
247
- * @return array $value List of activity types.
248
- */
249
- public static function get_activity_types() {
250
-
251
- /**
252
- * Filters the list of activity types that Akismet should automatically check for spam.
253
- *
254
- * @since 1.6.0
255
- *
256
- * @param array $value Array of default activity types for Akismet to check.
257
- */
258
- return apply_filters( 'bp_akismet_get_activity_types', array( 'activity_comment', 'activity_update' ) );
259
- }
260
-
261
- /**
262
- * Mark activity item as spam.
263
- *
264
- * @since 1.6.0
265
- *
266
- * @param BP_Activity_Activity $activity Activity item being spammed.
267
- * @param string $source Either "by_a_person" (e.g. a person has
268
- * manually marked the activity as spam) or
269
- * "by_akismet" (automatically spammed).
270
- */
271
- public function mark_as_spam( $activity, $source ) {
272
- // Record this item so we can do some tidyup in BP_Akismet::check_member_activity_update().
273
- $this->last_activity = $activity;
274
-
275
- /**
276
- * Fires after marking an activity item has been marked as spam.
277
- *
278
- * @since 1.6.0
279
- *
280
- * @param BP_Activity_Activity $activity Activity object being marked as spam.
281
- * @param string $source Source of the whom marked as spam.
282
- * Either "by_a_person" (e.g. a person has
283
- * manually marked the activity as spam)
284
- * or "by_akismet".
285
- */
286
- do_action( 'bp_activity_akismet_mark_as_spam', $activity, $source );
287
- }
288
-
289
- /**
290
- * Mark activity item as ham.
291
- *
292
- * @since 1.6.0
293
- *
294
- * @param BP_Activity_Activity $activity Activity item being hammed.
295
- * @param string $source Either "by_a_person" (e.g. a person has
296
- * manually marked the activity as ham) or
297
- * "by_akismet" (automatically hammed).
298
- */
299
- public function mark_as_ham( $activity, $source ) {
300
- // If the activity was, originally, automatically marked as spam by Akismet, run the @mentions filter as it would have been skipped.
301
- if ( 'true' == bp_activity_get_meta( $activity->id, '_bp_akismet_result' ) && !bp_activity_get_meta( $activity->id, '_bp_akismet_user_result' ) )
302
- $activity->content = bp_activity_at_name_filter( $activity->content, $activity->id );
303
-
304
- /**
305
- * Fires after marking an activity item has been marked as ham.
306
- *
307
- * @since 1.6.0
308
- *
309
- * @param BP_Activity_Activity $activity Activity object being marked as ham.
310
- * @param string $source Source of the whom marked as ham.
311
- * Either "by_a_person" (e.g. a person has
312
- * manually marked the activity as ham) or
313
- * "by_akismet" (automatically hammed).
314
- */
315
- do_action( 'bp_activity_akismet_mark_as_ham', $activity, $source );
316
- }
317
-
318
- /**
319
- * Build a data package for the Akismet service to inspect.
320
- *
321
- * @since 1.6.0
322
- *
323
- * @see http://akismet.com/development/api/#comment-check
324
- * @static
325
- *
326
- * @param BP_Activity_Activity $activity Activity item data.
327
- * @return array $activity_data
328
- */
329
- public static function build_akismet_data_package( $activity ) {
330
- $userdata = get_userdata( $activity->user_id );
331
-
332
- $activity_data = array();
333
- $activity_data['akismet_comment_nonce'] = 'inactive';
334
- $activity_data['comment_author'] = $userdata->display_name;
335
- $activity_data['comment_author_email'] = $userdata->user_email;
336
- $activity_data['comment_author_url'] = bp_core_get_userlink( $userdata->ID, false, true);
337
- $activity_data['comment_content'] = $activity->content;
338
- $activity_data['comment_type'] = $activity->type;
339
- $activity_data['permalink'] = bp_activity_get_permalink( $activity->id, $activity );
340
- $activity_data['user_ID'] = $userdata->ID;
341
- $activity_data['user_role'] = Akismet::get_user_roles( $userdata->ID );
342
-
343
- /**
344
- * Get the nonce if the new activity was submitted through the "what's up, Paul?" form.
345
- * This helps Akismet ensure that the update was a valid form submission.
346
- */
347
- if ( !empty( $_POST['_bp_as_nonce'] ) )
348
- $activity_data['akismet_comment_nonce'] = wp_verify_nonce( $_POST['_bp_as_nonce'], "_bp_as_nonce_{$userdata->ID}" ) ? 'passed' : 'failed';
349
-
350
- /**
351
- * If the new activity was a reply to an existing item, check the nonce with the activity parent ID.
352
- * This helps Akismet ensure that the update was a valid form submission.
353
- */
354
- elseif ( !empty( $activity->secondary_item_id ) && !empty( $_POST['_bp_as_nonce_' . $activity->secondary_item_id] ) )
355
- $activity_data['akismet_comment_nonce'] = wp_verify_nonce( $_POST["_bp_as_nonce_{$activity->secondary_item_id}"], "_bp_as_nonce_{$userdata->ID}_{$activity->secondary_item_id}" ) ? 'passed' : 'failed';
356
-
357
- /**
358
- * Filters activity data before being sent to Akismet to inspect.
359
- *
360
- * @since 1.6.0
361
- *
362
- * @param array $activity_data Array of activity data for Akismet to inspect.
363
- * @param BP_Activity_Activity $activity Activity item data.
364
- */
365
- return apply_filters( 'bp_akismet_build_akismet_data_package', $activity_data, $activity );
366
- }
367
-
368
- /**
369
- * Check if the activity item is spam or ham.
370
- *
371
- * @since 1.6.0
372
- *
373
- * @see http://akismet.com/development/api/
374
- * @todo Spam counter?
375
- * @todo Auto-delete old spam?
376
- *
377
- * @param BP_Activity_Activity $activity The activity item to check.
378
- */
379
- public function check_activity( $activity ) {
380
- // By default, only handle activity updates and activity comments.
381
- if ( !in_array( $activity->type, BP_Akismet::get_activity_types() ) )
382
- return;
383
-
384
- // Make sure last_activity is clear to avoid any confusion.
385
- $this->last_activity = null;
386
-
387
- // Build data package for Akismet.
388
- $activity_data = BP_Akismet::build_akismet_data_package( $activity );
389
-
390
- // Check with Akismet to see if this is spam.
391
- $activity_data = $this->send_akismet_request( $activity_data, 'check', 'spam' );
392
-
393
- // Record this item.
394
- $this->last_activity = $activity;
395
-
396
- // Store a copy of the data that was submitted to Akismet.
397
- $this->last_activity->akismet_submission = $activity_data;
398
-
399
- // Spam.
400
- if ( 'true' == $activity_data['bp_as_result'] ) {
401
- /**
402
- * Fires after an activity item has been proven to be spam, but before officially being marked as spam.
403
- *
404
- * @since 1.6.0
405
- *
406
- * @param BP_Activity_Activity $activity The activity item proven to be spam.
407
- * @param array $activity_data Array of activity data for item including
408
- * Akismet check results data.
409
- */
410
- do_action_ref_array( 'bp_activity_akismet_spam_caught', array( &$activity, $activity_data ) );
411
-
412
- // Mark as spam.
413
- bp_activity_mark_as_spam( $activity, 'by_akismet' );
414
- }
415
-
416
- // Update activity meta after a spam check.
417
- add_action( 'bp_activity_after_save', array( $this, 'update_activity_akismet_meta' ), 1, 1 );
418
- }
419
-
420
- /**
421
- * Update activity meta after a manual spam change (user-initiated).
422
- *
423
- * @since 1.6.0
424
- *
425
- * @param BP_Activity_Activity $activity The activity to check.
426
- */
427
- public function update_activity_spam_meta( $activity ) {
428
- // By default, only handle activity updates and activity comments.
429
- if ( !in_array( $activity->type, BP_Akismet::get_activity_types() ) )
430
- return;
431
-
432
- $this->update_activity_history( $activity->id, sprintf( __( '%s reported this activity as spam', 'buddypress' ), bp_get_loggedin_user_username() ), 'report-spam' );
433
- bp_activity_update_meta( $activity->id, '_bp_akismet_user_result', 'true' );
434
- bp_activity_update_meta( $activity->id, '_bp_akismet_user', bp_get_loggedin_user_username() );
435
- }
436
-
437
- /**
438
- * Update activity meta after a manual ham change (user-initiated).
439
- *
440
- * @since 1.6.0
441
- *
442
- * @param BP_Activity_Activity $activity The activity to check.
443
- */
444
- public function update_activity_ham_meta( $activity ) {
445
- // By default, only handle activity updates and activity comments.
446
- if ( !in_array( $activity->type, BP_Akismet::get_activity_types() ) )
447
- return;
448
-
449
- $this->update_activity_history( $activity->id, sprintf( __( '%s reported this activity as not spam', 'buddypress' ), bp_get_loggedin_user_username() ), 'report-ham' );
450
- bp_activity_update_meta( $activity->id, '_bp_akismet_user_result', 'false' );
451
- bp_activity_update_meta( $activity->id, '_bp_akismet_user', bp_get_loggedin_user_username() );
452
- }
453
-
454
- /**
455
- * Update activity meta after an automatic spam check (not user-initiated).
456
- *
457
- * @since 1.6.0
458
- *
459
- * @param BP_Activity_Activity $activity The activity to check.
460
- */
461
- public function update_activity_akismet_meta( $activity ) {
462
- // Check we're dealing with what was last updated by Akismet.
463
- if ( empty( $this->last_activity ) || !empty( $this->last_activity ) && $activity->id != $this->last_activity->id )
464
- return;
465
-
466
- // By default, only handle activity updates and activity comments.
467
- if ( !in_array( $this->last_activity->type, BP_Akismet::get_activity_types() ) )
468
- return;
469
-
470
- // Spam.
471
- if ( 'true' == $this->last_activity->akismet_submission['bp_as_result'] ) {
472
- bp_activity_update_meta( $activity->id, '_bp_akismet_result', 'true' );
473
- $this->update_activity_history( $activity->id, __( 'Akismet caught this item as spam', 'buddypress' ), 'check-spam' );
474
-
475
- // Not spam.
476
- } elseif ( 'false' == $this->last_activity->akismet_submission['bp_as_result'] ) {
477
- bp_activity_update_meta( $activity->id, '_bp_akismet_result', 'false' );
478
- $this->update_activity_history( $activity->id, __( 'Akismet cleared this item', 'buddypress' ), 'check-ham' );
479
-
480
- // Uh oh, something's gone horribly wrong. Unexpected result.
481
- } else {
482
- bp_activity_update_meta( $activity->id, '_bp_akismet_error', bp_core_current_time() );
483
- $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' );
484
- }
485
-
486
- // Record the original data which was submitted to Akismet for checking.
487
- bp_activity_update_meta( $activity->id, '_bp_akismet_submission', $this->last_activity->akismet_submission );
488
- }
489
-
490
- /**
491
- * Contact Akismet to check if this is spam or ham.
492
- *
493
- * Props to WordPress core Akismet plugin for a lot of this.
494
- *
495
- * @since 1.6.0
496
- *
497
- * @param array $activity_data Packet of information to submit to Akismet.
498
- * @param string $check "check" or "submit".
499
- * @param string $spam "spam" or "ham".
500
- * @return array $activity_data Activity data, with Akismet data added.
501
- */
502
- public function send_akismet_request( $activity_data, $check = 'check', $spam = 'spam' ) {
503
- $query_string = $path = '';
504
-
505
- $activity_data['blog'] = bp_get_option( 'home' );
506
- $activity_data['blog_charset'] = bp_get_option( 'blog_charset' );
507
- $activity_data['blog_lang'] = get_locale();
508
- $activity_data['referrer'] = $_SERVER['HTTP_REFERER'];
509
- $activity_data['user_agent'] = bp_core_current_user_ua();
510
- $activity_data['user_ip'] = bp_core_current_user_ip();
511
-
512
- if ( Akismet::is_test_mode() )
513
- $activity_data['is_test'] = 'true';
514
-
515
- // Loop through _POST args and rekey strings.
516
- foreach ( $_POST as $key => $value )
517
- if ( is_string( $value ) && 'cookie' != $key )
518
- $activity_data['POST_' . $key] = $value;
519
-
520
- // Keys to ignore.
521
- $ignore = array( 'HTTP_COOKIE', 'HTTP_COOKIE2', 'PHP_AUTH_PW' );
522
-
523
- // Loop through _SERVER args and remove whitelisted keys.
524
- foreach ( $_SERVER as $key => $value ) {
525
-
526
- // Key should not be ignored.
527
- if ( !in_array( $key, $ignore ) && is_string( $value ) ) {
528
- $activity_data[$key] = $value;
529
-
530
- // Key should be ignored.
531
- } else {
532
- $activity_data[$key] = '';
533
- }
534
- }
535
-
536
- foreach ( $activity_data as $key => $data )
537
- $query_string .= $key . '=' . urlencode( stripslashes( $data ) ) . '&';
538
-
539
- if ( 'check' == $check )
540
- $path = 'comment-check';
541
- elseif ( 'submit' == $check )
542
- $path = 'submit-' . $spam;
543
-
544
- // Send to Akismet.
545
- add_filter( 'akismet_ua', array( $this, 'buddypress_ua' ) );
546
- $response = Akismet::http_post( $query_string, $path );
547
- remove_filter( 'akismet_ua', array( $this, 'buddypress_ua' ) );
548
-
549
- // Get the response.
550
- if ( ! empty( $response[1] ) && ! is_wp_error( $response[1] ) )
551
- $activity_data['bp_as_result'] = $response[1];
552
- else
553
- $activity_data['bp_as_result'] = false;
554
-
555
- // Perform a daily tidy up.
556
- if ( ! wp_next_scheduled( 'bp_activity_akismet_delete_old_metadata' ) )
557
- wp_schedule_event( time(), 'daily', 'bp_activity_akismet_delete_old_metadata' );
558
-
559
- return $activity_data;
560
- }
561
-
562
- /**
563
- * Filters user agent when sending to Akismet to add BuddyPress info.
564
- *
565
- * @since 1.6.0
566
- *
567
- * @param string $user_agent User agent string, as generated by Akismet.
568
- * @return string $user_agent Modified user agent string.
569
- */
570
- public function buddypress_ua( $user_agent ) {
571
- $user_agent = 'BuddyPress/' . bp_get_version() . ' | Akismet/'. constant( 'AKISMET_VERSION' );
572
- return $user_agent;
573
- }
574
-
575
- /**
576
- * Adds a "History" meta box to the activity edit screen.
577
- *
578
- * @since 1.6.0
579
- *
580
- * @param string $screen_action The type of screen that has been requested.
581
- */
582
- function add_history_metabox( $screen_action ) {
583
- // Only proceed if we're on the edit screen.
584
- if ( 'edit' != $screen_action )
585
- return;
586
-
587
- // Display meta box with a low priority (low position on screen by default).
588
- add_meta_box( 'bp_activity_history', __( 'Activity History', 'buddypress' ), array( $this, 'history_metabox' ), get_current_screen()->id, 'normal', 'low' );
589
- }
590
-
591
- /**
592
- * History meta box for the Activity admin edit screen.
593
- *
594
- * @since 1.6.0
595
- *
596
- * @see https://buddypress.trac.wordpress.org/ticket/3907
597
- * @todo Update activity meta to allow >1 record with the same key (iterate through $history).
598
- *
599
- * @param object $item Activity item.
600
- */
601
- function history_metabox( $item ) {
602
- $history = BP_Akismet::get_activity_history( $item->id );
603
-
604
- if ( empty( $history ) )
605
- return;
606
-
607
- echo '<div class="akismet-history"><div>';
608
- 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] ) );
609
- echo '</div></div>';
610
- }
611
-
612
- /**
613
- * Update an activity item's Akismet history.
614
- *
615
- * @since 1.6.0
616
- *
617
- * @param int $activity_id Activity item ID.
618
- * @param string $message Human-readable description of what's changed.
619
- * @param string $event The type of check we were carrying out.
620
- */
621
- public function update_activity_history( $activity_id = 0, $message = '', $event = '' ) {
622
- $event = array(
623
- 'event' => $event,
624
- 'message' => $message,
625
- 'time' => Akismet::_get_microtime(),
626
- 'user' => bp_loggedin_user_id(),
627
- );
628
-
629
- // Save the history data.
630
- bp_activity_update_meta( $activity_id, '_bp_akismet_history', $event );
631
- }
632
-
633
- /**
634
- * Get an activity item's Akismet history.
635
- *
636
- * @since 1.6.0
637
- *
638
- * @param int $activity_id Activity item ID.
639
- * @return array The activity item's Akismet history.
640
- */
641
- public function get_activity_history( $activity_id = 0 ) {
642
- $history = bp_activity_get_meta( $activity_id, '_bp_akismet_history' );
643
- if ( $history === false )
644
- $history = array();
645
-
646
- // Sort it by the time recorded.
647
- usort( $history, 'akismet_cmp_time' );
648
-
649
- return $history;
650
- }
651
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/css/mentions-rtl.css DELETED
@@ -1,106 +0,0 @@
1
- .atwho-view {
2
- background: rgba(204, 204, 204, 0.8);
3
- border-radius: 2px;
4
- border: 1px solid rgb(204, 204, 204);
5
- box-shadow: 0 0 5px rgba(204, 204, 204, 0.25), 0 0 1px #fff;
6
- color: #d84800;
7
- display: none;
8
- font-family: sans-serif;
9
- margin-top: 18px;
10
- position: absolute;
11
- top: 0;
12
- z-index: 1000; /* >999 for wp-admin */
13
- }
14
- .atwho-view {
15
- left: 0;
16
- }
17
-
18
- .atwho-view ul {
19
- background: #fff;
20
- list-style: none;
21
- margin: auto;
22
- padding: 0;
23
- }
24
-
25
- .atwho-view ul li {
26
- border-bottom: 1px solid #efefef;
27
- box-sizing: content-box;
28
- cursor: pointer;
29
- display: block;
30
- font-size: 14px;
31
- height: 20px;
32
- line-height: 20px;
33
- margin: 0;
34
- overflow: hidden;
35
- padding: 5px 10px;
36
- }
37
-
38
- .atwho-view img {
39
- border-radius: 2px;
40
- float: left;
41
- height: 20px;
42
- margin-top: 0;
43
- width: 20px;
44
- }
45
-
46
- .atwho-view strong {
47
- background: #efefef;
48
- font-weight: 700;
49
- }
50
-
51
- .atwho-view .username strong {
52
- color: #d54e21;
53
- }
54
-
55
- .atwho-view small {
56
- color: #aaa;
57
- float: left;
58
- font-size: smaller;
59
- font-weight: 400;
60
- margin: 0 40px 0 10px;
61
- }
62
-
63
- .atwho-view .cur {
64
- background: rgba(239, 239, 239, 0.5);
65
- }
66
-
67
- @media (max-width: 900px) {
68
-
69
- .atwho-view img {
70
- float: right;
71
- margin: 0 0 0 10px;
72
- }
73
- }
74
-
75
- @media (max-width: 400px) {
76
-
77
- .atwho-view ul li {
78
- font-size: 16px;
79
- line-height: 23px;
80
- padding: 13px;
81
- }
82
-
83
- .atwho-view ul li img {
84
- height: 30px;
85
- margin-top: -5px;
86
- width: 30px;
87
- }
88
-
89
- .atwho-view {
90
- border-radius: 0;
91
- height: 100%;
92
- right: 0 !important;
93
- width: 100%;
94
- }
95
-
96
- .atwho-view ul li .username {
97
- display: inline-block;
98
- margin: -10px 0 0 0;
99
- padding: 10px 0;
100
- }
101
-
102
- .atwho-view ul li small {
103
- display: inline-block;
104
- margin-right: 20px;
105
- }
106
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/css/mentions-rtl.min.css DELETED
@@ -1 +0,0 @@
1
- .atwho-view{background:rgba(204,204,204,.8);border-radius:2px;border:1px solid #ccc;box-shadow:0 0 5px rgba(204,204,204,.25),0 0 1px #fff;color:#d84800;display:none;font-family:sans-serif;margin-top:18px;position:absolute;top:0;z-index:1000}.atwho-view{left:0}.atwho-view ul{background:#fff;list-style:none;margin:auto;padding:0}.atwho-view ul li{border-bottom:1px solid #efefef;box-sizing:content-box;cursor:pointer;display:block;font-size:14px;height:20px;line-height:20px;margin:0;overflow:hidden;padding:5px 10px}.atwho-view img{border-radius:2px;float:left;height:20px;margin-top:0;width:20px}.atwho-view strong{background:#efefef;font-weight:700}.atwho-view .username strong{color:#d54e21}.atwho-view small{color:#aaa;float:left;font-size:smaller;font-weight:400;margin:0 40px 0 10px}.atwho-view .cur{background:rgba(239,239,239,.5)}@media (max-width:900px){.atwho-view img{float:right;margin:0 0 0 10px}}@media (max-width:400px){.atwho-view ul li{font-size:16px;line-height:23px;padding:13px}.atwho-view ul li img{height:30px;margin-top:-5px;width:30px}.atwho-view{border-radius:0;height:100%;right:0!important;width:100%}.atwho-view ul li .username{display:inline-block;margin:-10px 0 0 0;padding:10px 0}.atwho-view ul li small{display:inline-block;margin-right:20px}}
 
bp-activity/css/mentions.css DELETED
@@ -1,108 +0,0 @@
1
- .atwho-view {
2
- background: rgba(204, 204, 204, 0.8);
3
- border-radius: 2px;
4
- border: 1px solid rgb(204, 204, 204);
5
- box-shadow: 0 0 5px rgba(204, 204, 204, 0.25), 0 0 1px #fff;
6
- color: #d84800;
7
- display: none;
8
- font-family: sans-serif;
9
- margin-top: 18px;
10
- position: absolute;
11
- top: 0;
12
- z-index: 1000; /* >999 for wp-admin */
13
- }
14
-
15
- /* rtl:ignore */
16
- .atwho-view {
17
- left: 0;
18
- }
19
-
20
- .atwho-view ul {
21
- background: #fff;
22
- list-style: none;
23
- margin: auto;
24
- padding: 0;
25
- }
26
-
27
- .atwho-view ul li {
28
- border-bottom: 1px solid #efefef;
29
- box-sizing: content-box;
30
- cursor: pointer;
31
- display: block;
32
- font-size: 14px;
33
- height: 20px;
34
- line-height: 20px;
35
- margin: 0;
36
- overflow: hidden;
37
- padding: 5px 10px;
38
- }
39
-
40
- .atwho-view img {
41
- border-radius: 2px;
42
- float: right;
43
- height: 20px;
44
- margin-top: 0;
45
- width: 20px;
46
- }
47
-
48
- .atwho-view strong {
49
- background: #efefef;
50
- font-weight: 700;
51
- }
52
-
53
- .atwho-view .username strong {
54
- color: #d54e21;
55
- }
56
-
57
- .atwho-view small {
58
- color: #aaa;
59
- float: right;
60
- font-size: smaller;
61
- font-weight: 400;
62
- margin: 0 10px 0 40px;
63
- }
64
-
65
- .atwho-view .cur {
66
- background: rgba(239, 239, 239, 0.5);
67
- }
68
-
69
- @media (max-width: 900px) {
70
-
71
- .atwho-view img {
72
- float: left;
73
- margin: 0 10px 0 0;
74
- }
75
- }
76
-
77
- @media (max-width: 400px) {
78
-
79
- .atwho-view ul li {
80
- font-size: 16px;
81
- line-height: 23px;
82
- padding: 13px;
83
- }
84
-
85
- .atwho-view ul li img {
86
- height: 30px;
87
- margin-top: -5px;
88
- width: 30px;
89
- }
90
-
91
- .atwho-view {
92
- border-radius: 0;
93
- height: 100%;
94
- left: 0 !important;
95
- width: 100%;
96
- }
97
-
98
- .atwho-view ul li .username {
99
- display: inline-block;
100
- margin: -10px 0 0 0;
101
- padding: 10px 0;
102
- }
103
-
104
- .atwho-view ul li small {
105
- display: inline-block;
106
- margin-left: 20px;
107
- }
108
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/css/mentions.min.css DELETED
@@ -1 +0,0 @@
1
- .atwho-view{background:rgba(204,204,204,.8);border-radius:2px;border:1px solid #ccc;box-shadow:0 0 5px rgba(204,204,204,.25),0 0 1px #fff;color:#d84800;display:none;font-family:sans-serif;margin-top:18px;position:absolute;top:0;z-index:1000}.atwho-view{left:0}.atwho-view ul{background:#fff;list-style:none;margin:auto;padding:0}.atwho-view ul li{border-bottom:1px solid #efefef;box-sizing:content-box;cursor:pointer;display:block;font-size:14px;height:20px;line-height:20px;margin:0;overflow:hidden;padding:5px 10px}.atwho-view img{border-radius:2px;float:right;height:20px;margin-top:0;width:20px}.atwho-view strong{background:#efefef;font-weight:700}.atwho-view .username strong{color:#d54e21}.atwho-view small{color:#aaa;float:right;font-size:smaller;font-weight:400;margin:0 10px 0 40px}.atwho-view .cur{background:rgba(239,239,239,.5)}@media (max-width:900px){.atwho-view img{float:left;margin:0 10px 0 0}}@media (max-width:400px){.atwho-view ul li{font-size:16px;line-height:23px;padding:13px}.atwho-view ul li img{height:30px;margin-top:-5px;width:30px}.atwho-view{border-radius:0;height:100%;left:0!important;width:100%}.atwho-view ul li .username{display:inline-block;margin:-10px 0 0 0;padding:10px 0}.atwho-view ul li small{display:inline-block;margin-left:20px}}
 
bp-activity/feeds/bp-activity-favorites-feed.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * RSS2 Feed Template for displaying a member's favorite activity
4
+ *
5
+ * @package BuddyPress
6
+ */
7
+ header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true);
8
+ header('Status: 200 OK');
9
+ ?>
10
+ <?php echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
11
+
12
+ <rss version="2.0"
13
+ xmlns:content="http://purl.org/rss/1.0/modules/content/"
14
+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
15
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
16
+ xmlns:atom="http://www.w3.org/2005/Atom"
17
+ <?php do_action('bp_activity_favorites_feed'); ?>
18
+ >
19
+
20
+ <channel>
21
+ <title><?php echo bp_site_name() ?> | <?php echo $bp->displayed_user->fullname; ?> | <?php _e( 'Favorite Activity', 'buddypress' ) ?></title>
22
+ <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
23
+ <link><?php echo site_url( BP_ACTIVITY_SLUG . '/#my-favorites/' ) ?></link>
24
+ <description><?php echo $bp->displayed_user->fullname; ?> - <?php _e( 'Favorite Activity', 'buddypress' ) ?></description>
25
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_activity_get_last_updated(), false); ?></pubDate>
26
+ <generator>http://buddypress.org/?v=<?php echo BP_VERSION ?></generator>
27
+ <language><?php echo get_option('rss_language'); ?></language>
28
+ <?php do_action('bp_activity_favorites_feed_head'); ?>
29
+
30
+ <?php
31
+ $favs = bp_activity_get_user_favorites( $bp->displayed_user->id );
32
+ $fav_ids = implode( ',', (array)$favs );
33
+ ?>
34
+
35
+ <?php if ( bp_has_activities( 'include=' . $fav_ids . '&max=50&display_comments=stream' ) ) : ?>
36
+ <?php while ( bp_activities() ) : bp_the_activity(); ?>
37
+ <item>
38
+ <guid><?php bp_activity_thread_permalink() ?></guid>
39
+ <title><![CDATA[<?php bp_activity_feed_item_title() ?>]]></title>
40
+ <link><?php echo bp_activity_thread_permalink() ?></link>
41
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_get_activity_feed_item_date(), false); ?></pubDate>
42
+
43
+ <description>
44
+ <![CDATA[
45
+ <?php bp_activity_feed_item_description() ?>
46
+
47
+ <?php if ( bp_activity_can_comment() ) : ?>
48
+ <p><?php printf( __( 'Comments: %s', 'buddypress' ), bp_activity_get_comment_count() ); ?></p>
49
+ <?php endif; ?>
50
+
51
+ <?php if ( 'activity_comment' == bp_get_activity_action_name() ) : ?>
52
+ <br /><strong><?php _e( 'In reply to', 'buddypress' ) ?></strong> -
53
+ <?php bp_activity_parent_content() ?>
54
+ <?php endif; ?>
55
+ ]]>
56
+ </description>
57
+ <?php do_action('bp_activity_favorites_feed_item'); ?>
58
+ </item>
59
+ <?php endwhile; ?>
60
+
61
+ <?php endif; ?>
62
+ </channel>
63
+ </rss>
bp-activity/feeds/bp-activity-friends-feed.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * RSS2 Feed Template for displaying a member's friends activity stream.
4
+ *
5
+ * @package BuddyPress
6
+ */
7
+ header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true);
8
+ header('Status: 200 OK');
9
+ ?>
10
+ <?php echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
11
+
12
+ <rss version="2.0"
13
+ xmlns:content="http://purl.org/rss/1.0/modules/content/"
14
+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
15
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
16
+ xmlns:atom="http://www.w3.org/2005/Atom"
17
+ <?php do_action('bp_activity_friends_feed'); ?>
18
+ >
19
+
20
+ <channel>
21
+ <title><?php echo bp_site_name() ?> | <?php echo $bp->displayed_user->fullname; ?> | <?php _e( 'Friends Activity', 'buddypress' ) ?></title>
22
+ <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
23
+ <link><?php echo $bp->displayed_user->domain . $bp->activity->slug . '/my-friends/feed' ?></link>
24
+ <description><?php printf( __( '%s - Friends Activity Feed', 'buddypress' ), $bp->displayed_user->fullname ) ?></description>
25
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_activity_get_last_updated(), false); ?></pubDate>
26
+ <generator>http://buddypress.org/?v=<?php echo BP_VERSION ?></generator>
27
+ <language><?php echo get_option('rss_language'); ?></language>
28
+ <?php do_action('bp_activity_friends_feed_head'); ?>
29
+
30
+ <?php $friend_ids = implode( ',', friends_get_friend_user_ids( $bp->displayed_user->id ) ); ?>
31
+ <?php if ( bp_has_activities( 'user_id=' . $friend_ids . '&max=50&display_comments=stream' ) ) : ?>
32
+ <?php while ( bp_activities() ) : bp_the_activity(); ?>
33
+ <item>
34
+ <guid><?php bp_activity_thread_permalink() ?></guid>
35
+ <title><![CDATA[<?php bp_activity_feed_item_title() ?>]]></title>
36
+ <link><?php echo bp_activity_thread_permalink() ?></link>
37
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_get_activity_feed_item_date(), false); ?></pubDate>
38
+
39
+ <description>
40
+ <![CDATA[
41
+ <?php bp_activity_feed_item_description() ?>
42
+
43
+ <?php if ( bp_activity_can_comment() ) : ?>
44
+ <p><?php printf( __( 'Comments: %s', 'buddypress' ), bp_activity_get_comment_count() ); ?></p>
45
+ <?php endif; ?>
46
+
47
+ <?php if ( 'activity_comment' == bp_get_activity_action_name() ) : ?>
48
+ <br /><strong><?php _e( 'In reply to', 'buddypress' ) ?></strong> -
49
+ <?php bp_activity_parent_content() ?>
50
+ <?php endif; ?>
51
+ ]]>
52
+ </description>
53
+ <?php do_action('bp_activity_personal_feed_item'); ?>
54
+ </item>
55
+ <?php endwhile; ?>
56
+
57
+ <?php endif; ?>
58
+ </channel>
59
+ </rss>
bp-activity/feeds/bp-activity-group-feed.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * RSS2 Feed Template for displaying a group activity stream
4
+ *
5
+ * @package BuddyPress
6
+ */
7
+ header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true);
8
+ header('Status: 200 OK');
9
+ ?>
10
+ <?php echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
11
+
12
+ <rss version="2.0"
13
+ xmlns:content="http://purl.org/rss/1.0/modules/content/"
14
+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
15
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
16
+ xmlns:atom="http://www.w3.org/2005/Atom"
17
+ <?php do_action('bp_activity_group_feed'); ?>
18
+ >
19
+
20
+ <channel>
21
+ <title><?php echo bp_site_name() ?> | <?php echo $bp->groups->current_group->name ?> | <?php _e( 'Group Activity', 'buddypress' ) ?></title>
22
+ <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
23
+ <link><?php echo bp_get_group_permalink( $bp->groups->current_group ) . $bp->activity->slug . '/feed' ?></link>
24
+ <description><?php printf( __( '%s - Group Activity Feed', 'buddypress' ), $bp->groups->current_group->name ) ?></description>
25
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_activity_get_last_updated(), false); ?></pubDate>
26
+ <generator>http://buddypress.org/?v=<?php echo BP_VERSION ?></generator>
27
+ <language><?php echo get_option('rss_language'); ?></language>
28
+ <?php do_action('bp_activity_group_feed_head'); ?>
29
+
30
+ <?php if ( bp_has_activities( 'object=' . $bp->groups->id . '&primary_id=' . $bp->groups->current_group->id . '&max=50&display_comments=threaded' ) ) : ?>
31
+ <?php while ( bp_activities() ) : bp_the_activity(); ?>
32
+ <item>
33
+ <guid><?php bp_activity_thread_permalink() ?></guid>
34
+ <title><![CDATA[<?php bp_activity_feed_item_title() ?>]]></title>
35
+ <link><?php echo bp_activity_thread_permalink() ?></link>
36
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_get_activity_feed_item_date(), false); ?></pubDate>
37
+
38
+ <description>
39
+ <![CDATA[
40
+ <?php bp_activity_feed_item_description() ?>
41
+
42
+ <?php if ( bp_activity_can_comment() ) : ?>
43
+ <p><?php printf( __( 'Comments: %s', 'buddypress' ), bp_activity_get_comment_count() ); ?></p>
44
+ <?php endif; ?>
45
+ ]]>
46
+ </description>
47
+ <?php do_action('bp_activity_group_feed_item'); ?>
48
+ </item>
49
+ <?php endwhile; ?>
50
+
51
+ <?php endif; ?>
52
+ </channel>
53
+ </rss>
bp-activity/feeds/bp-activity-mentions-feed.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * RSS2 Feed Template for displaying a member's group's activity
4
+ *
5
+ * @package BuddyPress
6
+ */
7
+ header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true);
8
+ header('Status: 200 OK');
9
+ ?>
10
+ <?php echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
11
+
12
+ <rss version="2.0"
13
+ xmlns:content="http://purl.org/rss/1.0/modules/content/"
14
+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
15
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
16
+ xmlns:atom="http://www.w3.org/2005/Atom"
17
+ <?php do_action('bp_activity_mentions_feed'); ?>
18
+ >
19
+
20
+ <channel>
21
+ <title><?php echo bp_site_name() ?> | <?php echo $bp->displayed_user->fullname; ?> | <?php _e( 'Mentions', 'buddypress' ) ?></title>
22
+ <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
23
+ <link><?php echo site_url( BP_ACTIVITY_SLUG . '/#mentions/' ) ?></link>
24
+ <description><?php echo $bp->displayed_user->fullname; ?> - <?php _e( 'Mentions', 'buddypress' ) ?></description>
25
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_activity_get_last_updated(), false); ?></pubDate>
26
+ <generator>http://buddypress.org/?v=<?php echo BP_VERSION ?></generator>
27
+ <language><?php echo get_option('rss_language'); ?></language>
28
+ <?php do_action('bp_activity_mentions_feed_head'); ?>
29
+
30
+ <?php if ( bp_has_activities( 'max=50&display_comments=stream&search_terms=@' . bp_core_get_username( $bp->displayed_user->id, $bp->displayed_user->userdata->user_nicename, $bp->displayed_user->userdata->user_login ) ) ) : ?>
31
+ <?php while ( bp_activities() ) : bp_the_activity(); ?>
32
+ <item>
33
+ <guid><?php bp_activity_thread_permalink() ?></guid>
34
+ <title><![CDATA[<?php bp_activity_feed_item_title() ?>]]></title>
35
+ <link><?php echo bp_activity_thread_permalink() ?></link>
36
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_get_activity_feed_item_date(), false); ?></pubDate>
37
+
38
+ <description>
39
+ <![CDATA[
40
+ <?php bp_activity_feed_item_description() ?>
41
+
42
+ <?php if ( bp_activity_can_comment() ) : ?>
43
+ <p><?php printf( __( 'Comments: %s', 'buddypress' ), bp_activity_get_comment_count() ); ?></p>
44
+ <?php endif; ?>
45
+
46
+ <?php if ( 'activity_comment' == bp_get_activity_action_name() ) : ?>
47
+ <br /><strong><?php _e( 'In reply to', 'buddypress' ) ?></strong> -
48
+ <?php bp_activity_parent_content() ?>
49
+ <?php endif; ?>
50
+ ]]>
51
+ </description>
52
+ <?php do_action('bp_activity_mentions_feed_item'); ?>
53
+ </item>
54
+ <?php endwhile; ?>
55
+
56
+ <?php endif; ?>
57
+ </channel>
58
+ </rss>
bp-activity/feeds/bp-activity-mygroups-feed.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * RSS2 Feed Template for displaying a member's group's activity
4
+ *
5
+ * @package BuddyPress
6
+ */
7
+ header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true);
8
+ header('Status: 200 OK');
9
+ ?>
10
+ <?php echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
11
+
12
+ <rss version="2.0"
13
+ xmlns:content="http://purl.org/rss/1.0/modules/content/"
14
+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
15
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
16
+ xmlns:atom="http://www.w3.org/2005/Atom"
17
+ <?php do_action('bp_activity_mygroups_feed'); ?>
18
+ >
19
+
20
+ <channel>
21
+ <title><?php echo bp_site_name() ?> | <?php echo $bp->displayed_user->fullname; ?> | <?php _e( 'My Groups - Public Activity', 'buddypress' ) ?></title>
22
+ <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
23
+ <link><?php echo site_url( BP_ACTIVITY_SLUG . '/#my-groups/' ) ?></link>
24
+ <description><?php echo $bp->displayed_user->fullname; ?> - <?php _e( 'My Groups - Public Activity', 'buddypress' ) ?></description>
25
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_activity_get_last_updated(), false); ?></pubDate>
26
+ <generator>http://buddypress.org/?v=<?php echo BP_VERSION ?></generator>
27
+ <language><?php echo get_option('rss_language'); ?></language>
28
+ <?php do_action('bp_activity_mygroups_feed_head'); ?>
29
+
30
+ <?php
31
+ $groups = groups_get_user_groups( $bp->loggedin_user->id );
32
+ $group_ids = implode( ',', $groups['groups'] );
33
+ ?>
34
+
35
+ <?php if ( bp_has_activities( 'object=' . $bp->groups->id . '&primary_id=' . $group_ids . '&max=50&display_comments=threaded' ) ) : ?>
36
+ <?php while ( bp_activities() ) : bp_the_activity(); ?>
37
+ <item>
38
+ <guid><?php bp_activity_thread_permalink() ?></guid>
39
+ <title><![CDATA[<?php bp_activity_feed_item_title() ?>]]></title>
40
+ <link><?php echo bp_activity_thread_permalink() ?></link>
41
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_get_activity_feed_item_date(), false); ?></pubDate>
42
+
43
+ <description>
44
+ <![CDATA[
45
+ <?php bp_activity_feed_item_description() ?>
46
+
47
+ <?php if ( bp_activity_can_comment() ) : ?>
48
+ <p><?php printf( __( 'Comments: %s', 'buddypress' ), bp_activity_get_comment_count() ); ?></p>
49
+ <?php endif; ?>
50
+ ]]>
51
+ </description>
52
+ <?php do_action('bp_activity_mygroups_feed_item'); ?>
53
+ </item>
54
+ <?php endwhile; ?>
55
+
56
+ <?php endif; ?>
57
+ </channel>
58
+ </rss>
bp-activity/feeds/bp-activity-personal-feed.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * RSS2 Feed Template for displaying a member's activity stream.
4
+ *
5
+ * @package BuddyPress
6
+ */
7
+ header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true);
8
+ header('Status: 200 OK');
9
+ ?>
10
+ <?php echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
11
+
12
+ <rss version="2.0"
13
+ xmlns:content="http://purl.org/rss/1.0/modules/content/"
14
+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
15
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
16
+ xmlns:atom="http://www.w3.org/2005/Atom"
17
+ <?php do_action('bp_activity_personal_feed'); ?>
18
+ >
19
+
20
+ <channel>
21
+ <title><?php echo bp_site_name() ?> | <?php echo $bp->displayed_user->fullname; ?> | <?php _e( 'Activity', 'buddypress' ) ?></title>
22
+ <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
23
+ <link><?php echo $bp->displayed_user->domain . $bp->activity->slug . '/feed' ?></link>
24
+ <description><?php printf( __( '%s - Activity Feed', 'buddypress' ), $bp->displayed_user->fullname ) ?></description>
25
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_activity_get_last_updated(), false); ?></pubDate>
26
+ <generator>http://buddypress.org/?v=<?php echo BP_VERSION ?></generator>
27
+ <language><?php echo get_option('rss_language'); ?></language>
28
+ <?php do_action('bp_activity_personal_feed_head'); ?>
29
+
30
+ <?php if ( bp_has_activities( 'user_id=' . $bp->displayed_user->id . '&max=50&display_comments=stream' ) ) : ?>
31
+ <?php while ( bp_activities() ) : bp_the_activity(); ?>
32
+ <item>
33
+ <guid><?php bp_activity_thread_permalink() ?></guid>
34
+ <title><![CDATA[<?php bp_activity_feed_item_title() ?>]]></title>
35
+ <link><?php echo bp_activity_thread_permalink() ?></link>
36
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_get_activity_feed_item_date(), false); ?></pubDate>
37
+
38
+ <description>
39
+ <![CDATA[
40
+ <?php bp_activity_feed_item_description() ?>
41
+
42
+ <?php if ( bp_activity_can_comment() ) : ?>
43
+ <p><?php printf( __( 'Comments: %s', 'buddypress' ), bp_activity_get_comment_count() ); ?></p>
44
+ <?php endif; ?>
45
+
46
+ <?php if ( 'activity_comment' == bp_get_activity_action_name() ) : ?>
47
+ <br /><strong><?php _e( 'In reply to', 'buddypress' ) ?></strong> -
48
+ <?php bp_activity_parent_content() ?>
49
+ <?php endif; ?>
50
+ ]]>
51
+ </description>
52
+ <?php do_action('bp_activity_personal_feed_item'); ?>
53
+ </item>
54
+ <?php endwhile; ?>
55
+
56
+ <?php endif; ?>
57
+ </channel>
58
+ </rss>
bp-activity/feeds/bp-activity-sitewide-feed.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * RSS2 Feed Template for displaying the site wide activity stream.
4
+ *
5
+ * @package BuddyPress
6
+ */
7
+
8
+ header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true);
9
+ header('Status: 200 OK');
10
+ ?>
11
+ <?php echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
12
+
13
+ <rss version="2.0"
14
+ xmlns:content="http://purl.org/rss/1.0/modules/content/"
15
+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
16
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
17
+ xmlns:atom="http://www.w3.org/2005/Atom"
18
+ <?php do_action('bp_activity_sitewide_feed'); ?>
19
+ >
20
+
21
+ <channel>
22
+ <title><?php echo bp_site_name() ?> | <?php _e( 'Site Wide Activity', 'buddypress' ) ?></title>
23
+ <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
24
+ <link><?php echo site_url() . '/' . $bp->activity->slug . '/feed' ?></link>
25
+ <description><?php _e( 'Site Wide Activity Feed', 'buddypress' ) ?></description>
26
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_activity_get_last_updated(), false); ?></pubDate>
27
+ <generator>http://buddypress.org/?v=<?php echo BP_VERSION ?></generator>
28
+ <language><?php echo get_option('rss_language'); ?></language>
29
+ <?php do_action('bp_activity_sitewide_feed_head'); ?>
30
+
31
+ <?php if ( bp_has_activities( 'type=sitewide&max=50&display_comments=threaded' ) ) : ?>
32
+ <?php while ( bp_activities() ) : bp_the_activity(); ?>
33
+ <item>
34
+ <guid><?php bp_activity_thread_permalink() ?></guid>
35
+ <title><![CDATA[<?php bp_activity_feed_item_title() ?>]]></title>
36
+ <link><?php bp_activity_thread_permalink() ?></link>
37
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_get_activity_feed_item_date(), false); ?></pubDate>
38
+
39
+ <description>
40
+ <![CDATA[
41
+ <?php bp_activity_feed_item_description() ?>
42
+
43
+ <?php if ( bp_activity_can_comment() ) : ?>
44
+ <p><?php printf( __( 'Comments: %s', 'buddypress' ), bp_activity_get_comment_count() ); ?></p>
45
+ <?php endif; ?>
46
+ ]]>
47
+ </description>
48
+ <?php do_action('bp_activity_personal_feed_item'); ?>
49
+ </item>
50
+ <?php endwhile; ?>
51
+
52
+ <?php endif; ?>
53
+ </channel>
54
+ </rss>
bp-activity/js/mentions.js DELETED
@@ -1,255 +0,0 @@
1
- /* global bp */
2
-
3
- window.bp = window.bp || {};
4
-
5
- ( function( bp, $, undefined ) {
6
- var mentionsQueryCache = [],
7
- mentionsItem;
8
-
9
- bp.mentions = bp.mentions || {};
10
- bp.mentions.users = window.bp.mentions.users || [];
11
-
12
- if ( typeof window.BP_Suggestions === 'object' ) {
13
- bp.mentions.users = window.BP_Suggestions.friends || bp.mentions.users;
14
- }
15
-
16
- /**
17
- * Adds BuddyPress @mentions to form inputs.
18
- *
19
- * @param {array|object} options If array, becomes the suggestions' data source. If object, passed as config to $.atwho().
20
- * @since 2.1.0
21
- */
22
- $.fn.bp_mentions = function( options ) {
23
- if ( $.isArray( options ) ) {
24
- options = { data: options };
25
- }
26
-
27
- /**
28
- * Default options for at.js; see https://github.com/ichord/At.js/.
29
- */
30
- var suggestionsDefaults = {
31
- delay: 200,
32
- hide_without_suffix: true,
33
- insert_tpl: '</>${atwho-data-value}</>', // For contentEditable, the fake tags make jQuery insert a textNode.
34
- limit: 10,
35
- start_with_space: false,
36
- suffix: '',
37
-
38
- callbacks: {
39
- /**
40
- * Custom filter to only match the start of spaced words.
41
- * Based on the core/default one.
42
- *
43
- * @param {string} query
44
- * @param {array} data
45
- * @param {string} search_key
46
- * @return {array}
47
- * @since 2.1.0
48
- */
49
- filter: function( query, data, search_key ) {
50
- var item, _i, _len, _results = [],
51
- regxp = new RegExp( '^' + query + '| ' + query, 'ig' ); // start of string, or preceded by a space.
52
-
53
- for ( _i = 0, _len = data.length; _i < _len; _i++ ) {
54
- item = data[ _i ];
55
- if ( item[ search_key ].toLowerCase().match( regxp ) ) {
56
- _results.push( item );
57
- }
58
- }
59
-
60
- return _results;
61
- },
62
-
63
- /**
64
- * Removes some spaces around highlighted string and tweaks regex to allow spaces
65
- * (to match display_name). Based on the core default.
66
- *
67
- * @param {unknown} li
68
- * @param {string} query
69
- * @return {string}
70
- * @since 2.1.0
71
- */
72
- highlighter: function( li, query ) {
73
- if ( ! query ) {
74
- return li;
75
- }
76
-
77
- var regexp = new RegExp( '>(\\s*|[\\w\\s]*)(' + this.at.replace( '+', '\\+') + '?' + query.replace( '+', '\\+' ) + ')([\\w ]*)\\s*<', 'ig' );
78
- return li.replace( regexp, function( str, $1, $2, $3 ) {
79
- return '>' + $1 + '<strong>' + $2 + '</strong>' + $3 + '<';
80
- });
81
- },
82
-
83
- /**
84
- * Reposition the suggestion list dynamically.
85
- *
86
- * @param {unknown} offset
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,
94
- move,
95
- $view = $( '#atwho-ground-' + this.id + ' .atwho-view' ),
96
- $body = $( 'body' ),
97
- atwhoDataValue = this.$inputor.data( 'atwho' );
98
-
99
- if ( 'undefined' !== atwhoDataValue && 'undefined' !== atwhoDataValue.iframe && null !== atwhoDataValue.iframe ) {
100
- caret = this.$inputor.caret( 'offset', { iframe: atwhoDataValue.iframe } );
101
- // Caret.js no longer calculates iframe caret position from the window (it's now just within the iframe).
102
- // We need to get the iframe offset from the window and merge that into our object.
103
- iframeOffset = $( atwhoDataValue.iframe ).offset();
104
- if ( 'undefined' !== iframeOffset ) {
105
- caret.left += iframeOffset.left;
106
- caret.top += iframeOffset.top;
107
- }
108
- } else {
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();
116
- } else {
117
- $view.removeClass( 'right' );
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
-
133
- offset.top = caret.top + line;
134
- offset.left += move;
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
- */
146
- inserting_wrapper: function( $inputor, content, suffix ) {
147
- return '' + content + suffix;
148
- }
149
- }
150
- },
151
-
152
- /**
153
- * Default options for our @mentions; see https://github.com/ichord/At.js/.
154
- */
155
- mentionsDefaults = {
156
- callbacks: {
157
- /**
158
- * If there are no matches for the query in this.data, then query BuddyPress.
159
- *
160
- * @param {string} query Partial @mention to search for.
161
- * @param {function} render_view Render page callback function.
162
- * @since 2.1.0
163
- */
164
- remote_filter: function( query, render_view ) {
165
- var self = $( this ),
166
- params = {};
167
-
168
- mentionsItem = mentionsQueryCache[ query ];
169
- if ( typeof mentionsItem === 'object' ) {
170
- render_view( mentionsItem );
171
- return;
172
- }
173
-
174
- if ( self.xhr ) {
175
- self.xhr.abort();
176
- }
177
-
178
- params = { 'action': 'bp_get_suggestions', 'term': query, 'type': 'members' };
179
-
180
- if ( $.isNumeric( this.$inputor.data( 'suggestions-group-id' ) ) ) {
181
- params['group-id'] = parseInt( this.$inputor.data( 'suggestions-group-id' ), 10 );
182
- }
183
-
184
- self.xhr = $.getJSON( ajaxurl, params )
185
- /**
186
- * Success callback for the @suggestions lookup.
187
- *
188
- * @param {object} response Details of users matching the query.
189
- * @since 2.1.0
190
- */
191
- .done(function( response ) {
192
- if ( ! response.success ) {
193
- return;
194
- }
195
-
196
- var data = $.map( response.data,
197
- /**
198
- * Create a composite index to determine ordering of results;
199
- * nicename matches will appear on top.
200
- *
201
- * @param {array} suggestion A suggestion's original data.
202
- * @return {array} A suggestion's new data.
203
- * @since 2.1.0
204
- */
205
- function( suggestion ) {
206
- suggestion.search = suggestion.search || suggestion.ID + ' ' + suggestion.name;
207
- return suggestion;
208
- }
209
- );
210
-
211
- mentionsQueryCache[ query ] = data;
212
- render_view( data );
213
- });
214
- }
215
- },
216
-
217
- data: $.map( options.data,
218
- /**
219
- * Create a composite index to search against of nicename + display name.
220
- * This will also determine ordering of results, so nicename matches will appear on top.
221
- *
222
- * @param {array} suggestion A suggestion's original data.
223
- * @return {array} A suggestion's new data.
224
- * @since 2.1.0
225
- */
226
- function( suggestion ) {
227
- suggestion.search = suggestion.search || suggestion.ID + ' ' + suggestion.name;
228
- return suggestion;
229
- }
230
- ),
231
-
232
- at: '@',
233
- search_key: 'search',
234
- tpl: '<li data-value="@${ID}"><img src="${image}" /><span class="username">@${ID}</span><small>${name}</small></li>'
235
- },
236
-
237
- opts = $.extend( true, {}, suggestionsDefaults, mentionsDefaults, options );
238
- return $.fn.atwho.call( this, opts );
239
- };
240
-
241
- $( document ).ready(function() {
242
- // Activity/reply, post comments, dashboard post 'text' editor.
243
- $( '.bp-suggestions, #comments form textarea, .wp-editor-area' ).bp_mentions( bp.mentions.users );
244
- });
245
-
246
- bp.mentions.tinyMCEinit = function() {
247
- if ( typeof window.tinyMCE === 'undefined' || window.tinyMCE.activeEditor === null || typeof window.tinyMCE.activeEditor === 'undefined' ) {
248
- return;
249
- } else {
250
- $( window.tinyMCE.activeEditor.contentDocument.activeElement )
251
- .atwho( 'setIframe', $( '.wp-editor-wrap iframe' )[0] )
252
- .bp_mentions( bp.mentions.users );
253
- }
254
- };
255
- })( bp, jQuery );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/js/mentions.min.js DELETED
@@ -1 +0,0 @@
1
- window.bp=window.bp||{},function(t,e,i){var n,s=[];t.mentions=t.mentions||{},t.mentions.users=window.bp.mentions.users||[],"object"==typeof window.BP_Suggestions&&(t.mentions.users=window.BP_Suggestions.friends||t.mentions.users),e.fn.bp_mentions=function(t){e.isArray(t)&&(t={data:t});var i={delay:200,hide_without_suffix:!0,insert_tpl:"</>${atwho-data-value}</>",limit:10,start_with_space:!1,suffix:"",callbacks:{filter:function(t,e,i){var n,s,r,o=[],a=new RegExp("^"+t+"| "+t,"ig");for(s=0,r=e.length;s<r;s++)(n=e[s])[i].toLowerCase().match(a)&&o.push(n);return o},highlighter:function(t,e){if(!e)return t;var i=new RegExp(">(\\s*|[\\w\\s]*)("+this.at.replace("+","\\+")+"?"+e.replace("+","\\+")+")([\\w ]*)\\s*<","ig");return t.replace(i,function(t,e,i,n){return">"+e+"<strong>"+i+"</strong>"+n+"<"})},before_reposition:function(t){var i,n,s,r,o=e("#atwho-ground-"+this.id+" .atwho-view"),a=e("body"),u=this.$inputor.data("atwho");"undefined"!==u&&"undefined"!==u.iframe&&null!==u.iframe?(i=this.$inputor.caret("offset",{iframe:u.iframe}),"undefined"!==(s=e(u.iframe).offset())&&(i.left+=s.left,i.top+=s.top)):i=this.$inputor.caret("offset"),i.left>a.width()/2?(o.addClass("right"),r=i.left-t.left-this.view.$el.width()):(o.removeClass("right"),r=i.left-t.left+1),a.width()<=400&&e(document).scrollTop(i.top-6),(!(n=parseInt(this.$inputor.css("line-height").substr(0,this.$inputor.css("line-height").length-2),10))||n<5)&&(n=19),t.top=i.top+n,t.left+=r},inserting_wrapper:function(t,e,i){return""+e+i}}},r={callbacks:{remote_filter:function(t,i){var r=e(this),o={};"object"!=typeof(n=s[t])?(r.xhr&&r.xhr.abort(),o={action:"bp_get_suggestions",term:t,type:"members"},e.isNumeric(this.$inputor.data("suggestions-group-id"))&&(o["group-id"]=parseInt(this.$inputor.data("suggestions-group-id"),10)),r.xhr=e.getJSON(ajaxurl,o).done(function(n){if(n.success){var r=e.map(n.data,function(t){return t.search=t.search||t.ID+" "+t.name,t});s[t]=r,i(r)}})):i(n)}},data:e.map(t.data,function(t){return t.search=t.search||t.ID+" "+t.name,t}),at:"@",search_key:"search",tpl:'<li data-value="@${ID}"><img src="${image}" /><span class="username">@${ID}</span><small>${name}</small></li>'},o=e.extend(!0,{},i,r,t);return e.fn.atwho.call(this,o)},e(document).ready(function(){e(".bp-suggestions, #comments form textarea, .wp-editor-area").bp_mentions(t.mentions.users)}),t.mentions.tinyMCEinit=function(){void 0!==window.tinyMCE&&null!==window.tinyMCE.activeEditor&&void 0!==window.tinyMCE.activeEditor&&e(window.tinyMCE.activeEditor.contentDocument.activeElement).atwho("setIframe",e(".wp-editor-wrap iframe")[0]).bp_mentions(t.mentions.users)}}(bp,jQuery);
 
bp-blogs.php ADDED
@@ -0,0 +1,821 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ define ( 'BP_BLOGS_DB_VERSION', '2015' );
4
+
5
+ /* Define the slug for the component */
6
+ if ( !defined( 'BP_BLOGS_SLUG' ) )
7
+ define ( 'BP_BLOGS_SLUG', 'blogs' );
8
+
9
+ require ( BP_PLUGIN_DIR . '/bp-blogs/bp-blogs-classes.php' );
10
+ require ( BP_PLUGIN_DIR . '/bp-blogs/bp-blogs-templatetags.php' );
11
+
12
+ /* Include the sitewide blog posts widget if this is a multisite installation */
13
+ if ( bp_core_is_multisite() )
14
+ require ( BP_PLUGIN_DIR . '/bp-blogs/bp-blogs-widgets.php' );
15
+
16
+ function bp_blogs_install() {
17
+ global $wpdb, $bp;
18
+
19
+ if ( !empty($wpdb->charset) )
20
+ $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
21
+
22
+ $sql[] = "CREATE TABLE {$bp->blogs->table_name} (
23
+ id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
24
+ user_id bigint(20) NOT NULL,
25
+ blog_id bigint(20) NOT NULL,
26
+ KEY user_id (user_id),
27
+ KEY blog_id (blog_id)
28
+ ) {$charset_collate};";
29
+
30
+ $sql[] = "CREATE TABLE {$bp->blogs->table_name_blogmeta} (
31
+ id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
32
+ blog_id bigint(20) NOT NULL,
33
+ meta_key varchar(255) DEFAULT NULL,
34
+ meta_value longtext DEFAULT NULL,
35
+ KEY blog_id (blog_id),
36
+ KEY meta_key (meta_key)
37
+ ) {$charset_collate};";
38
+
39
+
40
+ require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
41
+
42
+ dbDelta($sql);
43
+
44
+ // On first installation - record all existing blogs in the system.
45
+ if ( !(int)get_site_option('bp-blogs-first-install') && bp_core_is_multisite() ) {
46
+ bp_blogs_record_existing_blogs();
47
+ add_site_option( 'bp-blogs-first-install', 1 );
48
+ }
49
+
50
+ update_site_option( 'bp-blogs-db-version', BP_BLOGS_DB_VERSION );
51
+ }
52
+
53
+ function bp_blogs_check_installed() {
54
+ global $wpdb, $bp, $userdata;
55
+
56
+ /* Only create the bp-blogs tables if this is a multisite install */
57
+ if ( is_super_admin() && bp_core_is_multisite() ) {
58
+ /* Need to check db tables exist, activate hook no-worky in mu-plugins folder. */
59
+ if ( get_site_option( 'bp-blogs-db-version' ) < BP_BLOGS_DB_VERSION )
60
+ bp_blogs_install();
61
+ }
62
+ }
63
+ add_action( is_multisite() ? 'network_admin_menu' : 'admin_menu', 'bp_blogs_check_installed' );
64
+
65
+ function bp_blogs_setup_globals() {
66
+ global $bp, $wpdb;
67
+
68
+ /* For internal identification */
69
+ $bp->blogs->id = 'blogs';
70
+
71
+ $bp->blogs->slug = BP_BLOGS_SLUG;
72
+
73
+ $bp->blogs->table_name = $bp->table_prefix . 'bp_user_blogs';
74
+ $bp->blogs->table_name_blogmeta = $bp->table_prefix . 'bp_user_blogs_blogmeta';
75
+
76
+ $bp->blogs->format_notification_function = 'bp_blogs_format_notifications';
77
+
78
+ /* Register this in the active components array */
79
+ $bp->active_components[$bp->blogs->slug] = $bp->blogs->id;
80
+
81
+ do_action( 'bp_blogs_setup_globals' );
82
+ }
83
+ add_action( 'bp_setup_globals', 'bp_blogs_setup_globals' );
84
+
85
+ function bp_blogs_setup_root_component() {
86
+ /* Register 'blogs' as a root component */
87
+ bp_core_add_root_component( BP_BLOGS_SLUG );
88
+ }
89
+ add_action( 'bp_setup_root_components', 'bp_blogs_setup_root_component' );
90
+
91
+ /**
92
+ * bp_blogs_setup_nav()
93
+ *
94
+ * Adds "Blog" to the navigation arrays for the current and logged in user.
95
+ *
96
+ * @package BuddyPress Blogs
97
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
98
+ * @uses bp_is_my_profile() Checks to see if the current user being viewed is the logged in user
99
+ */
100
+ function bp_blogs_setup_nav() {
101
+ global $bp;
102
+
103
+ /* Blog/post/comment menus should not appear on single WordPress setups. Although comments
104
+ and posts made by users will still show on their activity stream .*/
105
+ if ( !bp_core_is_multisite() )
106
+ return false;
107
+
108
+ /* Add 'Blogs' to the main navigation */
109
+ bp_core_new_nav_item( array( 'name' => sprintf( __( 'Blogs <span>(%d)</span>', 'buddypress' ), bp_blogs_total_blogs_for_user() ), 'slug' => $bp->blogs->slug, 'position' => 30, 'screen_function' => 'bp_blogs_screen_my_blogs', 'default_subnav_slug' => 'my-blogs', 'item_css_id' => $bp->blogs->id ) );
110
+
111
+ $blogs_link = $bp->loggedin_user->domain . $bp->blogs->slug . '/';
112
+
113
+ /* Set up the component options navigation for Blog */
114
+ if ( 'blogs' == $bp->current_component ) {
115
+ if ( bp_is_my_profile() ) {
116
+ if ( function_exists('xprofile_setup_nav') ) {
117
+ $bp->bp_options_title = __('My Blogs', 'buddypress');
118
+ }
119
+ } else {
120
+ /* If we are not viewing the logged in user, set up the current users avatar and name */
121
+ $bp->bp_options_avatar = bp_core_fetch_avatar( array( 'item_id' => $bp->displayed_user->id, 'type' => 'thumb' ) );
122
+ $bp->bp_options_title = $bp->displayed_user->fullname;
123
+ }
124
+ }
125
+
126
+ do_action( 'bp_blogs_setup_nav' );
127
+ }
128
+ add_action( 'bp_setup_nav', 'bp_blogs_setup_nav' );
129
+
130
+ function bp_blogs_directory_blogs_setup() {
131
+ global $bp;
132
+
133
+ if ( bp_core_is_multisite() && $bp->current_component == $bp->blogs->slug && empty( $bp->current_action ) ) {
134
+ $bp->is_directory = true;
135
+
136
+ do_action( 'bp_blogs_directory_blogs_setup' );
137
+ bp_core_load_template( apply_filters( 'bp_blogs_template_directory_blogs_setup', 'blogs/index' ) );
138
+ }
139
+ }
140
+ add_action( 'wp', 'bp_blogs_directory_blogs_setup', 2 );
141
+
142
+
143
+ /********************************************************************************
144
+ * Screen Functions
145
+ *
146
+ * Screen functions are the controllers of BuddyPress. They will execute when their
147
+ * specific URL is caught. They will first save or manipulate data using business
148
+ * functions, then pass on the user to a template file.
149
+ */
150
+
151
+ function bp_blogs_screen_my_blogs() {
152
+ global $bp;
153
+
154
+ if ( !bp_core_is_multisite() )
155
+ return false;
156
+
157
+ do_action( 'bp_blogs_screen_my_blogs' );
158
+ bp_core_load_template( apply_filters( 'bp_blogs_template_my_blogs', 'members/single/home' ) );
159
+ }
160
+
161
+ function bp_blogs_screen_create_a_blog() {
162
+ global $bp;
163
+
164
+ if ( !bp_core_is_multisite() || $bp->current_component != $bp->blogs->slug || 'create' != $bp->current_action )
165
+ return false;
166
+
167
+ if ( !is_user_logged_in() || !bp_blog_signup_enabled() )
168
+ return false;
169
+
170
+ do_action( 'bp_blogs_screen_create_a_blog' );
171
+ bp_core_load_template( apply_filters( 'bp_blogs_template_create_a_blog', 'blogs/create' ) );
172
+ }
173
+ /* The create screen is not attached to a nav item, so we need to attach it to an action */
174
+ add_action( 'wp', 'bp_blogs_screen_create_a_blog', 3 );
175
+
176
+
177
+ /********************************************************************************
178
+ * Activity & Notification Functions
179
+ *
180
+ * These functions handle the recording, deleting and formatting of activity and
181
+ * notifications for the user and for this specific component.
182
+ */
183
+
184
+ function bp_blogs_register_activity_actions() {
185
+ global $bp;
186
+
187
+ if ( !function_exists( 'bp_activity_set_action' ) )
188
+ return false;
189
+
190
+ bp_activity_set_action( $bp->blogs->id, 'new_blog', __( 'New blog created', 'buddypress' ) );
191
+ bp_activity_set_action( $bp->blogs->id, 'new_blog_post', __( 'New blog post published', 'buddypress' ) );
192
+ bp_activity_set_action( $bp->blogs->id, 'new_blog_comment', __( 'New blog post comment posted', 'buddypress' ) );
193
+
194
+ do_action( 'bp_blogs_register_activity_actions' );
195
+ }
196
+ add_action( 'bp_register_activity_actions', 'bp_blogs_register_activity_actions' );
197
+
198
+ function bp_blogs_record_activity( $args = '' ) {
199
+ global $bp;
200
+
201
+ if ( !function_exists( 'bp_activity_add' ) )
202
+ return false;
203
+
204
+ /* Because blog, comment, and blog post code execution happens before anything else
205
+ we may need to manually instantiate the activity component globals */
206
+ if ( !$bp->activity && function_exists('bp_activity_setup_globals') )
207
+ bp_activity_setup_globals();
208
+
209
+ $defaults = array(
210
+ 'user_id' => $bp->loggedin_user->id,
211
+ 'action' => '',
212
+ 'content' => '',
213
+ 'primary_link' => '',
214
+ 'component' => $bp->blogs->id,
215
+ 'type' => false,
216
+ 'item_id' => false,
217
+ 'secondary_item_id' => false,
218
+ 'recorded_time' => bp_core_current_time(),
219
+ 'hide_sitewide' => false
220
+ );
221
+
222
+ $r = wp_parse_args( $args, $defaults );
223
+ extract( $r, EXTR_SKIP );
224
+
225
+ /* Remove large images and replace them with just one image thumbnail */
226
+ if ( function_exists( 'bp_activity_thumbnail_content_images' ) && !empty( $content ) )
227
+ $content = bp_activity_thumbnail_content_images( $content );
228
+
229
+ if ( !empty( $action ) )
230
+ $action = apply_filters( 'bp_blogs_record_activity_action', $action );
231
+
232
+ if ( !empty( $content ) )
233
+ $content = apply_filters( 'bp_blogs_record_activity_content', bp_create_excerpt( $content ), $content );
234
+
235
+ /* Check for an existing entry and update if one exists. */
236
+ $id = bp_activity_get_activity_id( array(
237
+ 'user_id' => $user_id,
238
+ 'component' => $component,
239
+ 'type' => $type,
240
+ 'item_id' => $item_id,
241
+ 'secondary_item_id' => $secondary_item_id
242
+ ) );
243
+
244
+ return bp_activity_add( array( 'id' => $id, 'user_id' => $user_id, 'action' => $action, 'content' => $content, 'primary_link' => $primary_link, 'component' => $component, 'type' => $type, 'item_id' => $item_id, 'secondary_item_id' => $secondary_item_id, 'recorded_time' => $recorded_time, 'hide_sitewide' => $hide_sitewide ) );
245
+ }
246
+
247
+ function bp_blogs_delete_activity( $args = true ) {
248
+ global $bp;
249
+
250
+ if ( function_exists('bp_activity_delete_by_item_id') ) {
251
+ $defaults = array(
252
+ 'item_id' => false,
253
+ 'component' => $bp->blogs->id,
254
+ 'type' => false,
255
+ 'user_id' => false,
256
+ 'secondary_item_id' => false
257
+ );
258
+
259
+ $params = wp_parse_args( $args, $defaults );
260
+ extract( $params, EXTR_SKIP );
261
+
262
+ bp_activity_delete_by_item_id( array(
263
+ 'item_id' => $item_id,
264
+ 'component' => $component,
265
+ 'type' => $type,
266
+ 'user_id' => $user_id,
267
+ 'secondary_item_id' => $secondary_item_id
268
+ ) );
269
+ }
270
+ }
271
+
272
+ /********************************************************************************
273
+ * Business Functions
274
+ *
275
+ * Business functions are where all the magic happens in BuddyPress. They will
276
+ * handle the actual saving or manipulation of information. Usually they will
277
+ * hand off to a database class for data access, then return
278
+ * true or false on success or failure.
279
+ */
280
+
281
+ function bp_blogs_get_blogs( $args = '' ) {
282
+ global $bp;
283
+
284
+ $defaults = array(
285
+ 'type' => 'active', // active, alphabetical, newest, or random.
286
+ 'user_id' => false, // Pass a user_id to limit to only blogs that this user has privilages higher than subscriber on.
287
+ 'search_terms' => false, // Limit to blogs that match these search terms
288
+
289
+ 'per_page' => 20, // The number of results to return per page
290
+ 'page' => 1, // The page to return if limiting per page
291
+ );
292
+
293
+ $params = wp_parse_args( $args, $defaults );
294
+ extract( $params, EXTR_SKIP );
295
+
296
+ return apply_filters( 'bp_blogs_get_blogs', BP_Blogs_Blog::get( $type, $per_page, $page, $user_id, $search_terms ), &$params );
297
+ }
298
+
299
+ function bp_blogs_record_existing_blogs() {
300
+ global $bp, $wpdb;
301
+
302
+ /* Truncate user blogs table and re-record. */
303
+ $wpdb->query( "TRUNCATE TABLE {$bp->blogs->table_name}" );
304
+
305
+ $blog_ids = $wpdb->get_col( $wpdb->prepare( "SELECT blog_id FROM {$wpdb->base_prefix}blogs WHERE mature = 0 AND spam = 0 AND deleted = 0" ) );
306
+
307
+ if ( $blog_ids ) {
308
+ foreach( (array)$blog_ids as $blog_id ) {
309
+ $users = get_users_of_blog( $blog_id );
310
+
311
+ if ( $users ) {
312
+ foreach ( (array)$users as $user ) {
313
+ $role = unserialize( $user->meta_value );
314
+
315
+ if ( !isset( $role['subscriber'] ) )
316
+ bp_blogs_record_blog( $blog_id, $user->user_id, true );
317
+ }
318
+ }
319
+ }
320
+ }
321
+ }
322
+
323
+ /**
324
+ * Makes BuddyPress aware of a new site so that it can track its activity.
325
+ *
326
+ * @global object $bp BuddyPress global settings
327
+ * @param int $blog_id
328
+ * @param int $user_id
329
+ * @param $bool $no_activity ; optional.
330
+ * @since 1.0
331
+ * @uses BP_Blogs_Blog
332
+ */
333
+ function bp_blogs_record_blog( $blog_id, $user_id, $no_activity = false ) {
334
+ global $bp;
335
+
336
+ if ( !$user_id )
337
+ $user_id = $bp->loggedin_user->id;
338
+
339
+ $name = get_blog_option( $blog_id, 'blogname' );
340
+ $description = get_blog_option( $blog_id, 'blogdescription' );
341
+
342
+ if ( empty( $name ) )
343
+ return false;
344
+
345
+ $recorded_blog = new BP_Blogs_Blog;
346
+ $recorded_blog->user_id = $user_id;
347
+ $recorded_blog->blog_id = $blog_id;
348
+
349
+ $recorded_blog_id = $recorded_blog->save();
350
+
351
+ bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'name', $name );
352
+ bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'description', $description );
353
+ bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'last_activity', bp_core_current_time() );
354
+
355
+ // Only record this activity if the blog is public
356
+ if ( (int)$_POST['blog_public'] && !$no_activity ) {
357
+ // Record this in activity streams
358
+ bp_blogs_record_activity( array(
359
+ 'user_id' => $recorded_blog->user_id,
360
+ 'action' => apply_filters( 'bp_blogs_activity_created_blog_action', sprintf( __( '%s created the blog %s', 'buddypress'), bp_core_get_userlink( $recorded_blog->user_id ), '<a href="' . get_site_url( $recorded_blog->blog_id ) . '">' . esc_attr( $name ) . '</a>' ), &$recorded_blog, $name, $description ),
361
+ 'primary_link' => apply_filters( 'bp_blogs_activity_created_blog_primary_link', get_site_url( $recorded_blog->blog_id ), $recorded_blog->blog_id ),
362
+ 'type' => 'new_blog',
363
+ 'item_id' => $recorded_blog->blog_id
364
+ ) );
365
+ }
366
+
367
+ do_action( 'bp_blogs_new_blog', &$recorded_blog, $is_private, $is_recorded );
368
+ }
369
+ add_action( 'wpmu_new_blog', 'bp_blogs_record_blog', 10, 2 );
370
+
371
+ /**
372
+ * bp_blogs_update_option_blogname()
373
+ *
374
+ * Updates blogname in BuddyPress blogmeta table
375
+ *
376
+ * @global object $wpdb DB Layer
377
+ * @param string $oldvalue Value before save (not used)
378
+ * @param string $newvalue Value to change meta to
379
+ */
380
+ function bp_blogs_update_option_blogname( $oldvalue, $newvalue ) {
381
+ global $wpdb;
382
+ bp_blogs_update_blogmeta( $wpdb->blogid, 'name', $newvalue );
383
+ }
384
+ add_action( 'update_option_blogname', 'bp_blogs_update_option_blogname', 10, 2 );
385
+
386
+ /**
387
+ * bp_blogs_update_option_blogdescription()
388
+ *
389
+ * Updates blogdescription in BuddyPress blogmeta table
390
+ *
391
+ * @global object $wpdb DB Layer
392
+ * @param string $oldvalue Value before save (not used)
393
+ * @param string $newvalue Value to change meta to
394
+ */
395
+ function bp_blogs_update_option_blogdescription( $oldvalue, $newvalue ) {
396
+ global $wpdb;
397
+ bp_blogs_update_blogmeta( $wpdb->blogid, 'description', $newvalue );
398
+ }
399
+ add_action( 'update_option_blogdescription', 'bp_blogs_update_option_blogdescription', 10, 2 );
400
+
401
+ function bp_blogs_record_post( $post_id, $post, $user_id = false ) {
402
+ global $bp, $wpdb;
403
+
404
+ $post_id = (int)$post_id;
405
+ $blog_id = (int)$wpdb->blogid;
406
+
407
+ if ( !$user_id )
408
+ $user_id = (int)$post->post_author;
409
+
410
+ // This is to stop infinite loops with Donncha's sitewide tags plugin
411
+ if ( (int)$blog_id == (int)$bp->site_options['tags_blog_id'] )
412
+ return false;
413
+
414
+ // Don't record this if it's not a post
415
+ if ( 'post' != $post->post_type )
416
+ return false;
417
+
418
+ if ( 'publish' == $post->post_status && empty( $post->post_password ) ) {
419
+ if ( (int)get_blog_option( $blog_id, 'blog_public' ) || !bp_core_is_multisite() ) {
420
+ // Record this in activity streams
421
+ $post_permalink = get_permalink( $post_id );
422
+ $activity_action = sprintf( __( '%s wrote a new blog post: %s', 'buddypress' ), bp_core_get_userlink( (int)$post->post_author ), '<a href="' . $post_permalink . '">' . $post->post_title . '</a>' );
423
+ $activity_content = $post->post_content;
424
+
425
+ bp_blogs_record_activity( array(
426
+ 'user_id' => (int)$post->post_author,
427
+ 'action' => apply_filters( 'bp_blogs_activity_new_post_action', $activity_action, &$post, $post_permalink ),
428
+ 'content' => apply_filters( 'bp_blogs_activity_new_post_content', $activity_content, &$post, $post_permalink ),
429
+ 'primary_link' => apply_filters( 'bp_blogs_activity_new_post_primary_link', $post_permalink, $post_id ),
430
+ 'type' => 'new_blog_post',
431
+ 'item_id' => $blog_id,
432
+ 'secondary_item_id' => $post_id,
433
+ 'recorded_time' => $post->post_date_gmt
434
+ ));
435
+ }
436
+
437
+ // Update the blogs last activity
438
+ bp_blogs_update_blogmeta( $blog_id, 'last_activity', bp_core_current_time() );
439
+ } else {
440
+ bp_blogs_remove_post( $post_id, $blog_id );
441
+ }
442
+
443
+ do_action( 'bp_blogs_new_blog_post', $post_id, $post, $user_id );
444
+ }
445
+ add_action( 'save_post', 'bp_blogs_record_post', 10, 2 );
446
+
447
+ /**
448
+ * bp_blogs_record_comment()
449
+ *
450
+ * Record blog comment activity. Checks if blog is public and post is not
451
+ * password protected.
452
+ *
453
+ * @global object $wpdb
454
+ * @global $bp $bp
455
+ * @param int $comment_id
456
+ * @param bool $is_approved
457
+ * @return mixed
458
+ */
459
+
460
+ function bp_blogs_record_comment( $comment_id, $is_approved = true ) {
461
+ global $wpdb, $bp;
462
+
463
+ // Get the users comment
464
+ $recorded_comment = get_comment( $comment_id );
465
+
466
+ // Don't record activity if the comment hasn't been approved
467
+ if ( empty( $is_approved ) )
468
+ return false;
469
+
470
+ // Don't record activity if no email address has been included
471
+ if ( empty( $recorded_comment->comment_author_email ) )
472
+ return false;
473
+
474
+ // Get the user_id from the comment author email.
475
+ $user = get_user_by_email( $recorded_comment->comment_author_email );
476
+ $user_id = (int)$user->ID;
477
+
478
+ // If there's no registered user id, don't record activity
479
+ if ( empty( $user_id ) )
480
+ return false;
481
+
482
+ // Get blog and post data
483
+ $blog_id = (int)$wpdb->blogid;
484
+ $recorded_comment->post = get_post( $recorded_comment->comment_post_ID );
485
+
486
+ // If this is a password protected post, don't record the comment
487
+ if ( !empty( $recorded_comment->post->post_password ) )
488
+ return false;
489
+
490
+ // If blog is public allow activity to be posted
491
+ if ( get_blog_option( $blog_id, 'blog_public' ) ) {
492
+
493
+ // Get activity related links
494
+ $post_permalink = get_permalink( $recorded_comment->comment_post_ID );
495
+ $comment_link = htmlspecialchars( get_comment_link( $recorded_comment->comment_ID ) );
496
+
497
+ // Prepare to record in activity streams
498
+ $activity_action = sprintf( __( '%s commented on the blog post %s', 'buddypress' ), bp_core_get_userlink( $user_id ), '<a href="' . $post_permalink . '">' . apply_filters( 'the_title', $recorded_comment->post->post_title ) . '</a>' );
499
+ $activity_content = $recorded_comment->comment_content;
500
+
501
+ // Record in activity streams
502
+ bp_blogs_record_activity( array(
503
+ 'user_id' => $user_id,
504
+ 'action' => apply_filters( 'bp_blogs_activity_new_comment_action', $activity_action, &$recorded_comment, $comment_link ),
505
+ 'content' => apply_filters( 'bp_blogs_activity_new_comment_content', $activity_content, &$recorded_comment, $comment_link ),
506
+ 'primary_link' => apply_filters( 'bp_blogs_activity_new_comment_primary_link', $comment_link, &$recorded_comment ),
507
+ 'type' => 'new_blog_comment',
508
+ 'item_id' => $blog_id,
509
+ 'secondary_item_id' => $comment_id,
510
+ 'recorded_time' => $recorded_comment->comment_date_gmt
511
+ ) );
512
+
513
+ // Update the blogs last active date
514
+ bp_blogs_update_blogmeta( $blog_id, 'last_activity', bp_core_current_time() );
515
+ }
516
+
517
+ return $recorded_comment;
518
+ }
519
+ add_action( 'comment_post', 'bp_blogs_record_comment', 10, 2 );
520
+ //add_action( 'edit_comment', 'bp_blogs_record_comment', 10 );
521
+
522
+ function bp_blogs_manage_comment( $comment_id, $comment_status ) {
523
+ if ( 'spam' == $comment_status || 'hold' == $comment_status || 'delete' == $comment_status || 'trash' == $comment_status )
524
+ return bp_blogs_remove_comment( $comment_id );
525
+
526
+ return bp_blogs_record_comment( $comment_id, true );
527
+ }
528
+ add_action( 'wp_set_comment_status', 'bp_blogs_manage_comment', 10, 2 );
529
+
530
+ function bp_blogs_add_user_to_blog( $user_id, $role, $blog_id = false ) {
531
+ global $current_blog;
532
+
533
+ if ( empty( $blog_id ) )
534
+ $blog_id = $current_blog->blog_id;
535
+
536
+ if ( $role != 'subscriber' )
537
+ bp_blogs_record_blog( $blog_id, $user_id, true );
538
+ }
539
+ add_action( 'add_user_to_blog', 'bp_blogs_add_user_to_blog', 10, 3 );
540
+
541
+ function bp_blogs_remove_user_from_blog( $user_id, $blog_id = false ) {
542
+ global $current_blog;
543
+
544
+ if ( empty( $blog_id ) )
545
+ $blog_id = $current_blog->blog_id;
546
+
547
+ bp_blogs_remove_blog_for_user( $user_id, $blog_id );
548
+ }
549
+ add_action( 'remove_user_from_blog', 'bp_blogs_remove_user_from_blog', 10, 2 );
550
+
551
+ function bp_blogs_remove_blog( $blog_id ) {
552
+ global $bp;
553
+
554
+ $blog_id = (int)$blog_id;
555
+
556
+ BP_Blogs_Blog::delete_blog_for_all( $blog_id );
557
+
558
+ // Delete activity stream item
559
+ bp_blogs_delete_activity( array( 'item_id' => $blog_id, 'component' => $bp->blogs->slug, 'type' => 'new_blog' ) );
560
+
561
+ do_action( 'bp_blogs_remove_blog', $blog_id );
562
+ }
563
+ add_action( 'delete_blog', 'bp_blogs_remove_blog' );
564
+
565
+ function bp_blogs_remove_blog_for_user( $user_id, $blog_id ) {
566
+ global $current_user;
567
+
568
+ $blog_id = (int)$blog_id;
569
+ $user_id = (int)$user_id;
570
+
571
+ BP_Blogs_Blog::delete_blog_for_user( $blog_id, $user_id );
572
+
573
+ // Delete activity stream item
574
+ bp_blogs_delete_activity( array( 'item_id' => $blog_id, 'component' => $bp->blogs->slug, 'type' => 'new_blog' ) );
575
+
576
+ do_action( 'bp_blogs_remove_blog_for_user', $blog_id, $user_id );
577
+ }
578
+ add_action( 'remove_user_from_blog', 'bp_blogs_remove_blog_for_user', 10, 2 );
579
+
580
+ function bp_blogs_remove_post( $post_id, $blog_id = false ) {
581
+ global $current_blog, $bp;
582
+
583
+ $post_id = (int)$post_id;
584
+
585
+ if ( !$blog_id )
586
+ $blog_id = (int)$current_blog->blog_id;
587
+
588
+ // Delete activity stream item
589
+ bp_blogs_delete_activity( array( 'item_id' => $blog_id, 'secondary_item_id' => $post_id, 'component' => $bp->blogs->slug, 'type' => 'new_blog_post' ) );
590
+
591
+ do_action( 'bp_blogs_remove_post', $blog_id, $post_id, $post->user_id );
592
+ }
593
+ add_action( 'delete_post', 'bp_blogs_remove_post' );
594
+
595
+ function bp_blogs_remove_comment( $comment_id ) {
596
+ global $wpdb, $bp;
597
+
598
+ // Delete activity stream item
599
+ bp_blogs_delete_activity( array( 'item_id' => $wpdb->blogid , 'secondary_item_id' => $comment_id, 'type' => 'new_blog_comment' ) );
600
+
601
+ do_action( 'bp_blogs_remove_comment', $blog_id, $comment_id, $bp->loggedin_user->id );
602
+ }
603
+ add_action( 'delete_comment', 'bp_blogs_remove_comment' );
604
+
605
+ function bp_blogs_total_blogs() {
606
+ if ( !$count = wp_cache_get( 'bp_total_blogs', 'bp' ) ) {
607
+ $blogs = BP_Blogs_Blog::get_all();
608
+ $count = $blogs['total'];
609
+ wp_cache_set( 'bp_total_blogs', $count, 'bp' );
610
+ }
611
+ return $count;
612
+ }
613
+
614
+ function bp_blogs_total_blogs_for_user( $user_id = false ) {
615
+ global $bp;
616
+
617
+ if ( !$user_id )
618
+ $user_id = ( $bp->displayed_user->id ) ? $bp->displayed_user->id : $bp->loggedin_user->id;
619
+
620
+ if ( !$count = wp_cache_get( 'bp_total_blogs_for_user_' . $user_id, 'bp' ) ) {
621
+ $count = BP_Blogs_Blog::total_blog_count_for_user( $user_id );
622
+ wp_cache_set( 'bp_total_blogs_for_user_' . $user_id, $count, 'bp' );
623
+ }
624
+
625
+ return $count;
626
+ }
627
+
628
+ function bp_blogs_remove_data_for_blog( $blog_id ) {
629
+ global $bp;
630
+
631
+ /* If this is regular blog, delete all data for that blog. */
632
+ BP_Blogs_Blog::delete_blog_for_all( $blog_id );
633
+
634
+ // Delete activity stream item
635
+ bp_blogs_delete_activity( array( 'item_id' => $blog_id, 'component' => $bp->blogs->slug, 'type' => false ) );
636
+
637
+ do_action( 'bp_blogs_remove_data_for_blog', $blog_id );
638
+ }
639
+ add_action( 'delete_blog', 'bp_blogs_remove_data_for_blog', 1 );
640
+
641
+ function bp_blogs_get_blogs_for_user( $user_id, $show_hidden = false ) {
642
+ return BP_Blogs_Blog::get_blogs_for_user( $user_id, $show_hidden );
643
+ }
644
+
645
+ function bp_blogs_get_all_blogs( $limit = null, $page = null ) {
646
+ return BP_Blogs_Blog::get_all( $limit, $page );
647
+ }
648
+
649
+ function bp_blogs_get_random_blogs( $limit = null, $page = null ) {
650
+ return BP_Blogs_Blog::get( 'random', $limit, $page );
651
+ }
652
+
653
+ function bp_blogs_is_blog_hidden( $blog_id ) {
654
+ return BP_Blogs_Blog::is_hidden( $blog_id );
655
+ }
656
+
657
+ function bp_blogs_redirect_to_random_blog() {
658
+ global $bp, $wpdb;
659
+
660
+ if ( $bp->current_component == $bp->blogs->slug && isset( $_GET['random-blog'] ) ) {
661
+ $blog = bp_blogs_get_random_blogs( 1, 1 );
662
+
663
+ bp_core_redirect( get_site_url( $blog['blogs'][0]->blog_id ) );
664
+ }
665
+ }
666
+ add_action( 'wp', 'bp_blogs_redirect_to_random_blog', 6 );
667
+
668
+
669
+ //
670
+ // Blog meta functions
671
+ // These functions are used to store specific blogmeta in one global table, rather than in each
672
+ // blog's options table. Significantly speeds up global blog queries.
673
+ // By default each blog's name, description and last updated time are stored and synced here.
674
+ //
675
+
676
+ function bp_blogs_delete_blogmeta( $blog_id, $meta_key = false, $meta_value = false ) {
677
+ global $wpdb, $bp;
678
+
679
+ if ( !is_numeric( $blog_id ) || !bp_core_is_multisite() )
680
+ return false;
681
+
682
+ $meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
683
+
684
+ if ( is_array($meta_value) || is_object($meta_value) )
685
+ $meta_value = serialize($meta_value);
686
+
687
+ $meta_value = trim( $meta_value );
688
+
689
+ if ( !$meta_key ) {
690
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d", $blog_id ) );
691
+ } else if ( $meta_value ) {
692
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d AND meta_key = %s AND meta_value = %s", $blog_id, $meta_key, $meta_value ) );
693
+ } else {
694
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d AND meta_key = %s", $blog_id, $meta_key ) );
695
+ }
696
+
697
+ wp_cache_delete( 'bp_blogs_blogmeta_' . $blog_id . '_' . $meta_key, 'bp' );
698
+
699
+ return true;
700
+ }
701
+
702
+ function bp_blogs_get_blogmeta( $blog_id, $meta_key = '') {
703
+ global $wpdb, $bp;
704
+
705
+ $blog_id = (int) $blog_id;
706
+
707
+ if ( !$blog_id || !bp_core_is_multisite() )
708
+ return false;
709
+
710
+ if ( !empty($meta_key) ) {
711
+ $meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
712
+
713
+ if ( !$metas = wp_cache_get( 'bp_blogs_blogmeta_' . $blog_id . '_' . $meta_key, 'bp' ) ) {
714
+ $metas = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d AND meta_key = %s", $blog_id, $meta_key ) );
715
+ wp_cache_set( 'bp_blogs_blogmeta_' . $blog_id . '_' . $meta_key, $metas, 'bp' );
716
+ }
717
+ } else {
718
+ $metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d", $blog_id) );
719
+ }
720
+
721
+ if ( empty($metas) ) {
722
+ if ( empty($meta_key) )
723
+ return array();
724
+ else
725
+ return '';
726
+ }
727
+
728
+ $metas = array_map('maybe_unserialize', (array)$metas);
729
+
730
+ if ( 1 == count($metas) )
731
+ return $metas[0];
732
+ else
733
+ return $metas;
734
+ }
735
+
736
+ function bp_blogs_update_blogmeta( $blog_id, $meta_key, $meta_value ) {
737
+ global $wpdb, $bp;
738
+
739
+ if ( !is_numeric( $blog_id ) || !bp_core_is_multisite() )
740
+ return false;
741
+
742
+ $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
743
+
744
+ if ( is_string($meta_value) )
745
+ $meta_value = stripslashes($wpdb->escape($meta_value));
746
+
747
+ $meta_value = maybe_serialize($meta_value);
748
+
749
+ if (empty($meta_value)) {
750
+ return bp_blogs_delete_blogmeta( $blog_id, $meta_key );
751
+ }
752
+
753
+ $cur = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d AND meta_key = %s", $blog_id, $meta_key ) );
754
+
755
+ if ( !$cur ) {
756
+ $wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->blogs->table_name_blogmeta} ( blog_id, meta_key, meta_value ) VALUES ( %d, %s, %s )", $blog_id, $meta_key, $meta_value ) );
757
+ } else if ( $cur->meta_value != $meta_value ) {
758
+ $wpdb->query( $wpdb->prepare( "UPDATE {$bp->blogs->table_name_blogmeta} SET meta_value = %s WHERE blog_id = %d AND meta_key = %s", $meta_value, $blog_id, $meta_key ) );
759
+ } else {
760
+ return false;
761
+ }
762
+
763
+ wp_cache_set( 'bp_blogs_blogmeta_' . $blog_id . '_' . $meta_key, $metas, 'bp' );
764
+
765
+ return true;
766
+ }
767
+
768
+ function bp_blogs_remove_data( $user_id ) {
769
+ if ( !bp_core_is_multisite() )
770
+ return false;
771
+
772
+ /* If this is regular blog, delete all data for that blog. */
773
+ BP_Blogs_Blog::delete_blogs_for_user( $user_id );
774
+
775
+ do_action( 'bp_blogs_remove_data', $user_id );
776
+ }
777
+ add_action( 'wpmu_delete_user', 'bp_blogs_remove_data' );
778
+ add_action( 'delete_user', 'bp_blogs_remove_data' );
779
+ add_action( 'make_spam_user', 'bp_blogs_remove_data' );
780
+
781
+
782
+ /********************************************************************************
783
+ * Caching
784
+ *
785
+ * Caching functions handle the clearing of cached objects and pages on specific
786
+ * actions throughout BuddyPress.
787
+ */
788
+
789
+ function bp_blogs_clear_blog_object_cache( $blog_id, $user_id ) {
790
+ wp_cache_delete( 'bp_blogs_of_user_' . $user_id, 'bp' );
791
+ wp_cache_delete( 'bp_blogs_for_user_' . $user_id, 'bp' );
792
+ wp_cache_delete( 'bp_total_blogs_for_user_' . $user_id, 'bp' );
793
+
794
+ /* Clear the sitewide activity cache */
795
+ wp_cache_delete( 'sitewide_activity', 'bp' );
796
+ }
797
+
798
+ function bp_blogs_format_clear_blog_cache( $recorded_blog_obj ) {
799
+ bp_blogs_clear_blog_object_cache( false, $recorded_blog_obj->user_id );
800
+
801
+ /* Clear the sitewide activity cache */
802
+ wp_cache_delete( 'sitewide_activity', 'bp' );
803
+ wp_cache_delete( 'bp_total_blogs', 'bp' );
804
+ }
805
+
806
+ // List actions to clear object caches on
807
+ add_action( 'bp_blogs_remove_blog_for_user', 'bp_blogs_clear_blog_object_cache', 10, 2 );
808
+ add_action( 'bp_blogs_new_blog', 'bp_blogs_format_clear_blog_cache', 10, 2 );
809
+
810
+ // List actions to clear super cached pages on, if super cache is installed
811
+ add_action( 'bp_blogs_remove_data_for_blog', 'bp_core_clear_cache' );
812
+ add_action( 'bp_blogs_remove_comment', 'bp_core_clear_cache' );
813
+ add_action( 'bp_blogs_remove_post', 'bp_core_clear_cache' );
814
+ add_action( 'bp_blogs_remove_blog_for_user', 'bp_core_clear_cache' );
815
+ add_action( 'bp_blogs_remove_blog', 'bp_core_clear_cache' );
816
+ add_action( 'bp_blogs_new_blog_comment', 'bp_core_clear_cache' );
817
+ add_action( 'bp_blogs_new_blog_post', 'bp_core_clear_cache' );
818
+ add_action( 'bp_blogs_new_blog', 'bp_core_clear_cache' );
819
+ add_action( 'bp_blogs_remove_data', 'bp_core_clear_cache' );
820
+
821
+ ?>
bp-blogs/bp-blogs-actions.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Blogs Actions.
4
- *
5
- * @package BuddyPress
6
- * @subpackage BlogsActions
7
- * @since 1.5.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Redirect to a random blog in the multisite network.
15
- *
16
- * @since 1.0.0
17
- */
18
- function bp_blogs_redirect_to_random_blog() {
19
-
20
- // Bail if not looking for a random blog.
21
- if ( ! bp_is_blogs_component() || ! isset( $_GET['random-blog'] ) )
22
- return;
23
-
24
- // Multisite is active so find a random blog.
25
- if ( is_multisite() ) {
26
- $blog = bp_blogs_get_random_blogs( 1, 1 );
27
- bp_core_redirect( get_home_url( $blog['blogs'][0]->blog_id ) );
28
-
29
- // No multisite and still called, always redirect to root.
30
- } else {
31
- bp_core_redirect( bp_core_get_root_domain() );
32
- }
33
- }
34
- add_action( 'bp_actions', 'bp_blogs_redirect_to_random_blog' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-blogs/bp-blogs-activity.php DELETED
@@ -1,1446 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Blogs Activity.
4
- *
5
- * @package BuddyPress
6
- * @subpackage BlogsActivity
7
- * @since 1.5.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Register activity actions for the blogs component.
15
- *
16
- * @since 1.0.0
17
- *
18
- * @return bool|null Returns false if activity component is not active.
19
- */
20
- function bp_blogs_register_activity_actions() {
21
- if ( is_multisite() ) {
22
- bp_activity_set_action(
23
- buddypress()->blogs->id,
24
- 'new_blog',
25
- __( 'New site created', 'buddypress' ),
26
- 'bp_blogs_format_activity_action_new_blog',
27
- __( 'New Sites', 'buddypress' ),
28
- array( 'activity', 'member' ),
29
- 0
30
- );
31
- }
32
-
33
- /**
34
- * Fires after the registry of the default blog component activity actions.
35
- *
36
- * @since 1.1.0
37
- */
38
- do_action( 'bp_blogs_register_activity_actions' );
39
- }
40
- add_action( 'bp_register_activity_actions', 'bp_blogs_register_activity_actions' );
41
-
42
- /**
43
- * Set up the tracking arguments for the 'post' post type.
44
- *
45
- * @since 2.5.0 This was moved out of the BP_Blogs_Component class.
46
- *
47
- * @see bp_activity_get_post_type_tracking_args() for information on parameters.
48
- *
49
- * @param object|null $params Tracking arguments.
50
- * @param string|int $post_type Post type to track.
51
- * @return object|null
52
- */
53
- function bp_blogs_register_post_tracking_args( $params = null, $post_type = 0 ) {
54
-
55
- /**
56
- * Filters the post types to track for the Blogs component.
57
- *
58
- * @since 1.5.0
59
- * @deprecated 2.3.0
60
- *
61
- * Make sure plugins still using 'bp_blogs_record_post_post_types'
62
- * to track their post types will generate new_blog_post activities
63
- * See https://buddypress.trac.wordpress.org/ticket/6306
64
- *
65
- * @param array $value Array of post types to track.
66
- */
67
- $post_types = apply_filters( 'bp_blogs_record_post_post_types', array( 'post' ) );
68
- $post_types_array = array_flip( $post_types );
69
-
70
- if ( ! isset( $post_types_array[ $post_type ] ) ) {
71
- return $params;
72
- }
73
-
74
- // Set specific params for the 'post' post type.
75
- $params->component_id = buddypress()->blogs->id;
76
- $params->action_id = 'new_blog_post';
77
- $params->admin_filter = __( 'New post published', 'buddypress' );
78
- $params->format_callback = 'bp_blogs_format_activity_action_new_blog_post';
79
- $params->front_filter = __( 'Posts', 'buddypress' );
80
- $params->contexts = array( 'activity', 'member' );
81
- $params->position = 5;
82
-
83
- if ( post_type_supports( $post_type, 'comments' ) ) {
84
- $params->comment_action_id = 'new_blog_comment';
85
-
86
- /**
87
- * Filters the post types to track for the Blogs component.
88
- *
89
- * @since 1.5.0
90
- * @deprecated 2.5.0
91
- *
92
- * Make sure plugins still using 'bp_blogs_record_comment_post_types'
93
- * to track comment about their post types will generate new_blog_comment activities
94
- * See https://buddypress.trac.wordpress.org/ticket/6306
95
- *
96
- * @param array $value Array of post types to track.
97
- */
98
- $comment_post_types = apply_filters( 'bp_blogs_record_comment_post_types', array( 'post' ) );
99
- $comment_post_types_array = array_flip( $comment_post_types );
100
-
101
- if ( isset( $comment_post_types_array[ $post_type ] ) ) {
102
- $params->comments_tracking = new stdClass();
103
- $params->comments_tracking->component_id = buddypress()->blogs->id;
104
- $params->comments_tracking->action_id = 'new_blog_comment';
105
- $params->comments_tracking->admin_filter = __( 'New post comment posted', 'buddypress' );
106
- $params->comments_tracking->format_callback = 'bp_blogs_format_activity_action_new_blog_comment';
107
- $params->comments_tracking->front_filter = __( 'Comments', 'buddypress' );
108
- $params->comments_tracking->contexts = array( 'activity', 'member' );
109
- $params->comments_tracking->position = 10;
110
- }
111
- }
112
-
113
- return $params;
114
- }
115
- add_filter( 'bp_activity_get_post_type_tracking_args', 'bp_blogs_register_post_tracking_args', 10, 2 );
116
-
117
- /**
118
- * Format 'new_blog' activity actions.
119
- *
120
- * @since 2.0.0
121
- *
122
- * @param string $action Static activity action.
123
- * @param object $activity Activity data object.
124
- * @return string
125
- */
126
- 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( __( '%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' ) ) {
134
- $user_blog = BP_Blogs_Blog::get_user_blog( $activity->user_id, $activity->item_id );
135
- if ( $user_blog ) {
136
- $recorded_blog = new BP_Blogs_Blog( $user_blog );
137
- }
138
-
139
- if ( isset( $recorded_blog ) ) {
140
- $action = apply_filters( 'bp_blogs_activity_created_blog_action', $action, $recorded_blog, $blog_name, bp_blogs_get_blogmeta( $activity->item_id, 'description' ) );
141
- }
142
- }
143
-
144
- /**
145
- * Filters the new blog activity action for the new blog.
146
- *
147
- * @since 2.0.0
148
- *
149
- * @param string $action Constructed activity action.
150
- * @param object $activity Activity data object.
151
- */
152
- return apply_filters( 'bp_blogs_format_activity_action_new_blog', $action, $activity );
153
- }
154
-
155
- /**
156
- * Format 'new_blog_post' activity actions.
157
- *
158
- * @since 2.0.0
159
- *
160
- * @param string $action Static activity action.
161
- * @param object $activity Activity data object.
162
- * @return string Constructed activity action.
163
- */
164
- function bp_blogs_format_activity_action_new_blog_post( $action, $activity ) {
165
- $blog_url = bp_blogs_get_blogmeta( $activity->item_id, 'url' );
166
- $blog_name = bp_blogs_get_blogmeta( $activity->item_id, 'name' );
167
-
168
- if ( empty( $blog_url ) || empty( $blog_name ) ) {
169
- $blog_url = get_home_url( $activity->item_id );
170
- $blog_name = get_blog_option( $activity->item_id, 'blogname' );
171
-
172
- bp_blogs_update_blogmeta( $activity->item_id, 'url', $blog_url );
173
- bp_blogs_update_blogmeta( $activity->item_id, 'name', $blog_name );
174
- }
175
-
176
- /**
177
- * When the post is published we are faking an activity object
178
- * to which we add 2 properties :
179
- * - the post url
180
- * - the post title
181
- * This is done to build the 'post link' part of the activity
182
- * action string.
183
- * NB: in this case the activity has not yet been created.
184
- */
185
- if ( isset( $activity->post_url ) ) {
186
- $post_url = $activity->post_url;
187
-
188
- /**
189
- * The post_url property is not set, we need to build the url
190
- * thanks to the post id which is also saved as the secondary
191
- * item id property of the activity object.
192
- */
193
- } else {
194
- $post_url = add_query_arg( 'p', $activity->secondary_item_id, trailingslashit( $blog_url ) );
195
- }
196
-
197
- // Should be the case when the post has just been published.
198
- if ( isset( $activity->post_title ) ) {
199
- $post_title = $activity->post_title;
200
-
201
- // If activity already exists try to get the post title from activity meta.
202
- } else if ( ! empty( $activity->id ) ) {
203
- $post_title = bp_activity_get_meta( $activity->id, 'post_title' );
204
- }
205
-
206
- /**
207
- * In case the post was published without a title
208
- * or the activity meta was not found.
209
- */
210
- if ( empty( $post_title ) ) {
211
- // Defaults to no title.
212
- $post_title = esc_html__( '(no title)', 'buddypress' );
213
-
214
- switch_to_blog( $activity->item_id );
215
-
216
- $post = get_post( $activity->secondary_item_id );
217
- if ( is_a( $post, 'WP_Post' ) ) {
218
- // Does the post have a title ?
219
- if ( ! empty( $post->post_title ) ) {
220
- $post_title = $post->post_title;
221
- }
222
-
223
- // Make sure the activity exists before saving the post title in activity meta.
224
- if ( ! empty( $activity->id ) ) {
225
- bp_activity_update_meta( $activity->id, 'post_title', $post_title );
226
- }
227
- }
228
-
229
- restore_current_blog();
230
- }
231
-
232
- // Build the 'post link' part of the activity action string.
233
- $post_link = '<a href="' . esc_url( $post_url ) . '">' . $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( __( '%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( __( '%1$s wrote a new post, %2$s', 'buddypress' ), $user_link, $post_link );
242
- }
243
-
244
- // Legacy filter - requires the post object.
245
- if ( has_filter( 'bp_blogs_activity_new_post_action' ) ) {
246
- switch_to_blog( $activity->item_id );
247
- $post = get_post( $activity->secondary_item_id );
248
- restore_current_blog();
249
-
250
- if ( ! empty( $post ) && ! is_wp_error( $post ) ) {
251
- $action = apply_filters( 'bp_blogs_activity_new_post_action', $action, $post, $post_url );
252
- }
253
- }
254
-
255
- /**
256
- * Filters the new blog post action for the new blog.
257
- *
258
- * @since 2.0.0
259
- *
260
- * @param string $action Constructed activity action.
261
- * @param object $activity Activity data object.
262
- */
263
- return apply_filters( 'bp_blogs_format_activity_action_new_blog_post', $action, $activity );
264
- }
265
-
266
- /**
267
- * Format 'new_blog_comment' activity actions.
268
- *
269
- * @since 2.0.0
270
- *
271
- * @param string $action Static activity action.
272
- * @param object $activity Activity data object.
273
- * @return string Constructed activity action.
274
- */
275
- function bp_blogs_format_activity_action_new_blog_comment( $action, $activity ) {
276
- /**
277
- * When the comment is published we are faking an activity object
278
- * to which we add 4 properties :
279
- * - the post url
280
- * - the post title
281
- * - the blog url
282
- * - the blog name
283
- * This is done to build the 'post link' part of the activity
284
- * action string.
285
- * NB: in this case the activity has not yet been created.
286
- */
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 {
294
- $blog_url = bp_blogs_get_blogmeta( $activity->item_id, 'url' );
295
- }
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 {
303
- $blog_name = bp_blogs_get_blogmeta( $activity->item_id, 'name' );
304
- }
305
-
306
- if ( empty( $blog_url ) || empty( $blog_name ) ) {
307
- $blog_url = get_home_url( $activity->item_id );
308
- $blog_name = get_blog_option( $activity->item_id, 'blogname' );
309
-
310
- bp_blogs_update_blogmeta( $activity->item_id, 'url', $blog_url );
311
- bp_blogs_update_blogmeta( $activity->item_id, 'name', $blog_name );
312
- }
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
-
320
- /**
321
- * The post_url property is not set, we need to build the url
322
- * thanks to the post id which is also saved as the secondary
323
- * item id property of the activity object.
324
- */
325
- } elseif ( ! empty( $activity->id ) ) {
326
- $post_url = bp_activity_get_meta( $activity->id, 'post_url' );
327
- }
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
- }
339
-
340
- // Should only be empty at the time of post creation.
341
- if ( empty( $post_url ) || empty( $post_title ) ) {
342
- switch_to_blog( $activity->item_id );
343
-
344
- $comment = get_comment( $activity->secondary_item_id );
345
-
346
- if ( ! empty( $comment->comment_post_ID ) ) {
347
- $post_url = add_query_arg( 'p', $comment->comment_post_ID, trailingslashit( $blog_url ) );
348
- bp_activity_update_meta( $activity->id, 'post_url', $post_url );
349
-
350
- $post = get_post( $comment->comment_post_ID );
351
-
352
- if ( is_a( $post, 'WP_Post' ) ) {
353
- $post_title = $post->post_title;
354
- bp_activity_update_meta( $activity->id, 'post_title', $post_title );
355
- }
356
- }
357
-
358
- restore_current_blog();
359
- }
360
-
361
- $post_link = '<a href="' . esc_url( $post_url ) . '">' . $post_title . '</a>';
362
- $user_link = bp_core_get_userlink( $activity->user_id );
363
-
364
- if ( is_multisite() ) {
365
- $action = sprintf( __( '%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( __( '%1$s commented on the post, %2$s', 'buddypress' ), $user_link, $post_link );
368
- }
369
-
370
- // Legacy filter - requires the comment object.
371
- if ( has_filter( 'bp_blogs_activity_new_comment_action' ) ) {
372
- switch_to_blog( $activity->item_id );
373
- $comment = get_comment( $activity->secondary_item_id );
374
- restore_current_blog();
375
-
376
- if ( ! empty( $comment ) && ! is_wp_error( $comment ) ) {
377
- $action = apply_filters( 'bp_blogs_activity_new_comment_action', $action, $comment, $post_url . '#' . $activity->secondary_item_id );
378
- }
379
- }
380
-
381
- /**
382
- * Filters the new blog comment action for the new blog.
383
- *
384
- * @since 2.0.0
385
- *
386
- * @param string $action Constructed activity action.
387
- * @param object $activity Activity data object.
388
- */
389
- return apply_filters( 'bp_blogs_format_activity_action_new_blog_comment', $action, $activity );
390
- }
391
-
392
- /**
393
- * Fetch data related to blogs at the beginning of an activity loop.
394
- *
395
- * This reduces database overhead during the activity loop.
396
- *
397
- * @since 2.0.0
398
- *
399
- * @param array $activities Array of activity items.
400
- * @return array
401
- */
402
- function bp_blogs_prefetch_activity_object_data( $activities ) {
403
- if ( empty( $activities ) ) {
404
- return $activities;
405
- }
406
-
407
- $blog_ids = array();
408
-
409
- foreach ( $activities as $activity ) {
410
- if ( buddypress()->blogs->id !== $activity->component ) {
411
- continue;
412
- }
413
-
414
- $blog_ids[] = $activity->item_id;
415
- }
416
-
417
- if ( ! empty( $blog_ids ) ) {
418
- bp_blogs_update_meta_cache( $blog_ids );
419
- }
420
-
421
- return $activities;
422
- }
423
- add_filter( 'bp_activity_prefetch_object_data', 'bp_blogs_prefetch_activity_object_data' );
424
-
425
- /**
426
- * Record blog-related activity to the activity stream.
427
- *
428
- * @since 1.0.0
429
- *
430
- * @see bp_activity_add() for description of parameters.
431
- *
432
- * @param array|string $args {
433
- * See {@link bp_activity_add()} for complete description of arguments.
434
- * The arguments listed here have different default values from
435
- * bp_activity_add().
436
- * @type string $component Default: 'blogs'.
437
- * }
438
- * @return WP_Error|bool|int On success, returns the activity ID. False on failure.
439
- */
440
- function bp_blogs_record_activity( $args = '' ) {
441
- $defaults = array(
442
- 'user_id' => bp_loggedin_user_id(),
443
- 'action' => '',
444
- 'content' => '',
445
- 'primary_link' => '',
446
- 'component' => buddypress()->blogs->id,
447
- 'type' => false,
448
- 'item_id' => false,
449
- 'secondary_item_id' => false,
450
- 'recorded_time' => bp_core_current_time(),
451
- 'hide_sitewide' => false
452
- );
453
-
454
- $r = wp_parse_args( $args, $defaults );
455
-
456
- if ( ! empty( $r['action'] ) ) {
457
-
458
- /**
459
- * Filters the action associated with activity for activity stream.
460
- *
461
- * @since 1.2.0
462
- *
463
- * @param string $value Action for the activity stream.
464
- */
465
- $r['action'] = apply_filters( 'bp_blogs_record_activity_action', $r['action'] );
466
- }
467
-
468
- if ( ! empty( $r['content'] ) ) {
469
-
470
- /**
471
- * Filters the content associated with activity for activity stream.
472
- *
473
- * @since 1.2.0
474
- *
475
- * @param string $value Generated summary from content for the activity stream.
476
- * @param string $value Content for the activity stream.
477
- * @param array $r Array of arguments used for the activity stream item.
478
- */
479
- $r['content'] = apply_filters( 'bp_blogs_record_activity_content', bp_activity_create_summary( $r['content'], $r ), $r['content'], $r );
480
- }
481
-
482
- // Check for an existing entry and update if one exists.
483
- $id = bp_activity_get_activity_id( array(
484
- 'user_id' => $r['user_id'],
485
- 'component' => $r['component'],
486
- 'type' => $r['type'],
487
- 'item_id' => $r['item_id'],
488
- 'secondary_item_id' => $r['secondary_item_id'],
489
- ) );
490
-
491
- return bp_activity_add( array( 'id' => $id, 'user_id' => $r['user_id'], 'action' => $r['action'], 'content' => $r['content'], 'primary_link' => $r['primary_link'], 'component' => $r['component'], 'type' => $r['type'], 'item_id' => $r['item_id'], 'secondary_item_id' => $r['secondary_item_id'], 'recorded_time' => $r['recorded_time'], 'hide_sitewide' => $r['hide_sitewide'] ) );
492
- }
493
-
494
- /**
495
- * Delete a blog-related activity stream item.
496
- *
497
- * @since 1.0.0
498
- *
499
- * @see bp_activity_delete() for description of parameters.
500
- *
501
- * @param array|string $args {
502
- * See {@link bp_activity_delete()} for complete description of arguments.
503
- * The arguments listed here have different default values from
504
- * bp_activity_add().
505
- * @type string $component Default: 'blogs'.
506
- * }
507
- * @return bool True on success, false on failure.
508
- */
509
- function bp_blogs_delete_activity( $args = '' ) {
510
- $r = bp_parse_args( $args, array(
511
- 'item_id' => false,
512
- 'component' => buddypress()->blogs->id,
513
- 'type' => false,
514
- 'user_id' => false,
515
- 'secondary_item_id' => false
516
- ) );
517
-
518
- bp_activity_delete_by_item_id( $r );
519
- }
520
-
521
- /**
522
- * Check if a blog post's activity item should be closed from commenting.
523
- *
524
- * This mirrors the {@link comments_open()} and {@link _close_comments_for_old_post()}
525
- * functions, but for use with the BuddyPress activity stream to be as
526
- * lightweight as possible.
527
- *
528
- * By lightweight, we actually mirror a few of the blog's commenting settings
529
- * to blogmeta and checks the values in blogmeta instead. This is to prevent
530
- * multiple {@link switch_to_blog()} calls in the activity stream.
531
- *
532
- * @since 2.0.0
533
- *
534
- * @param object $activity The BP_Activity_Activity object.
535
- * @return bool
536
- */
537
- function bp_blogs_comments_open( $activity ) {
538
- $open = true;
539
-
540
- $blog_id = $activity->item_id;
541
-
542
- // See if we've mirrored the close comments option before.
543
- $days_old = bp_blogs_get_blogmeta( $blog_id, 'close_comments_days_old' );
544
-
545
- // We've never cached these items before, so do it now.
546
- if ( '' === $days_old ) {
547
- switch_to_blog( $blog_id );
548
-
549
- // Use comments_open().
550
- remove_filter( 'comments_open', 'bp_comments_open', 10 );
551
- $open = comments_open( $activity->secondary_item_id );
552
- add_filter( 'comments_open', 'bp_comments_open', 10, 2 );
553
-
554
- // Might as well mirror values to blogmeta since we're here!
555
- $thread_depth = get_option( 'thread_comments' );
556
- if ( ! empty( $thread_depth ) ) {
557
- $thread_depth = get_option( 'thread_comments_depth' );
558
- } else {
559
- // Perhaps filter this?
560
- $thread_depth = 1;
561
- }
562
-
563
- bp_blogs_update_blogmeta( $blog_id, 'close_comments_for_old_posts', get_option( 'close_comments_for_old_posts' ) );
564
- bp_blogs_update_blogmeta( $blog_id, 'close_comments_days_old', get_option( 'close_comments_days_old' ) );
565
- bp_blogs_update_blogmeta( $blog_id, 'thread_comments_depth', $thread_depth );
566
-
567
- restore_current_blog();
568
-
569
- // Check blogmeta and manually check activity item.
570
- // Basically a copy of _close_comments_for_old_post().
571
- } else {
572
-
573
- // Comments are closed.
574
- if ( 'closed' == bp_activity_get_meta( $activity->id, 'post_comment_status' ) ) {
575
- return false;
576
- }
577
-
578
- if ( ! bp_blogs_get_blogmeta( $blog_id, 'close_comments_for_old_posts' ) ) {
579
- return $open;
580
- }
581
-
582
- $days_old = (int) $days_old;
583
- if ( ! $days_old ) {
584
- return $open;
585
- }
586
-
587
- /*
588
- Commenting out for now - needs some more thought...
589
- should we add the post type to activity meta?
590
-
591
- $post = get_post($post_id);
592
-
593
- // This filter is documented in wp-includes/comment.php
594
- $post_types = apply_filters( 'close_comments_for_post_types', array( 'post' ) );
595
- if ( ! in_array( $post->post_type, $post_types ) )
596
- return $open;
597
- */
598
-
599
- if ( time() - strtotime( $activity->date_recorded ) > ( $days_old * DAY_IN_SECONDS ) ) {
600
- return false;
601
- }
602
-
603
- return $open;
604
- }
605
-
606
- return $open;
607
- }
608
-
609
- /** SITE TRACKING *******************************************************/
610
-
611
- /**
612
- * Add an activity entry for a newly-created site.
613
- *
614
- * Hooked to the 'bp_blogs_new_blog' action.
615
- *
616
- * @since 2.6.0
617
- *
618
- * @param BP_Blogs_Blog $recorded_blog Current site being recorded. Passed by reference.
619
- * @param bool $is_private Whether the current site being recorded is private.
620
- * @param bool $is_recorded Whether the current site was recorded.
621
- */
622
- function bp_blogs_record_activity_on_site_creation( $recorded_blog, $is_private, $is_recorded, $no_activity ) {
623
- // Only record this activity if the blog is public.
624
- if ( ! $is_private && ! $no_activity && bp_blogs_is_blog_trackable( $recorded_blog->blog_id, $recorded_blog->user_id ) ) {
625
- bp_blogs_record_activity( array(
626
- 'user_id' => $recorded_blog->user_id,
627
-
628
- /**
629
- * Filters the activity created blog primary link.
630
- *
631
- * @since 1.1.0
632
- *
633
- * @param string $value Blog primary link.
634
- * @param int $value Blog ID.
635
- */
636
- 'primary_link' => apply_filters( 'bp_blogs_activity_created_blog_primary_link', bp_blogs_get_blogmeta( $recorded_blog->blog_id, 'url' ), $recorded_blog->blog_id ),
637
- 'type' => 'new_blog',
638
- 'item_id' => $recorded_blog->blog_id
639
- ) );
640
- }
641
- }
642
- add_action( 'bp_blogs_new_blog', 'bp_blogs_record_activity_on_site_creation', 10, 4 );
643
-
644
- /**
645
- * Deletes the 'new_blog' activity entry when a site is deleted.
646
- *
647
- * @since 2.6.0
648
- *
649
- * @param int $blog_id Site ID.
650
- */
651
- function bp_blogs_delete_new_blog_activity_for_site( $blog_id, $user_id = 0 ) {
652
- $args = array(
653
- 'item_id' => $blog_id,
654
- 'component' => buddypress()->blogs->id,
655
- 'type' => 'new_blog'
656
- );
657
-
658
- /**
659
- * In the case a user is removed, make sure he is the author of the 'new_blog' activity
660
- * when trying to delete it.
661
- */
662
- if ( ! empty( $user_id ) ) {
663
- $args['user_id'] = $user_id;
664
- }
665
-
666
- bp_blogs_delete_activity( $args );
667
- }
668
- add_action( 'bp_blogs_remove_blog', 'bp_blogs_delete_new_blog_activity_for_site', 10, 1 );
669
- add_action( 'bp_blogs_remove_blog_for_user', 'bp_blogs_delete_new_blog_activity_for_site', 10, 2 );
670
-
671
- /**
672
- * Delete all 'blogs' activity items for a site when the site is deleted.
673
- *
674
- * @since 2.6.0
675
- *
676
- * @param int $blog_id Site ID.
677
- */
678
- function bp_blogs_delete_activity_for_site( $blog_id ) {
679
- bp_blogs_delete_activity( array(
680
- 'item_id' => $blog_id,
681
- 'component' => buddypress()->blogs->id,
682
- 'type' => false
683
- ) );
684
- }
685
- add_action( 'bp_blogs_remove_data_for_blog', 'bp_blogs_delete_activity_for_site' );
686
-
687
- /**
688
- * Remove a blog post activity item from the activity stream.
689
- *
690
- * @since 1.0.0
691
- *
692
- * @param int $post_id ID of the post to be removed.
693
- * @param int $blog_id Optional. Defaults to current blog ID.
694
- * @param int $user_id Optional. Defaults to the logged-in user ID. This param
695
- * is currently unused in the function (but is passed to hooks).
696
- * @return bool
697
- */
698
- function bp_blogs_remove_post( $post_id, $blog_id = 0, $user_id = 0 ) {
699
- global $wpdb;
700
-
701
- if ( empty( $wpdb->blogid ) ) {
702
- return false;
703
- }
704
-
705
- $post_id = (int) $post_id;
706
-
707
- if ( ! $blog_id ) {
708
- $blog_id = (int) $wpdb->blogid;
709
- }
710
-
711
- if ( ! $user_id ) {
712
- $user_id = bp_loggedin_user_id();
713
- }
714
-
715
- /**
716
- * Fires before removal of a blog post activity item from the activity stream.
717
- *
718
- * @since 1.5.0
719
- *
720
- * @param int $blog_id ID of the blog associated with the post that was removed.
721
- * @param int $post_id ID of the post that was removed.
722
- * @param int $user_id ID of the user having the blog removed for.
723
- */
724
- do_action( 'bp_blogs_before_remove_post', $blog_id, $post_id, $user_id );
725
-
726
- bp_blogs_delete_activity( array(
727
- 'item_id' => $blog_id,
728
- 'secondary_item_id' => $post_id,
729
- 'component' => buddypress()->blogs->id,
730
- 'type' => 'new_blog_post'
731
- ) );
732
-
733
- /**
734
- * Fires after removal of a blog post activity item from the activity stream.
735
- *
736
- * @since 1.0.0
737
- *
738
- * @param int $blog_id ID of the blog associated with the post that was removed.
739
- * @param int $post_id ID of the post that was removed.
740
- * @param int $user_id ID of the user having the blog removed for.
741
- */
742
- do_action( 'bp_blogs_remove_post', $blog_id, $post_id, $user_id );
743
- }
744
- add_action( 'delete_post', 'bp_blogs_remove_post' );
745
-
746
- /** POST COMMENT SYNCHRONIZATION ****************************************/
747
-
748
- /**
749
- * Syncs activity comments and posts them back as blog comments.
750
- *
751
- * Note: This is only a one-way sync - activity comments -> blog comment.
752
- *
753
- * For blog post -> activity comment, see {@link bp_activity_post_type_comment()}.
754
- *
755
- * @since 2.0.0
756
- * @since 2.5.0 Allow custom post types to sync their comments with activity ones
757
- *
758
- * @param int $comment_id The activity ID for the posted activity comment.
759
- * @param array $params Parameters for the activity comment.
760
- * @param object $parent_activity Parameters of the parent activity item (in this case, the blog post).
761
- */
762
- function bp_blogs_sync_add_from_activity_comment( $comment_id, $params, $parent_activity ) {
763
- // if parent activity isn't a post type having the buddypress-activity support, stop now!
764
- if ( ! bp_activity_type_supports( $parent_activity->type, 'post-type-comment-tracking' ) ) {
765
- return;
766
- }
767
-
768
- // If activity comments are disabled for blog posts, stop now!
769
- if ( bp_disable_blogforum_comments() ) {
770
- return;
771
- }
772
-
773
- // Do not sync if the activity comment was marked as spam.
774
- $activity = new BP_Activity_Activity( $comment_id );
775
- if ( $activity->is_spam ) {
776
- return;
777
- }
778
-
779
- // Get userdata.
780
- if ( $params['user_id'] == bp_loggedin_user_id() ) {
781
- $user = buddypress()->loggedin_user->userdata;
782
- } else {
783
- $user = bp_core_get_core_userdata( $params['user_id'] );
784
- }
785
-
786
- // Get associated post type and set default comment parent
787
- $post_type = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' );
788
- $comment_parent = 0;
789
-
790
- // See if a parent WP comment ID exists.
791
- if ( ! empty( $params['parent_id'] ) && ! empty( $post_type ) ) {
792
- $comment_parent = bp_activity_get_meta( $params['parent_id'], "bp_blogs_{$post_type}_comment_id" );
793
- }
794
-
795
- // Comment args.
796
- $args = array(
797
- 'comment_post_ID' => $parent_activity->secondary_item_id,
798
- 'comment_author' => bp_core_get_user_displayname( $params['user_id'] ),
799
- 'comment_author_email' => $user->user_email,
800
- 'comment_author_url' => bp_core_get_user_domain( $params['user_id'], $user->user_nicename, $user->user_login ),
801
- 'comment_content' => $params['content'],
802
- 'comment_type' => '', // Could be interesting to add 'buddypress' here...
803
- 'comment_parent' => (int) $comment_parent,
804
- 'user_id' => $params['user_id'],
805
- 'comment_approved' => 1
806
- );
807
-
808
- // Prevent separate activity entry being made.
809
- remove_action( 'comment_post', 'bp_activity_post_type_comment', 10 );
810
-
811
- // Handle multisite.
812
- switch_to_blog( $parent_activity->item_id );
813
-
814
- // Handle timestamps for the WP comment after we've switched to the blog.
815
- $args['comment_date'] = current_time( 'mysql' );
816
- $args['comment_date_gmt'] = current_time( 'mysql', 1 );
817
-
818
- // Post the comment.
819
- $post_comment_id = wp_insert_comment( $args );
820
-
821
- // Add meta to comment.
822
- add_comment_meta( $post_comment_id, 'bp_activity_comment_id', $comment_id );
823
-
824
- // Add meta to activity comment.
825
- if ( ! empty( $post_type ) ) {
826
- bp_activity_update_meta( $comment_id, "bp_blogs_{$post_type}_comment_id", $post_comment_id );
827
- }
828
-
829
- // Resave activity comment with WP comment permalink.
830
- //
831
- // in bp_blogs_activity_comment_permalink(), we change activity comment
832
- // permalinks to use the post comment link
833
- //
834
- // @todo since this is done after AJAX posting, the activity comment permalink
835
- // doesn't change on the front end until the next page refresh.
836
- $resave_activity = new BP_Activity_Activity( $comment_id );
837
- $resave_activity->primary_link = get_comment_link( $post_comment_id );
838
-
839
- /**
840
- * Now that the activity id exists and the post comment was created, we don't need to update
841
- * the content of the comment as there are no chances it has evolved.
842
- */
843
- remove_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
844
-
845
- $resave_activity->save();
846
-
847
- // Add the edit activity comment hook back.
848
- add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
849
-
850
- // Multisite again!
851
- restore_current_blog();
852
-
853
- // Add the comment hook back.
854
- add_action( 'comment_post', 'bp_activity_post_type_comment', 10, 2 );
855
-
856
- /**
857
- * Fires after activity comments have been synced and posted as blog comments.
858
- *
859
- * @since 2.0.0
860
- *
861
- * @param int $comment_id The activity ID for the posted activity comment.
862
- * @param array $args Array of args used for the comment syncing.
863
- * @param object $parent_activity Parameters of the blog post parent activity item.
864
- * @param object $user User data object for the blog comment.
865
- */
866
- do_action( 'bp_blogs_sync_add_from_activity_comment', $comment_id, $args, $parent_activity, $user );
867
- }
868
- add_action( 'bp_activity_comment_posted', 'bp_blogs_sync_add_from_activity_comment', 10, 3 );
869
-
870
- /**
871
- * Deletes the blog comment when the associated activity comment is deleted.
872
- *
873
- * Note: This is hooked on the 'bp_activity_delete_comment_pre' filter instead
874
- * of the 'bp_activity_delete_comment' action because we need to fetch the
875
- * activity comment children before they are deleted.
876
- *
877
- * @since 2.0.0
878
- * @since 2.5.0 Add the $delected parameter
879
- *
880
- * @param bool $retval Whether BuddyPress should continue or not.
881
- * @param int $parent_activity_id The parent activity ID for the activity comment.
882
- * @param int $activity_id The activity ID for the pending deleted activity comment.
883
- * @param bool $deleted Whether the comment was deleted or not.
884
- * @return bool
885
- */
886
- function bp_blogs_sync_delete_from_activity_comment( $retval, $parent_activity_id, $activity_id, &$deleted ) {
887
- // Check if parent activity is a blog post.
888
- $parent_activity = new BP_Activity_Activity( $parent_activity_id );
889
-
890
- // if parent activity isn't a post type having the buddypress-activity support, stop now!
891
- if ( ! bp_activity_type_supports( $parent_activity->type, 'post-type-comment-tracking' ) ) {
892
- return $retval;
893
- }
894
-
895
- // Fetch the activity comments for the activity item.
896
- $activity = bp_activity_get( array(
897
- 'in' => $activity_id,
898
- 'display_comments' => 'stream',
899
- 'spam' => 'all',
900
- ) );
901
-
902
- // Get all activity comment IDs for the pending deleted item.
903
- $activity_ids = bp_activity_recurse_comments_activity_ids( $activity );
904
- $activity_ids[] = $activity_id;
905
-
906
- // Handle multisite
907
- // switch to the blog where the comment was made.
908
- switch_to_blog( $parent_activity->item_id );
909
-
910
- // Remove associated blog comments.
911
- bp_blogs_remove_associated_blog_comments( $activity_ids, current_user_can( 'moderate_comments' ) );
912
-
913
- // Multisite again!
914
- restore_current_blog();
915
-
916
- // Rebuild activity comment tree
917
- // emulate bp_activity_delete_comment().
918
- BP_Activity_Activity::rebuild_activity_comment_tree( $parent_activity_id );
919
-
920
- // Avoid the error message although the comments were successfully deleted
921
- $deleted = true;
922
-
923
- // We're overriding the default bp_activity_delete_comment() functionality
924
- // so we need to return false.
925
- return false;
926
- }
927
- add_filter( 'bp_activity_delete_comment_pre', 'bp_blogs_sync_delete_from_activity_comment', 10, 4 );
928
-
929
- /**
930
- * Updates the blog comment when the associated activity comment is edited.
931
- *
932
- * @since 2.0.0
933
- *
934
- * @param BP_Activity_Activity $activity The activity object.
935
- */
936
- function bp_blogs_sync_activity_edit_to_post_comment( BP_Activity_Activity $activity ) {
937
- // This is a new entry, so stop!
938
- // We only want edits!
939
- if ( empty( $activity->id ) || bp_disable_blogforum_comments() ) {
940
- return;
941
- }
942
-
943
- // fetch parent activity item
944
- $parent_activity = new BP_Activity_Activity( $activity->item_id );
945
-
946
- // if parent activity isn't a post type having the buddypress-activity support for comments, stop now!
947
- if ( ! bp_activity_type_supports( $parent_activity->type, 'post-type-comment-tracking' ) ) {
948
- return;
949
- }
950
-
951
- $post_type = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' );
952
-
953
- // No associated post type for this activity comment, stop.
954
- if ( ! $post_type ) {
955
- return;
956
- }
957
-
958
- // Try to see if a corresponding blog comment exists.
959
- $post_comment_id = bp_activity_get_meta( $activity->id, "bp_blogs_{$post_type}_comment_id" );
960
-
961
- if ( empty( $post_comment_id ) ) {
962
- return;
963
- }
964
-
965
- // Handle multisite.
966
- switch_to_blog( $parent_activity->item_id );
967
-
968
- // Get the comment status
969
- $post_comment_status = wp_get_comment_status( $post_comment_id );
970
- $old_comment_status = $post_comment_status;
971
-
972
- // No need to edit the activity, as it's the activity who's updating the comment
973
- remove_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10 );
974
- remove_action( 'bp_activity_post_type_comment', 'bp_blogs_comment_sync_activity_comment', 10 );
975
-
976
- if ( 1 === $activity->is_spam && 'spam' !== $post_comment_status ) {
977
- wp_spam_comment( $post_comment_id );
978
- } elseif ( ! $activity->is_spam ) {
979
- if ( 'spam' === $post_comment_status ) {
980
- wp_unspam_comment( $post_comment_id );
981
- } elseif ( 'trash' === $post_comment_status ) {
982
- wp_untrash_comment( $post_comment_id );
983
- } else {
984
- // Update the blog post comment.
985
- wp_update_comment( array(
986
- 'comment_ID' => $post_comment_id,
987
- 'comment_content' => $activity->content,
988
- ) );
989
- }
990
- }
991
-
992
- // Restore actions
993
- add_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10, 3 );
994
- add_action( 'bp_activity_post_type_comment', 'bp_blogs_comment_sync_activity_comment', 10, 4 );
995
-
996
- restore_current_blog();
997
- }
998
- add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
999
-
1000
- /**
1001
- * When a post is trashed, remove each comment's associated activity meta.
1002
- *
1003
- * When a post is trashed and later untrashed, we currently don't reinstate
1004
- * activity items for these comments since their activity entries are already
1005
- * deleted when initially trashed.
1006
- *
1007
- * Since these activity entries are deleted, we need to remove the deleted
1008
- * activity comment IDs from each comment's meta when a post is trashed.
1009
- *
1010
- * @since 2.0.0
1011
- *
1012
- * @param int $post_id The post ID.
1013
- * @param array $comments Array of comment statuses. The key is comment ID, the
1014
- * value is the $comment->comment_approved value.
1015
- */
1016
- function bp_blogs_remove_activity_meta_for_trashed_comments( $post_id = 0, $comments = array() ) {
1017
- if ( ! empty( $comments ) ) {
1018
- foreach ( array_keys( $comments ) as $comment_id ) {
1019
- delete_comment_meta( $comment_id, 'bp_activity_comment_id' );
1020
- }
1021
- }
1022
- }
1023
- add_action( 'trashed_post_comments', 'bp_blogs_remove_activity_meta_for_trashed_comments', 10, 2 );
1024
-
1025
- /**
1026
- * Filter 'new_blog_comment' bp_has_activities() loop to include new- and old-style blog activity comment items.
1027
- *
1028
- * In BuddyPress 2.0, the schema for storing activity items related to blog
1029
- * posts changed. Instead creating new top-level 'new_blog_comment' activity
1030
- * items, blog comments are recorded in the activity stream as comments on the
1031
- * 'new_blog_post' activity items corresponding to the parent post. This filter
1032
- * ensures that the 'new_blog_comment' filter in bp_has_activities() (which
1033
- * powers the 'Comments' filter in the activity directory dropdown) includes
1034
- * both old-style and new-style activity comments.
1035
- *
1036
- * @since 2.1.0
1037
- * @since 2.5.0 Used for any synced Post type comments, in wp-admin or front-end contexts.
1038
- *
1039
- * @param array $args Arguments passed from bp_parse_args() in bp_has_activities().
1040
- * @return array $args
1041
- */
1042
- function bp_blogs_new_blog_comment_query_backpat( $args ) {
1043
- global $wpdb;
1044
- $bp = buddypress();
1045
-
1046
- // If activity comments are disabled for blog posts, stop now!
1047
- if ( bp_disable_blogforum_comments() ) {
1048
- return $args;
1049
- }
1050
-
1051
- // Get the associated post type
1052
- $post_type = bp_activity_post_type_get_tracking_arg( $args['action'], 'post_type' );
1053
-
1054
- // Bail if this is not an activity associated with a post type
1055
- if ( empty( $post_type ) ) {
1056
- return $args;
1057
- }
1058
-
1059
- // Bail if this is an activity about posts and not comments
1060
- if ( bp_activity_post_type_get_tracking_arg( $args['action'], 'comment_action_id' ) ) {
1061
- return $args;
1062
- }
1063
-
1064
- // Comment synced ?
1065
- $activity_ids = $wpdb->get_col( $wpdb->prepare( "SELECT activity_id FROM {$bp->activity->table_name_meta} WHERE meta_key = %s", "bp_blogs_{$post_type}_comment_id" ) );
1066
-
1067
- if ( empty( $activity_ids ) ) {
1068
- return $args;
1069
- }
1070
-
1071
- // Init the filter query.
1072
- $filter_query = array();
1073
-
1074
- if ( ! isset( $args['scope'] ) || 'null' === $args['scope'] ) {
1075
- $args['scope'] = '';
1076
- } elseif ( 'just-me' === $args['scope'] ) {
1077
- $filter_query = array(
1078
- 'relation' => 'AND',
1079
- array(
1080
- 'column' => 'user_id',
1081
- 'value' => bp_displayed_user_id(),
1082
- ),
1083
- );
1084
- $args['scope'] = '';
1085
- }
1086
-
1087
- $filter_query[] = array(
1088
- 'relation' => 'OR',
1089
- array(
1090
- 'column' => 'type',
1091
- 'value' => $args['action'],
1092
- ),
1093
- array(
1094
- 'column' => 'id',
1095
- 'value' => $activity_ids,
1096
- 'compare' => 'IN'
1097
- ),
1098
- );
1099
-
1100
- $args['filter_query'] = $filter_query;
1101
-
1102
- // Make sure to have comment in stream mode && avoid duplicate content.
1103
- $args['display_comments'] = 'stream';
1104
-
1105
- // Finally reset the action.
1106
- $args['action'] = '';
1107
- $args['type'] = '';
1108
-
1109
- // Return the original arguments.
1110
- return $args;
1111
- }
1112
- add_filter( 'bp_after_has_activities_parse_args', 'bp_blogs_new_blog_comment_query_backpat' );
1113
- add_filter( 'bp_activity_list_table_filter_activity_type_items', 'bp_blogs_new_blog_comment_query_backpat' );
1114
-
1115
- /**
1116
- * Utility function to set up some variables for use in the activity loop.
1117
- *
1118
- * Grabs the blog's comment depth and the post's open comment status options
1119
- * for later use in the activity and activity comment loops.
1120
- *
1121
- * This is to prevent having to requery these items later on.
1122
- *
1123
- * @since 2.0.0
1124
- *
1125
- * @see bp_blogs_disable_activity_commenting()
1126
- * @see bp_blogs_setup_comment_loop_globals_on_ajax()
1127
- *
1128
- * @param object $activity The BP_Activity_Activity object.
1129
- */
1130
- function bp_blogs_setup_activity_loop_globals( $activity ) {
1131
- if ( ! is_object( $activity ) ) {
1132
- return;
1133
- }
1134
-
1135
- // The activity type does not support comments or replies ? stop now!
1136
- if ( ! bp_activity_type_supports( $activity->type, 'post-type-comment-reply' ) ) {
1137
- return;
1138
- }
1139
-
1140
- if ( empty( $activity->id ) ) {
1141
- return;
1142
- }
1143
-
1144
- // If we've already done this before, stop now!
1145
- if ( isset( buddypress()->blogs->allow_comments[ $activity->id ] ) ) {
1146
- return;
1147
- }
1148
-
1149
- $allow_comments = bp_blogs_comments_open( $activity );
1150
- $thread_depth = bp_blogs_get_blogmeta( $activity->item_id, 'thread_comments_depth' );
1151
-
1152
- // Initialize a local object so we won't have to query this again in the
1153
- // comment loop.
1154
- if ( empty( buddypress()->blogs->allow_comments ) ) {
1155
- buddypress()->blogs->allow_comments = array();
1156
- }
1157
- if ( empty( buddypress()->blogs->thread_depth ) ) {
1158
- buddypress()->blogs->thread_depth = array();
1159
- }
1160
-
1161
- // Cache comment settings in the buddypress() singleton to reference later in
1162
- // the activity comment loop
1163
- // @see bp_blogs_disable_activity_replies()
1164
- //
1165
- // thread_depth is keyed by activity ID instead of blog ID because when we're
1166
- // in a comment loop, we don't have access to the blog ID...
1167
- // should probably object cache these values instead...
1168
- buddypress()->blogs->allow_comments[ $activity->id ] = $allow_comments;
1169
- buddypress()->blogs->thread_depth[ $activity->id ] = $thread_depth;
1170
- }
1171
-
1172
- /**
1173
- * Set up some globals used in the activity comment loop when AJAX is used.
1174
- *
1175
- * @since 2.0.0
1176
- *
1177
- * @see bp_blogs_setup_activity_loop_globals()
1178
- */
1179
- function bp_blogs_setup_comment_loop_globals_on_ajax() {
1180
- // Not AJAX? stop now!
1181
- if ( ! defined( 'DOING_AJAX' ) ) {
1182
- return;
1183
- }
1184
- if ( false === (bool) constant( 'DOING_AJAX' ) ) {
1185
- return;
1186
- }
1187
-
1188
- // Get the parent activity item.
1189
- $comment = bp_activity_current_comment();
1190
- $parent_activity = new BP_Activity_Activity( $comment->item_id );
1191
-
1192
- // Setup the globals.
1193
- bp_blogs_setup_activity_loop_globals( $parent_activity );
1194
- }
1195
- add_action( 'bp_before_activity_comment', 'bp_blogs_setup_comment_loop_globals_on_ajax' );
1196
-
1197
- /**
1198
- * Disable activity commenting for blog posts based on certain criteria.
1199
- *
1200
- * If activity commenting is enabled for blog posts, we still need to disable
1201
- * commenting if:
1202
- * - comments are disabled for the WP blog post from the admin dashboard
1203
- * - the WP blog post is supposed to be automatically closed from comments
1204
- * based on a certain age
1205
- * - the activity entry is a 'new_blog_comment' type
1206
- *
1207
- * @since 2.0.0
1208
- *
1209
- * @param bool $retval Is activity commenting enabled for this activity entry.
1210
- * @return bool
1211
- */
1212
- function bp_blogs_disable_activity_commenting( $retval ) {
1213
- global $activities_template;
1214
-
1215
- // If activity commenting is disabled, return current value.
1216
- if ( bp_disable_blogforum_comments() || ! isset( $activities_template->in_the_loop ) ) {
1217
- return $retval;
1218
- }
1219
-
1220
- $type = bp_get_activity_type();
1221
-
1222
- // It's a post type supporting comment tracking.
1223
- if ( bp_activity_type_supports( $type, 'post-type-comment-tracking' ) ) {
1224
- // The activity type is supporting comments or replies
1225
- if ( bp_activity_type_supports( $type, 'post-type-comment-reply' ) ) {
1226
- // Setup some globals we'll need to reference later.
1227
- bp_blogs_setup_activity_loop_globals( $activities_template->activity );
1228
-
1229
- // If comments are closed for the WP blog post, we should disable
1230
- // activity comments for this activity entry.
1231
- if ( empty( buddypress()->blogs->allow_comments[ bp_get_activity_id() ] ) ) {
1232
- $retval = false;
1233
- }
1234
- // The activity type does not support comments or replies
1235
- } else {
1236
- $retval = false;
1237
- }
1238
- }
1239
-
1240
- return $retval;
1241
- }
1242
- add_filter( 'bp_activity_can_comment', 'bp_blogs_disable_activity_commenting' );
1243
-
1244
- /**
1245
- * Limit the display of post type synced comments.
1246
- *
1247
- * @since 2.5.0
1248
- *
1249
- * When viewing the synced comments in stream mode, this prevents comments to
1250
- * be displayed twice, and avoids a Javascript error as the form to add replies
1251
- * is not available.
1252
- *
1253
- * @param int $retval The comment count for the activity.
1254
- * @return int The comment count, or 0 to hide activity comment replies.
1255
- */
1256
- function bp_blogs_post_type_comments_avoid_duplicates( $retval ) {
1257
- /**
1258
- * Only limit the display when Post type comments are synced with
1259
- * activity comments.
1260
- */
1261
- if ( bp_disable_blogforum_comments() ) {
1262
- return $retval;
1263
- }
1264
-
1265
- if ( 'activity_comment' !== bp_get_activity_type() ) {
1266
- return $retval;
1267
- }
1268
-
1269
- // Check the parent activity
1270
- $parent_activity = new BP_Activity_Activity( bp_get_activity_item_id() );
1271
-
1272
- if ( isset( $parent_activity->type ) && bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' ) ) {
1273
- $retval = 0;
1274
- }
1275
-
1276
- return $retval;
1277
- }
1278
- add_filter( 'bp_activity_get_comment_count', 'bp_blogs_post_type_comments_avoid_duplicates' );
1279
-
1280
- /**
1281
- * Check if an activity comment associated with a blog post can be replied to.
1282
- *
1283
- * By default, disables replying to activity comments if the corresponding WP
1284
- * blog post no longer accepts comments.
1285
- *
1286
- * This check uses a locally-cached value set in {@link bp_blogs_disable_activity_commenting()}
1287
- * via {@link bp_blogs_setup_activity_loop_globals()}.
1288
- *
1289
- * @since 2.0.0
1290
- *
1291
- * @param bool $retval Are replies allowed for this activity reply.
1292
- * @param object|array $comment The activity comment object.
1293
- *
1294
- * @return bool
1295
- */
1296
- function bp_blogs_can_comment_reply( $retval, $comment ) {
1297
- if ( is_array( $comment ) ) {
1298
- $comment = (object) $comment;
1299
- }
1300
-
1301
- // Check comment depth and disable if depth is too large.
1302
- if ( isset( buddypress()->blogs->thread_depth[$comment->item_id] ) ){
1303
- if ( bp_activity_get_comment_depth( $comment ) >= buddypress()->blogs->thread_depth[$comment->item_id] ) {
1304
- $retval = false;
1305
- }
1306
- }
1307
-
1308
- // Check if we should disable activity replies based on the parent activity.
1309
- if ( isset( buddypress()->blogs->allow_comments[$comment->item_id] ) ){
1310
- // The blog post has closed off commenting, so we should disable all activity
1311
- // comments under the parent 'new_blog_post' activity entry.
1312
- if ( empty( buddypress()->blogs->allow_comments[$comment->item_id] ) ) {
1313
- $retval = false;
1314
- }
1315
- }
1316
-
1317
- return $retval;
1318
- }
1319
- add_filter( 'bp_activity_can_comment_reply', 'bp_blogs_can_comment_reply', 10, 2 );
1320
-
1321
- /**
1322
- * Changes activity comment permalinks to use the blog comment permalink
1323
- * instead of the activity permalink.
1324
- *
1325
- * This is only done if activity commenting is allowed and whether the parent
1326
- * activity item is a 'new_blog_post' entry.
1327
- *
1328
- * @since 2.0.0
1329
- *
1330
- * @param string $retval The activity comment permalink.
1331
- * @return string
1332
- */
1333
- function bp_blogs_activity_comment_permalink( $retval = '' ) {
1334
- global $activities_template;
1335
-
1336
- // Get the current comment ID.
1337
- $item_id = isset( $activities_template->activity->current_comment->item_id )
1338
- ? $activities_template->activity->current_comment->item_id
1339
- : false;
1340
-
1341
- // Maybe adjust the link if item ID exists.
1342
- if ( ( false !== $item_id ) && isset( buddypress()->blogs->allow_comments[ $item_id ] ) ) {
1343
- $retval = $activities_template->activity->current_comment->primary_link;
1344
- }
1345
-
1346
- return $retval;
1347
- }
1348
- add_filter( 'bp_get_activity_comment_permalink', 'bp_blogs_activity_comment_permalink' );
1349
-
1350
- /**
1351
- * Changes single activity comment entries to use the blog comment permalink.
1352
- *
1353
- * This is only done if the activity comment is associated with a blog comment.
1354
- *
1355
- * @since 2.0.1
1356
- *
1357
- * @param string $retval The activity permalink.
1358
- * @param BP_Activity_Activity $activity Activity object.
1359
- * @return string
1360
- */
1361
- function bp_blogs_activity_comment_single_permalink( $retval, $activity ) {
1362
- if ( 'activity_comment' !== $activity->type ) {
1363
- return $retval;
1364
- }
1365
-
1366
- if ( bp_disable_blogforum_comments() ) {
1367
- return $retval;
1368
- }
1369
-
1370
- $parent_activity = new BP_Activity_Activity( $activity->item_id );
1371
-
1372
- if ( isset( $parent_activity->type ) && bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' ) ) {
1373
- $retval = $activity->primary_link;
1374
- }
1375
-
1376
- return $retval;
1377
- }
1378
- add_filter( 'bp_activity_get_permalink', 'bp_blogs_activity_comment_single_permalink', 10, 2 );
1379
-
1380
- /**
1381
- * Formats single activity comment entries to use the blog comment action.
1382
- *
1383
- * This is only done if the activity comment is associated with a blog comment.
1384
- *
1385
- * @since 2.0.1
1386
- *
1387
- * @param string $retval The activity action.
1388
- * @param BP_Activity_Activity $activity Activity object.
1389
- * @return string
1390
- */
1391
- function bp_blogs_activity_comment_single_action( $retval, $activity ) {
1392
- if ( 'activity_comment' !== $activity->type ) {
1393
- return $retval;
1394
- }
1395
-
1396
- if ( bp_disable_blogforum_comments() ) {
1397
- return $retval;
1398
- }
1399
-
1400
- $parent_activity = new BP_Activity_Activity( $activity->item_id );
1401
-
1402
- if ( ! isset( $parent_activity->type ) ) {
1403
- return $retval;
1404
- }
1405
-
1406
- $post_type = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' );
1407
-
1408
- if ( ! $post_type ) {
1409
- return $retval;
1410
- }
1411
-
1412
- $blog_comment_id = bp_activity_get_meta( $activity->id, "bp_blogs_{$post_type}_comment_id" );
1413
-
1414
- if ( ! empty( $blog_comment_id ) ) {
1415
- $bp = buddypress();
1416
-
1417
- // Check if a comment action id is set for the parent activity
1418
- $comment_action_id = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'comment_action_id' );
1419
-
1420
- // Use the action string callback for the activity type
1421
- if ( ! empty( $comment_action_id ) ) {
1422
- // Fake a 'new_{post_type}_comment' by cloning the activity object.
1423
- $object = clone $activity;
1424
-
1425
- // Set the type of the activity to be a comment about a post type
1426
- $object->type = $comment_action_id;
1427
-
1428
- // Use the blog ID as the item_id.
1429
- $object->item_id = $parent_activity->item_id;
1430
-
1431
- // Use comment ID as the secondary_item_id.
1432
- $object->secondary_item_id = $blog_comment_id;
1433
-
1434
- // Get the format callback for this activity comment
1435
- $format_callback = bp_activity_post_type_get_tracking_arg( $comment_action_id, 'format_callback' );
1436
-
1437
- // now format the activity action using the 'new_{post_type}_comment' action callback
1438
- if ( is_callable( $format_callback ) ) {
1439
- $retval = call_user_func_array( $format_callback, array( '', $object ) );
1440
- }
1441
- }
1442
- }
1443
-
1444
- return $retval;
1445
- }
1446
- add_filter( 'bp_get_activity_action_pre_meta', 'bp_blogs_activity_comment_single_action', 10, 2 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-blogs/bp-blogs-cache.php DELETED
@@ -1,68 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Blogs Caching.
4
- *
5
- * Caching functions handle the clearing of cached objects and pages on specific
6
- * actions throughout BuddyPress.
7
- *
8
- * @package BuddyPress
9
- * @subpackage BlogsCache
10
- * @since 1.5.0
11
- */
12
-
13
- // Exit if accessed directly.
14
- defined( 'ABSPATH' ) || exit;
15
-
16
- /**
17
- * Slurp up blogmeta for a specified set of blogs.
18
- *
19
- * It grabs all blogmeta associated with all of the blogs passed
20
- * in $blog_ids and adds it to the WP cache. This improves efficiency when
21
- * using querying blogmeta inline.
22
- *
23
- * @param int|string|array|bool $blog_ids Accepts a single blog ID, or a comma-
24
- * separated list or array of blog IDs.
25
- */
26
- function bp_blogs_update_meta_cache( $blog_ids = false ) {
27
- $cache_args = array(
28
- 'object_ids' => $blog_ids,
29
- 'object_type' => buddypress()->blogs->id,
30
- 'object_column' => 'blog_id',
31
- 'cache_group' => 'blog_meta',
32
- 'meta_table' => buddypress()->blogs->table_name_blogmeta,
33
- );
34
-
35
- bp_update_meta_cache( $cache_args );
36
- }
37
- /**
38
- * Clear the blog object cache.
39
- *
40
- * @since 1.0.0
41
- *
42
- * @param int $blog_id ID of the current blog.
43
- * @param int $user_id ID of the user whose blog cache should be cleared.
44
- */
45
- function bp_blogs_clear_blog_object_cache( $blog_id = 0, $user_id = 0 ) {
46
- if ( ! empty( $user_id ) ) {
47
- wp_cache_delete( 'bp_blogs_of_user_' . $user_id, 'bp' );
48
- wp_cache_delete( 'bp_total_blogs_for_user_' . $user_id, 'bp' );
49
- }
50
-
51
- wp_cache_delete( 'bp_total_blogs', 'bp' );
52
- }
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.
60
- add_action( 'bp_blogs_remove_data_for_blog', 'bp_core_clear_cache' );
61
- add_action( 'bp_blogs_remove_comment', 'bp_core_clear_cache' );
62
- add_action( 'bp_blogs_remove_post', 'bp_core_clear_cache' );
63
- add_action( 'bp_blogs_remove_blog_for_user', 'bp_core_clear_cache' );
64
- add_action( 'bp_blogs_remove_blog', 'bp_core_clear_cache' );
65
- add_action( 'bp_blogs_new_blog_comment', 'bp_core_clear_cache' );
66
- add_action( 'bp_blogs_new_blog_post', 'bp_core_clear_cache' );
67
- add_action( 'bp_blogs_new_blog', 'bp_core_clear_cache' );
68
- add_action( 'bp_blogs_remove_data', 'bp_core_clear_cache' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-blogs/bp-blogs-classes.php ADDED
@@ -0,0 +1,313 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ Class BP_Blogs_Blog {
4
+ var $id;
5
+ var $user_id;
6
+ var $blog_id;
7
+
8
+ function bp_blogs_blog( $id = null ) {
9
+ global $bp, $wpdb;
10
+
11
+ if ( !$user_id )
12
+ $user_id = $bp->displayed_user->id;
13
+
14
+ if ( $id ) {
15
+ $this->id = $id;
16
+ $this->populate();
17
+ }
18
+ }
19
+
20
+ function populate() {
21
+ global $wpdb, $bp;
22
+
23
+ $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->blogs->table_name} WHERE id = %d", $this->id ) );
24
+
25
+ $this->user_id = $blog->user_id;
26
+ $this->blog_id = $blog->blog_id;
27
+ }
28
+
29
+ function save() {
30
+ global $wpdb, $bp;
31
+
32
+ $this->user_id = apply_filters( 'bp_blogs_blog_user_id_before_save', $this->user_id, $this->id );
33
+ $this->blog_id = apply_filters( 'bp_blogs_blog_id_before_save', $this->blog_id, $this->id );
34
+
35
+ do_action( 'bp_blogs_blog_before_save', $this );
36
+
37
+ // Don't try and save if there is no user ID or blog ID set.
38
+ if ( !$this->user_id || !$this->blog_id )
39
+ return false;
40
+
41
+ // Don't save if this blog has already been recorded for the user.
42
+ if ( !$this->id && $this->exists() )
43
+ return false;
44
+
45
+ if ( $this->id ) {
46
+ // Update
47
+ $sql = $wpdb->prepare( "UPDATE {$bp->blogs->table_name} SET user_id = %d, blog_id = %d WHERE id = %d", $this->user_id, $this->blog_id, $this->id );
48
+ } else {
49
+ // Save
50
+ $sql = $wpdb->prepare( "INSERT INTO {$bp->blogs->table_name} ( user_id, blog_id ) VALUES ( %d, %d )", $this->user_id, $this->blog_id );
51
+ }
52
+
53
+ if ( !$wpdb->query($sql) )
54
+ return false;
55
+
56
+ do_action( 'bp_blogs_blog_after_save', $this );
57
+
58
+ if ( $this->id )
59
+ return $this->id;
60
+ else
61
+ return $wpdb->insert_id;
62
+ }
63
+
64
+ function exists() {
65
+ global $bp, $wpdb;
66
+
67
+ return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->blogs->table_name} WHERE user_id = %d AND blog_id = %d", $this->user_id, $this->blog_id ) );
68
+ }
69
+
70
+ /* Static Functions */
71
+
72
+ function get( $type, $limit = false, $page = false, $user_id = false, $search_terms = false ) {
73
+ global $bp, $wpdb;
74
+
75
+ if ( !$bp->blogs )
76
+ bp_blogs_setup_globals();
77
+
78
+ if ( !is_user_logged_in() || ( !is_super_admin() && ( $user_id != $bp->loggedin_user->id ) ) )
79
+ $hidden_sql = "AND wb.public = 1";
80
+
81
+ if ( $limit && $page )
82
+ $pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
83
+
84
+ if ( $user_id )
85
+ $user_sql = $wpdb->prepare( " AND b.user_id = %d", $user_id );
86
+
87
+ switch ( $type ) {
88
+ case 'active': default:
89
+ $order_sql = "ORDER BY bm.meta_value DESC";
90
+ break;
91
+ case 'alphabetical':
92
+ $order_sql = "ORDER BY bm2.meta_value ASC";
93
+ break;
94
+ case 'newest':
95
+ $order_sql = "ORDER BY wb.registered DESC";
96
+ break;
97
+ case 'random':
98
+ $order_sql = "ORDER BY RAND()";
99
+ break;
100
+ }
101
+
102
+ if ( !empty( $search_terms ) ) {
103
+ $filter = like_escape( $wpdb->escape( $search_terms ) );
104
+ $paged_blogs = $wpdb->get_results( "SELECT b.blog_id, b.user_id as admin_user_id, u.user_email as admin_user_email, wb.domain, wb.path, bm.meta_value as last_activity, bm2.meta_value as name FROM {$bp->blogs->table_name} b, {$bp->blogs->table_name_blogmeta} bm, {$bp->blogs->table_name_blogmeta} bm2, {$wpdb->base_prefix}blogs wb, {$wpdb->users} u WHERE b.blog_id = wb.blog_id AND b.user_id = u.ID AND b.blog_id = bm.blog_id AND b.blog_id = bm2.blog_id AND wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$hidden_sql} AND bm.meta_key = 'last_activity' AND bm2.meta_key = 'name' AND bm2.meta_value LIKE '%%$filter%%' {$user_sql} GROUP BY b.blog_id {$order_sql} {$pag_sql}" );
105
+ $total_blogs = $wpdb->get_var( "SELECT COUNT(DISTINCT b.blog_id) FROM {$bp->blogs->table_name} b, {$wpdb->base_prefix}blogs wb, {$bp->blogs->table_name_blogmeta} bm, {$bp->blogs->table_name_blogmeta} bm2 WHERE b.blog_id = wb.blog_id AND bm.blog_id = b.blog_id AND bm2.blog_id = b.blog_id AND wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$hidden_sql} AND bm.meta_key = 'name' AND bm2.meta_key = 'description' AND ( bm.meta_value LIKE '%%$filter%%' || bm2.meta_value LIKE '%%$filter%%' ) {$user_sql}" );
106
+ } else {
107
+ $paged_blogs = $wpdb->get_results( $wpdb->prepare( "SELECT b.blog_id, b.user_id as admin_user_id, u.user_email as admin_user_email, wb.domain, wb.path, bm.meta_value as last_activity, bm2.meta_value as name FROM {$bp->blogs->table_name} b, {$bp->blogs->table_name_blogmeta} bm, {$bp->blogs->table_name_blogmeta} bm2, {$wpdb->base_prefix}blogs wb, {$wpdb->users} u WHERE b.blog_id = wb.blog_id AND b.user_id = u.ID AND b.blog_id = bm.blog_id AND b.blog_id = bm2.blog_id {$user_sql} AND wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$hidden_sql} AND bm.meta_key = 'last_activity' AND bm2.meta_key = 'name' GROUP BY b.blog_id {$order_sql} {$pag_sql}" ) );
108
+ $total_blogs = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT b.blog_id) FROM {$bp->blogs->table_name} b, {$wpdb->base_prefix}blogs wb WHERE b.blog_id = wb.blog_id {$user_sql} AND wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$hidden_sql}" ) );
109
+ }
110
+
111
+ foreach ( (array)$paged_blogs as $blog ) $blog_ids[] = $blog->blog_id;
112
+ $blog_ids = $wpdb->escape( join( ',', (array)$blog_ids ) );
113
+ $paged_blogs = BP_Blogs_Blog::get_blog_extras( &$paged_blogs, $blog_ids, $type );
114
+
115
+ return array( 'blogs' => $paged_blogs, 'total' => $total_blogs );
116
+ }
117
+
118
+ function delete_blog_for_all( $blog_id ) {
119
+ global $wpdb, $bp;
120
+
121
+ if ( !$bp->blogs )
122
+ bp_blogs_setup_globals();
123
+
124
+ bp_blogs_delete_blogmeta( $blog_id );
125
+
126
+ return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name} WHERE blog_id = %d", $blog_id ) );
127
+ }
128
+
129
+ function delete_blog_for_user( $blog_id, $user_id = null ) {
130
+ global $wpdb, $bp;
131
+
132
+ if ( !$bp->blogs )
133
+ bp_blogs_setup_globals();
134
+
135
+ if ( !$user_id )
136
+ $user_id = $bp->loggedin_user->id;
137
+
138
+ return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name} WHERE user_id = %d AND blog_id = %d", $user_id, $blog_id ) );
139
+ }
140
+
141
+ function delete_blogs_for_user( $user_id = null ) {
142
+ global $wpdb, $bp;
143
+
144
+ if ( !$bp->blogs )
145
+ bp_blogs_setup_globals();
146
+
147
+ if ( !$user_id )
148
+ $user_id = $bp->loggedin_user->id;
149
+
150
+ return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name} WHERE user_id = %d", $user_id ) );
151
+ }
152
+
153
+ function get_blogs_for_user( $user_id = false, $show_hidden = false ) {
154
+ global $bp, $wpdb;
155
+
156
+ if ( !$bp->blogs )
157
+ bp_blogs_setup_globals();
158
+
159
+ if ( !$user_id )
160
+ $user_id = $bp->displayed_user->id;
161
+
162
+ // Show logged in users their hidden blogs.
163
+ if ( !bp_is_my_profile() && !$show_hidden )
164
+ $blogs = $wpdb->get_results( $wpdb->prepare( "SELECT DISTINCT b.blog_id, b.id, bm1.meta_value as name, wb.domain, wb.path FROM {$bp->blogs->table_name} b, {$wpdb->base_prefix}blogs wb, {$bp->blogs->table_name_blogmeta} bm1 WHERE b.blog_id = wb.blog_id AND b.blog_id = bm1.blog_id AND bm1.meta_key = 'name' AND wb.public = 1 AND wb.deleted = 0 AND wb.spam = 0 AND wb.mature = 0 AND wb.archived = '0' AND b.user_id = %d ORDER BY b.blog_id", $user_id ) );
165
+ else
166
+ $blogs = $wpdb->get_results( $wpdb->prepare( "SELECT DISTINCT b.blog_id, b.id, bm1.meta_value as name, wb.domain, wb.path FROM {$bp->blogs->table_name} b, {$wpdb->base_prefix}blogs wb, {$bp->blogs->table_name_blogmeta} bm1 WHERE b.blog_id = wb.blog_id AND b.blog_id = bm1.blog_id AND bm1.meta_key = 'name' AND wb.deleted = 0 AND wb.spam = 0 AND wb.mature = 0 AND wb.archived = '0' AND b.user_id = %d ORDER BY b.blog_id", $user_id ) );
167
+
168
+ $total_blog_count = BP_Blogs_Blog::total_blog_count_for_user( $user_id );
169
+
170
+ foreach ( (array)$blogs as $blog ) {
171
+ $user_blogs[$blog->blog_id] = new stdClass;
172
+ $user_blogs[$blog->blog_id]->id = $blog->id;
173
+ $user_blogs[$blog->blog_id]->blog_id = $blog->blog_id;
174
+ $user_blogs[$blog->blog_id]->siteurl = ( is_ssl() ) ? 'https://' . $blog->domain . $blog->path : 'http://' . $blog->domain . $blog->path;
175
+ $user_blogs[$blog->blog_id]->name = $blog->name;
176
+ }
177
+
178
+ return array( 'blogs' => $user_blogs, 'count' => $total_blog_count );
179
+ }
180
+
181
+ function get_blog_ids_for_user( $user_id = false ) {
182
+ global $bp, $wpdb;
183
+
184
+ if ( !$bp->blogs )
185
+ bp_blogs_setup_globals();
186
+
187
+ if ( !$user_id )
188
+ $user_id = $bp->displayed_user->id;
189
+
190
+ return $wpdb->get_col( $wpdb->prepare( "SELECT blog_id FROM {$bp->blogs->table_name} WHERE user_id = %d", $user_id ) );
191
+ }
192
+
193
+ function is_recorded( $blog_id ) {
194
+ global $bp, $wpdb;
195
+
196
+ if ( !$bp->blogs )
197
+ bp_blogs_setup_globals();
198
+
199
+ return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->blogs->table_name} WHERE blog_id = %d", $blog_id ) );
200
+ }
201
+
202
+ function total_blog_count_for_user( $user_id = null ) {
203
+ global $bp, $wpdb;
204
+
205
+ if ( !$bp->blogs )
206
+ bp_blogs_setup_globals();
207
+
208
+ if ( !$user_id )
209
+ $user_id = $bp->displayed_user->id;
210
+
211
+ // If the user is logged in return the blog count including their hidden blogs.
212
+ if ( ( is_user_logged_in() && $user_id == $bp->loggedin_user->id ) || is_super_admin() )
213
+ return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT b.blog_id) FROM {$bp->blogs->table_name} b LEFT JOIN {$wpdb->base_prefix}blogs wb ON b.blog_id = wb.blog_id WHERE wb.deleted = 0 AND wb.spam = 0 AND wb.mature = 0 AND wb.archived = '0' AND user_id = %d", $user_id) );
214
+ else
215
+ return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT b.blog_id) FROM {$bp->blogs->table_name} b LEFT JOIN {$wpdb->base_prefix}blogs wb ON b.blog_id = wb.blog_id WHERE wb.public = 1 AND wb.deleted = 0 AND wb.spam = 0 AND wb.mature = 0 AND wb.archived = '0' AND user_id = %d", $user_id) );
216
+ }
217
+
218
+ function search_blogs( $filter, $limit = null, $page = null ) {
219
+ global $wpdb, $bp;
220
+
221
+ if ( !$bp->blogs )
222
+ bp_blogs_setup_globals();
223
+
224
+ $filter = like_escape( $wpdb->escape( $filter ) );
225
+
226
+ if ( !is_super_admin() )
227
+ $hidden_sql = "AND wb.public = 1";
228
+
229
+ if ( $limit && $page )
230
+ $pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
231
+
232
+ $paged_blogs = $wpdb->get_results( "SELECT DISTINCT bm.blog_id FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE ( ( bm.meta_key = 'name' OR bm.meta_key = 'description' ) AND bm.meta_value LIKE '%%$filter%%' ) {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY meta_value ASC{$pag_sql}" );
233
+ $total_blogs = $wpdb->get_var( "SELECT COUNT(DISTINCT bm.blog_id) FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE ( ( bm.meta_key = 'name' OR bm.meta_key = 'description' ) AND bm.meta_value LIKE '%%$filter%%' ) {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY meta_value ASC" );
234
+
235
+ return array( 'blogs' => $paged_blogs, 'total' => $total_blogs );
236
+ }
237
+
238
+ function get_all( $limit = null, $page = null ) {
239
+ global $bp, $wpdb;
240
+
241
+ if ( !$bp->blogs )
242
+ bp_blogs_setup_globals();
243
+
244
+ if ( !is_super_admin() )
245
+ $hidden_sql = "AND wb.public = 1";
246
+
247
+ if ( $limit && $page )
248
+ $pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
249
+
250
+ $paged_blogs = $wpdb->get_results( $wpdb->prepare( "SELECT DISTINCT b.blog_id FROM {$bp->blogs->table_name} b LEFT JOIN {$wpdb->base_prefix}blogs wb ON b.blog_id = wb.blog_id WHERE wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 {$hidden_sql} {$pag_sql}" ) );
251
+ $total_blogs = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT b.blog_id) FROM {$bp->blogs->table_name} b LEFT JOIN {$wpdb->base_prefix}blogs wb ON b.blog_id = wb.blog_id WHERE wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 {$hidden_sql}" ) );
252
+
253
+ return array( 'blogs' => $paged_blogs, 'total' => $total_blogs );
254
+ }
255
+
256
+ function get_by_letter( $letter, $limit = null, $page = null ) {
257
+ global $bp, $wpdb;
258
+
259
+ if ( !$bp->blogs )
260
+ bp_blogs_setup_globals();
261
+
262
+ $letter = like_escape( $wpdb->escape( $letter ) );
263
+
264
+ if ( !is_super_admin() )
265
+ $hidden_sql = "AND wb.public = 1";
266
+
267
+ if ( $limit && $page )
268
+ $pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
269
+
270
+ $paged_blogs = $wpdb->get_results( $wpdb->prepare( "SELECT DISTINCT bm.blog_id FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE bm.meta_key = 'name' AND bm.meta_value LIKE '$letter%%' {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY bm.meta_value ASC{$pag_sql}" ) );
271
+ $total_blogs = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT bm.blog_id) FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE bm.meta_key = 'name' AND bm.meta_value LIKE '$letter%%' {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY bm.meta_value ASC" ) );
272
+
273
+ return array( 'blogs' => $paged_blogs, 'total' => $total_blogs );
274
+ }
275
+
276
+ function get_blog_extras( $paged_blogs, $blog_ids, $type = false ) {
277
+ global $bp, $wpdb;
278
+
279
+ if ( empty( $blog_ids ) )
280
+ return $paged_blogs;
281
+
282
+ for ( $i = 0; $i < count( $paged_blogs ); $i++ ) {
283
+ $blog_prefix = $wpdb->get_blog_prefix( $paged_blogs[$i]->blog_id );
284
+ $paged_blogs[$i]->latest_post = $wpdb->get_row( "SELECT post_title, guid FROM {$blog_prefix}posts WHERE post_status = 'publish' AND post_type = 'post' AND id != 1 ORDER BY id DESC LIMIT 1" );
285
+ }
286
+
287
+ /* Fetch the blog description for each blog (as it may be empty we can't fetch it in the main query). */
288
+ $blog_descs = $wpdb->get_results( $wpdb->prepare( "SELECT blog_id, meta_value as description FROM {$bp->blogs->table_name_blogmeta} WHERE meta_key = 'description' AND blog_id IN ( {$blog_ids} )" ) );
289
+
290
+ for ( $i = 0; $i < count( $paged_blogs ); $i++ ) {
291
+ foreach ( (array)$blog_descs as $desc ) {
292
+ if ( $desc->blog_id == $paged_blogs[$i]->blog_id )
293
+ $paged_blogs[$i]->description = $desc->description;
294
+ }
295
+ }
296
+
297
+ return $paged_blogs;
298
+ }
299
+
300
+ function is_hidden( $blog_id ) {
301
+ global $wpdb;
302
+
303
+ if ( !$bp->blogs )
304
+ bp_blogs_setup_globals();
305
+
306
+ if ( !(int)$wpdb->get_var( $wpdb->prepare( "SELECT DISTINCT public FROM {$wpdb->base_prefix}blogs WHERE blog_id = %d", $blog_id ) ) )
307
+ return true;
308
+
309
+ return false;
310
+ }
311
+ }
312
+
313
+ ?>
bp-blogs/bp-blogs-filters.php DELETED
@@ -1,137 +0,0 @@
1
- <?php
2
- /**
3
- * Filters related to the Blogs component.
4
- *
5
- * @package BuddyPress
6
- * @subpackage BlogFilters
7
- * @since 1.6.0
8
- */
9
-
10
- /** Display Filters **********************************************************/
11
-
12
- add_filter( 'bp_get_blog_latest_post_title', 'wptexturize' );
13
- add_filter( 'bp_get_blog_latest_post_title', 'convert_chars' );
14
- add_filter( 'bp_get_blog_latest_post_title', 'trim' );
15
-
16
- add_filter( 'bp_blog_latest_post_content', 'wptexturize' );
17
- add_filter( 'bp_blog_latest_post_content', 'convert_smilies' );
18
- add_filter( 'bp_blog_latest_post_content', 'convert_chars' );
19
- add_filter( 'bp_blog_latest_post_content', 'wpautop' );
20
- add_filter( 'bp_blog_latest_post_content', 'shortcode_unautop' );
21
- add_filter( 'bp_blog_latest_post_content', 'prepend_attachment' );
22
-
23
- /**
24
- * Ensure that the 'Create a new site' link at wp-admin/my-sites.php points to the BP blog signup.
25
- *
26
- * @since 1.6.0
27
- *
28
- * returned value.
29
- *
30
- * @param string $url The original URL (points to wp-signup.php by default).
31
- * @return string The new URL.
32
- */
33
- function bp_blogs_creation_location( $url ) {
34
-
35
- /**
36
- * Filters the 'Create a new site' link URL.
37
- *
38
- * @since 1.6.0
39
- *
40
- * @param string $value URL for the 'Create a new site' signup page.
41
- */
42
- return apply_filters( 'bp_blogs_creation_location', trailingslashit( bp_get_blogs_directory_permalink() . 'create' ), $url );
43
- }
44
- add_filter( 'wp_signup_location', 'bp_blogs_creation_location' );
45
-
46
- /**
47
- * Only select comments by ID instead of all fields when using get_comments().
48
- *
49
- * @since 2.1.0
50
- *
51
- * @see bp_blogs_update_post_activity_meta()
52
- *
53
- * @param array $retval Current SQL clauses in array format.
54
- * @return array
55
- */
56
- function bp_blogs_comments_clauses_select_by_id( $retval ) {
57
- $retval['fields'] = 'comment_ID';
58
-
59
- return $retval;
60
- }
61
-
62
- /**
63
- * Check whether the current activity about a post or a comment can be published.
64
- *
65
- * Abstracted from the deprecated `bp_blogs_record_post()`.
66
- *
67
- * @since 2.2.0
68
- *
69
- * @param bool $return Whether the post should be published.
70
- * @param int $blog_id ID of the blog.
71
- * @param int $post_id ID of the post.
72
- * @param int $user_id ID of the post author.
73
- * @return bool True to authorize the post to be published, otherwise false.
74
- */
75
- function bp_blogs_post_pre_publish( $return = true, $blog_id = 0, $post_id = 0, $user_id = 0 ) {
76
- $bp = buddypress();
77
-
78
- // If blog is not trackable, do not record the activity.
79
- if ( ! bp_blogs_is_blog_trackable( $blog_id, $user_id ) ) {
80
- return false;
81
- }
82
-
83
- /*
84
- * Stop infinite loops with WordPress MU Sitewide Tags.
85
- * That plugin changed the way its settings were stored at some point. Thus the dual check.
86
- */
87
- $sitewide_tags_blog_settings = bp_core_get_root_option( 'sitewide_tags_blog' );
88
- if ( ! empty( $sitewide_tags_blog_settings ) ) {
89
- $st_options = maybe_unserialize( $sitewide_tags_blog_settings );
90
- $tags_blog_id = isset( $st_options['tags_blog_id'] ) ? $st_options['tags_blog_id'] : 0;
91
- } else {
92
- $tags_blog_id = bp_core_get_root_option( 'sitewide_tags_blog' );
93
- $tags_blog_id = intval( $tags_blog_id );
94
- }
95
-
96
- /**
97
- * Filters whether or not BuddyPress should block sitewide tags activity.
98
- *
99
- * @since 2.2.0
100
- *
101
- * @param bool $value Current status of the sitewide tags activity.
102
- */
103
- if ( (int) $blog_id == $tags_blog_id && apply_filters( 'bp_blogs_block_sitewide_tags_activity', true ) ) {
104
- return false;
105
- }
106
-
107
- /**
108
- * Filters whether or not the current blog is public.
109
- *
110
- * @since 2.2.0
111
- *
112
- * @param int $value Value from the blog_public option for the current blog.
113
- */
114
- $is_blog_public = apply_filters( 'bp_is_blog_public', (int) get_blog_option( $blog_id, 'blog_public' ) );
115
-
116
- if ( 0 === $is_blog_public && is_multisite() ) {
117
- return false;
118
- }
119
-
120
- return $return;
121
- }
122
- add_filter( 'bp_activity_post_pre_publish', 'bp_blogs_post_pre_publish', 10, 4 );
123
- add_filter( 'bp_activity_post_pre_comment', 'bp_blogs_post_pre_publish', 10, 4 );
124
-
125
- /**
126
- * Registers our custom thumb size with WP's Site Icon feature.
127
- *
128
- * @since 2.7.0
129
- *
130
- * @param array $sizes Current array of custom site icon sizes.
131
- * @return array
132
- */
133
- function bp_blogs_register_custom_site_icon_size( $sizes ) {
134
- $sizes[] = bp_core_avatar_thumb_width();
135
- return $sizes;
136
- }
137
- add_filter( 'site_icon_image_sizes', 'bp_blogs_register_custom_site_icon_size' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-blogs/bp-blogs-functions.php DELETED
@@ -1,1434 +0,0 @@
1
- <?php
2
- /**
3
- * Blogs component functions.
4
- *
5
- * @package BuddyPress
6
- * @subpackage BlogsFunctions
7
- * @since 1.5.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Check whether the $bp global lists an activity directory page.
15
- *
16
- * @since 1.5.0
17
- *
18
- * @return bool True if set, false if empty.
19
- */
20
- function bp_blogs_has_directory() {
21
- $bp = buddypress();
22
-
23
- return (bool) !empty( $bp->pages->blogs->id );
24
- }
25
-
26
- /**
27
- * Retrieve a set of blogs.
28
- *
29
- * @see BP_Blogs_Blog::get() for a description of arguments and return value.
30
- *
31
- * @param array|string $args {
32
- * Arguments are listed here with their default values. For more
33
- * information about the arguments, see {@link BP_Blogs_Blog::get()}.
34
- * @type string $type Default: 'active'.
35
- * @type int|bool $user_id Default: false.
36
- * @type array $include_blog_ids Default: false.
37
- * @type string|bool $search_terms Default: false.
38
- * @type int $per_page Default: 20.
39
- * @type int $page Default: 1.
40
- * @type bool $update_meta_cache Whether to pre-fetch blogmeta. Default: true.
41
- * }
42
- * @return array See {@link BP_Blogs_Blog::get()}.
43
- */
44
- 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.
58
- $blogs = BP_Blogs_Blog::get(
59
- $r['type'],
60
- $r['per_page'],
61
- $r['page'],
62
- $r['user_id'],
63
- $r['search_terms'],
64
- $r['update_meta_cache'],
65
- $r['include_blog_ids']
66
- );
67
-
68
- /**
69
- * Filters a set of blogs.
70
- *
71
- * @since 1.2.0
72
- *
73
- * @param array $blogs Array of blog data.
74
- * @param array $r Parsed query arguments.
75
- */
76
- return apply_filters( 'bp_blogs_get_blogs', $blogs, $r );
77
- }
78
-
79
- /**
80
- * Populate the BP blogs table with existing blogs.
81
- *
82
- * Warning: By default, this will remove all existing records from the BP
83
- * blogs and blogmeta tables before re-populating the tables.
84
- *
85
- * @since 1.0.0
86
- * @since 2.6.0 Accepts $args as a parameter.
87
- *
88
- * @param array $args {
89
- * Array of arguments.
90
- * @type int $offset The offset to use.
91
- * @type int $limit The number of blogs to record at one time.
92
- * @type array $blog_ids Blog IDs to record. If empty, all blogs will be recorded.
93
- * @type array $site_id The network site ID to use.
94
- * }
95
- *
96
- * @return bool
97
- */
98
- function bp_blogs_record_existing_blogs( $args = array() ) {
99
- global $wpdb;
100
-
101
- // Query for all sites in network.
102
- $r = bp_parse_args( $args, array(
103
- 'offset' => false === bp_get_option( '_bp_record_blogs_offset' ) ? 0 : bp_get_option( '_bp_record_blogs_offset' ),
104
- 'limit' => 50,
105
- 'blog_ids' => array(),
106
- 'site_id' => $wpdb->siteid
107
- ), 'record_existing_blogs' );
108
-
109
- // Truncate all BP blogs tables if starting fresh
110
- if ( empty( $r['offset'] ) && empty( $r['blog_ids'] ) ) {
111
- $bp = buddypress();
112
-
113
- // Truncate user blogs table
114
- $truncate = $wpdb->query( "TRUNCATE {$bp->blogs->table_name}" );
115
- if ( is_wp_error( $truncate ) ) {
116
- return false;
117
- }
118
-
119
- // Truncate user blogmeta table
120
- $truncate = $wpdb->query( "TRUNCATE {$bp->blogs->table_name_blogmeta}" );
121
- if ( is_wp_error( $truncate ) ) {
122
- return false;
123
- }
124
- }
125
-
126
- // Multisite
127
- if ( is_multisite() ) {
128
- $sql = array();
129
- $sql['select'] = $wpdb->prepare( "SELECT blog_id, last_updated FROM {$wpdb->base_prefix}blogs WHERE mature = 0 AND spam = 0 AND deleted = 0 AND site_id = %d", $r['site_id'] );
130
-
131
- // Omit root blog if large network
132
- if ( wp_is_large_network( 'users' ) ) {
133
- $sql['omit_root_blog'] = $wpdb->prepare( "AND blog_id != %d", bp_get_root_blog_id() );
134
- }
135
-
136
- // Filter by selected blog IDs
137
- if ( ! empty( $r['blog_ids'] ) ) {
138
- $in = implode( ',', wp_parse_id_list( $r['blog_ids'] ) );
139
- $sql['in'] = "AND blog_id IN ({$in})";
140
- }
141
-
142
- $sql['orderby'] = 'ORDER BY blog_id ASC';
143
-
144
- $sql['limit'] = $wpdb->prepare( "LIMIT %d", $r['limit'] );
145
-
146
- if ( ! empty( $r['offset'] ) ) {
147
- $sql['offset'] = $wpdb->prepare( "OFFSET %d", $r['offset'] );
148
- }
149
-
150
- $blogs = $wpdb->get_results( implode( ' ', $sql ) );
151
-
152
- // Record a single site.
153
- } else {
154
- // Just record blog for the current user only.
155
- $record = bp_blogs_record_blog( $wpdb->blogid, get_current_user_id(), true );
156
-
157
- if ( false === $record ) {
158
- return false;
159
- } else {
160
- return true;
161
- }
162
- }
163
-
164
- // Bail if there are no blogs
165
- if ( empty( $blogs ) ) {
166
- // Make sure we remove our offset marker
167
- if ( is_multisite() ) {
168
- bp_delete_option( '_bp_record_blogs_offset' );
169
- }
170
-
171
- return false;
172
- }
173
-
174
- // Loop through users of blogs and record the relationship.
175
- foreach ( (array) $blogs as $blog ) {
176
-
177
- // Ensure that the cache is clear after the table TRUNCATE above.
178
- wp_cache_delete( $blog->blog_id, 'blog_meta' );
179
-
180
- // Get all users.
181
- $users = get_users( array(
182
- 'blog_id' => $blog->blog_id,
183
- 'fields' => 'ID'
184
- ) );
185
-
186
- // Continue on if no users exist for this site (how did this happen?).
187
- if ( empty( $users ) ) {
188
- continue;
189
- }
190
-
191
- // Loop through users and record their relationship to this blog.
192
- foreach ( (array) $users as $user_id ) {
193
- bp_blogs_add_user_to_blog( $user_id, false, $blog->blog_id );
194
-
195
- // Clear cache
196
- bp_blogs_clear_blog_object_cache( $blog->blog_id, $user_id );
197
- }
198
-
199
- // Update blog last activity timestamp
200
- if ( ! empty( $blog->last_updated ) && false !== strtotime( $blog->last_updated ) ) {
201
- bp_blogs_update_blogmeta( $blog->blog_id, 'last_activity', $blog->last_updated );
202
- }
203
- }
204
-
205
- // See if we need to do this again
206
- if ( is_multisite() && empty( $r['blog_ids'] ) ) {
207
- $sql['offset'] = $wpdb->prepare( " OFFSET %d", $r['limit'] + $r['offset'] );
208
-
209
- // Check if there are more blogs to record
210
- $blog_ids = $wpdb->get_results( implode( ' ', $sql ) );
211
-
212
- // We have more blogs; record offset and re-run function
213
- if ( ! empty( $blog_ids ) ) {
214
- bp_update_option( '_bp_record_blogs_offset', $r['limit'] + $r['offset'] );
215
- bp_blogs_record_existing_blogs( array(
216
- 'offset' => $r['limit'] + $r['offset'],
217
- 'limit' => $r['limit'],
218
- 'blog_ids' => $r['blog_ids'],
219
- 'site_id' => $r['site_id']
220
- ) );
221
-
222
- // Bail since we have more blogs to record.
223
- return;
224
-
225
- // No more blogs; delete offset marker
226
- } else {
227
- bp_delete_option( '_bp_record_blogs_offset' );
228
- }
229
- }
230
-
231
- /**
232
- * Fires after the BP blogs tables have been populated with existing blogs.
233
- *
234
- * @since 2.4.0
235
- */
236
- do_action( 'bp_blogs_recorded_existing_blogs' );
237
-
238
- // No errors.
239
- return true;
240
- }
241
-
242
- /**
243
- * Check whether a given blog should be recorded in activity streams.
244
- *
245
- * If $user_id is provided, you can restrict site from being recordable
246
- * only to particular users.
247
- *
248
- * @since 1.7.0
249
- *
250
- * @param int $blog_id ID of the blog being checked.
251
- * @param int $user_id Optional. ID of the user for whom access is being checked.
252
- * @return bool True if blog is recordable, otherwise false.
253
- */
254
- function bp_blogs_is_blog_recordable( $blog_id, $user_id = 0 ) {
255
-
256
- /**
257
- * Filters whether or not a blog is globally activity stream recordable.
258
- *
259
- * @since 1.7.0
260
- *
261
- * @param bool $value Whether or not recordable. Default true.
262
- * @param int $blog_id Current blog ID.
263
- */
264
- $recordable_globally = apply_filters( 'bp_blogs_is_blog_recordable', true, $blog_id );
265
-
266
- if ( !empty( $user_id ) ) {
267
- /**
268
- * Filters whether or not a blog is globally activity stream recordable for user.
269
- *
270
- * @since 1.7.0
271
- *
272
- * @param bool $recordable_globally Whether or not recordable.
273
- * @param int $blog_id Current blog ID.
274
- * @param int $user_id Current user ID.
275
- */
276
- $recordable_for_user = apply_filters( 'bp_blogs_is_blog_recordable_for_user', $recordable_globally, $blog_id, $user_id );
277
- } else {
278
- $recordable_for_user = $recordable_globally;
279
- }
280
-
281
- if ( !empty( $recordable_for_user ) ) {
282
- return true;
283
- }
284
-
285
- return $recordable_globally;
286
- }
287
-
288
- /**
289
- * Check whether a given blog should be tracked by the Blogs component.
290
- *
291
- * If $user_id is provided, the developer can restrict site from
292
- * being trackable only to particular users.
293
- *
294
- * @since 1.7.0
295
- *
296
- * @param int $blog_id ID of the blog being checked.
297
- * @param int $user_id Optional. ID of the user for whom access is being checked.
298
- * @return bool True if blog is trackable, otherwise false.
299
- */
300
- function bp_blogs_is_blog_trackable( $blog_id, $user_id = 0 ) {
301
-
302
- /**
303
- * Filters whether or not a blog is globally trackable.
304
- *
305
- * @since 1.7.0
306
- *
307
- * @param bool $value Whether or not trackable.
308
- * @param int $blog_id Current blog ID.
309
- */
310
- $trackable_globally = apply_filters( 'bp_blogs_is_blog_trackable', bp_blogs_is_blog_recordable( $blog_id, $user_id ), $blog_id );
311
-
312
- if ( !empty( $user_id ) ) {
313
-
314
- /**
315
- * Filters whether or not a blog is globally trackable for user.
316
- *
317
- * @since 1.7.0
318
- *
319
- * @param bool $value Whether or not trackable.
320
- * @param int $blog_id Current blog ID.
321
- * @param int $user_id Current user ID.
322
- */
323
- $trackable_for_user = apply_filters( 'bp_blogs_is_blog_trackable_for_user', $trackable_globally, $blog_id, $user_id );
324
- } else {
325
- $trackable_for_user = $trackable_globally;
326
- }
327
-
328
- if ( !empty( $trackable_for_user ) ) {
329
- return $trackable_for_user;
330
- }
331
-
332
- return $trackable_globally;
333
- }
334
-
335
- /**
336
- * Make BuddyPress aware of a new site so that it can track its activity.
337
- *
338
- * @since 1.0.0
339
- *
340
- * @param int $blog_id ID of the blog being recorded.
341
- * @param int $user_id ID of the user for whom the blog is being recorded.
342
- * @param bool $no_activity Optional. Whether to skip recording an activity
343
- * item about this blog creation. Default: false.
344
- * @return false|null Returns false on failure.
345
- */
346
- function bp_blogs_record_blog( $blog_id, $user_id, $no_activity = false ) {
347
-
348
- if ( empty( $user_id ) )
349
- $user_id = bp_loggedin_user_id();
350
-
351
- // If blog is not recordable, do not record the activity.
352
- if ( !bp_blogs_is_blog_recordable( $blog_id, $user_id ) )
353
- return false;
354
-
355
- $name = get_blog_option( $blog_id, 'blogname' );
356
- $url = get_home_url( $blog_id );
357
-
358
- if ( empty( $name ) ) {
359
- $name = $url;
360
- }
361
-
362
- $description = get_blog_option( $blog_id, 'blogdescription' );
363
- $close_old_posts = get_blog_option( $blog_id, 'close_comments_for_old_posts' );
364
- $close_days_old = get_blog_option( $blog_id, 'close_comments_days_old' );
365
-
366
- $thread_depth = get_blog_option( $blog_id, 'thread_comments' );
367
- if ( ! empty( $thread_depth ) ) {
368
- $thread_depth = get_blog_option( $blog_id, 'thread_comments_depth' );
369
- } else {
370
- // Perhaps filter this?
371
- $thread_depth = 1;
372
- }
373
-
374
- $recorded_blog = new BP_Blogs_Blog;
375
- $recorded_blog->user_id = $user_id;
376
- $recorded_blog->blog_id = $blog_id;
377
- $recorded_blog_id = $recorded_blog->save();
378
- $is_recorded = !empty( $recorded_blog_id ) ? true : false;
379
-
380
- bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'url', $url );
381
- bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'name', $name );
382
- bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'description', $description );
383
- bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'last_activity', bp_core_current_time() );
384
- bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'close_comments_for_old_posts', $close_old_posts );
385
- bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'close_comments_days_old', $close_days_old );
386
- bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'thread_comments_depth', $thread_depth );
387
-
388
- $is_private = !empty( $_POST['blog_public'] ) && (int) $_POST['blog_public'] ? false : true;
389
-
390
- /**
391
- * Filters whether or not a new blog is public.
392
- *
393
- * @since 1.5.0
394
- *
395
- * @param bool $is_private Whether or not blog is public.
396
- */
397
- $is_private = !apply_filters( 'bp_is_new_blog_public', !$is_private );
398
-
399
- /**
400
- * Fires after BuddyPress has been made aware of a new site for activity tracking.
401
- *
402
- * @since 1.0.0
403
- * @since 2.6.0 Added $no_activity as a parameter.
404
- *
405
- * @param BP_Blogs_Blog $recorded_blog Current blog being recorded. Passed by reference.
406
- * @param bool $is_private Whether or not the current blog being recorded is private.
407
- * @param bool $is_recorded Whether or not the current blog was recorded.
408
- * @param bool $no_activity Whether to skip recording an activity item for this blog creation.
409
- */
410
- do_action_ref_array( 'bp_blogs_new_blog', array( &$recorded_blog, $is_private, $is_recorded, $no_activity ) );
411
- }
412
- add_action( 'wpmu_new_blog', 'bp_blogs_record_blog', 10, 2 );
413
-
414
- /**
415
- * Update blog name in BuddyPress blogmeta table.
416
- *
417
- * @global object $wpdb DB Layer.
418
- *
419
- * @param string $oldvalue Value before save. Passed by do_action() but
420
- * unused here.
421
- * @param string $newvalue Value to change meta to.
422
- */
423
- function bp_blogs_update_option_blogname( $oldvalue, $newvalue ) {
424
- global $wpdb;
425
-
426
- bp_blogs_update_blogmeta( $wpdb->blogid, 'name', $newvalue );
427
- }
428
- add_action( 'update_option_blogname', 'bp_blogs_update_option_blogname', 10, 2 );
429
-
430
- /**
431
- * Update blog description in BuddyPress blogmeta table.
432
- *
433
- * @global object $wpdb DB Layer.
434
- *
435
- * @param string $oldvalue Value before save. Passed by do_action() but
436
- * unused here.
437
- * @param string $newvalue Value to change meta to.
438
- */
439
- function bp_blogs_update_option_blogdescription( $oldvalue, $newvalue ) {
440
- global $wpdb;
441
-
442
- bp_blogs_update_blogmeta( $wpdb->blogid, 'description', $newvalue );
443
- }
444
- add_action( 'update_option_blogdescription', 'bp_blogs_update_option_blogdescription', 10, 2 );
445
-
446
- /**
447
- * Update "Close comments for old posts" option in BuddyPress blogmeta table.
448
- *
449
- * @since 2.0.0
450
- *
451
- * @global object $wpdb DB Layer.
452
- *
453
- * @param string $oldvalue Value before save. Passed by do_action() but
454
- * unused here.
455
- * @param string $newvalue Value to change meta to.
456
- */
457
- function bp_blogs_update_option_close_comments_for_old_posts( $oldvalue, $newvalue ) {
458
- global $wpdb;
459
-
460
- bp_blogs_update_blogmeta( $wpdb->blogid, 'close_comments_for_old_posts', $newvalue );
461
- }
462
- add_action( 'update_option_close_comments_for_old_posts', 'bp_blogs_update_option_close_comments_for_old_posts', 10, 2 );
463
-
464
- /**
465
- * Update "Close comments after days old" option in BuddyPress blogmeta table.
466
- *
467
- * @since 2.0.0
468
- *
469
- * @global object $wpdb DB Layer.
470
- *
471
- * @param string $oldvalue Value before save. Passed by do_action() but
472
- * unused here.
473
- * @param string $newvalue Value to change meta to.
474
- */
475
- function bp_blogs_update_option_close_comments_days_old( $oldvalue, $newvalue ) {
476
- global $wpdb;
477
-
478
- bp_blogs_update_blogmeta( $wpdb->blogid, 'close_comments_days_old', $newvalue );
479
- }
480
- add_action( 'update_option_close_comments_days_old', 'bp_blogs_update_option_close_comments_days_old', 10, 2 );
481
-
482
- /**
483
- * When toggling threaded comments, update thread depth in blogmeta table.
484
- *
485
- * @since 2.0.0
486
- *
487
- * @global object $wpdb DB Layer.
488
- *
489
- * @param string $oldvalue Value before save. Passed by do_action() but
490
- * unused here.
491
- * @param string $newvalue Value to change meta to.
492
- */
493
- function bp_blogs_update_option_thread_comments( $oldvalue, $newvalue ) {
494
- global $wpdb;
495
-
496
- if ( empty( $newvalue ) ) {
497
- $thread_depth = 1;
498
- } else {
499
- $thread_depth = get_option( 'thread_comments_depth' );
500
- }
501
-
502
- bp_blogs_update_blogmeta( $wpdb->blogid, 'thread_comments_depth', $thread_depth );
503
- }
504
- add_action( 'update_option_thread_comments', 'bp_blogs_update_option_thread_comments', 10, 2 );
505
-
506
- /**
507
- * When updating comment depth, update thread depth in blogmeta table.
508
- *
509
- * @since 2.0.0
510
- *
511
- * @global object $wpdb DB Layer.
512
- *
513
- * @param string $oldvalue Value before save. Passed by do_action() but
514
- * unused here.
515
- * @param string $newvalue Value to change meta to.
516
- */
517
- function bp_blogs_update_option_thread_comments_depth( $oldvalue, $newvalue ) {
518
- global $wpdb;
519
-
520
- $comments_enabled = get_option( 'thread_comments' );
521
-
522
- if ( $comments_enabled ) {
523
- bp_blogs_update_blogmeta( $wpdb->blogid, 'thread_comments_depth', $newvalue );
524
- }
525
- }
526
- add_action( 'update_option_thread_comments_depth', 'bp_blogs_update_option_thread_comments_depth', 10, 2 );
527
-
528
- /**
529
- * Syncs site icon URLs to blogmeta.
530
- *
531
- * @since 2.7.0
532
- *
533
- * @param int|string $old_value Old value
534
- * @param int|string $new_value New value
535
- */
536
- function bp_blogs_update_option_site_icon( $old_value, $new_value ) {
537
- if ( 0 === $new_value ) {
538
- bp_blogs_update_blogmeta( get_current_blog_id(), 'site_icon_url_thumb', 0 );
539
- bp_blogs_update_blogmeta( get_current_blog_id(), 'site_icon_url_full', 0 );
540
- } else {
541
- // Save site icon URL as blogmeta.
542
- bp_blogs_update_blogmeta( get_current_blog_id(), 'site_icon_url_thumb', get_site_icon_url( bp_core_avatar_thumb_width() ) );
543
- bp_blogs_update_blogmeta( get_current_blog_id(), 'site_icon_url_full', get_site_icon_url( bp_core_avatar_full_width() ) );
544
- }
545
- }
546
- add_action( 'update_option_site_icon', 'bp_blogs_update_option_site_icon', 10, 2 );
547
-
548
- /**
549
- * Deletes the 'url' blogmeta for a site.
550
- *
551
- * Fires when a site's details are updated, which generally happens when
552
- * editing a site under "Network Admin > Sites". Prior to WP 4.9, the
553
- * correct hook was 'refresh_blog_details'; afterward, 'clean_site_cache'.
554
- *
555
- * @since 2.3.0
556
- *
557
- * @param int $site_id The site ID.
558
- */
559
- function bp_blogs_delete_url_blogmeta( $site_id = 0 ) {
560
- bp_blogs_delete_blogmeta( (int) $site_id, 'url' );
561
- }
562
-
563
- if ( function_exists( 'wp_switch_roles_and_user' ) ) {
564
- add_action( 'clean_site_cache', 'bp_blogs_delete_url_blogmeta' );
565
- } else {
566
- add_action( 'refresh_blog_details', 'bp_blogs_delete_url_blogmeta' );
567
- }
568
-
569
- /**
570
- * Record activity metadata about a published blog post.
571
- *
572
- * @since 2.2.0
573
- *
574
- * @param int $activity_id ID of the activity item.
575
- * @param WP_Post $post Post object.
576
- * @param array $args Array of arguments.
577
- */
578
- function bp_blogs_publish_post_activity_meta( $activity_id, $post, $args ) {
579
- if ( empty( $activity_id ) || 'post' != $post->post_type ) {
580
- return;
581
- }
582
-
583
- bp_activity_update_meta( $activity_id, 'post_title', $post->post_title );
584
-
585
- if ( ! empty( $args['post_url'] ) ) {
586
- $post_permalink = $args['post_url'];
587
- } else {
588
- $post_permalink = $post->guid;
589
- }
590
-
591
- bp_activity_update_meta( $activity_id, 'post_url', $post_permalink );
592
-
593
- // Update the blog's last activity.
594
- bp_blogs_update_blogmeta( $args['item_id'], 'last_activity', bp_core_current_time() );
595
-
596
- /**
597
- * Fires after BuddyPress has recorded metadata about a published blog post.
598
- *
599
- * @since 1.0.0
600
- *
601
- * @param int $ID ID of the blog post being recorded.
602
- * @param WP_Post $post WP_Post object for the current blog post.
603
- * @param string $value ID of the user associated with the current blog post.
604
- */
605
- do_action( 'bp_blogs_new_blog_post', $post->ID, $post, $args['user_id'] );
606
- }
607
- add_action( 'bp_activity_post_type_published', 'bp_blogs_publish_post_activity_meta', 10, 3 );
608
-
609
- /**
610
- * Updates a blog post's activity meta entry during a post edit.
611
- *
612
- * @since 2.2.0
613
- * @since 2.5.0 Add the post type tracking args object parameter
614
- *
615
- * @param WP_Post $post Post object.
616
- * @param BP_Activity_Activity $activity Activity object.
617
- * @param object $activity_post_object The post type tracking args object.
618
- */
619
- function bp_blogs_update_post_activity_meta( $post, $activity, $activity_post_object ) {
620
- if ( empty( $activity->id ) || empty( $activity_post_object->action_id ) ) {
621
- return;
622
- }
623
-
624
- // Update post title in activity meta.
625
- $existing_title = bp_activity_get_meta( $activity->id, 'post_title' );
626
- if ( $post->post_title !== $existing_title ) {
627
- bp_activity_update_meta( $activity->id, 'post_title', $post->post_title );
628
-
629
- if ( ! empty( $activity_post_object->comments_tracking->action_id ) ) {
630
- // Now update activity meta for post comments... sigh.
631
- add_filter( 'comments_clauses', 'bp_blogs_comments_clauses_select_by_id' );
632
- $comments = get_comments( array( 'post_id' => $post->ID ) );
633
- remove_filter( 'comments_clauses', 'bp_blogs_comments_clauses_select_by_id' );
634
-
635
- if ( ! empty( $comments ) ) {
636
- $activity_ids = array();
637
- $comment_ids = wp_list_pluck( $comments, 'comment_ID' );
638
-
639
- // Set up activity args.
640
- $args = array(
641
- 'update_meta_cache' => false,
642
- 'show_hidden' => true,
643
- 'per_page' => 99999,
644
- );
645
-
646
- // Query for old-style "new_blog_comment" activity items.
647
- $args['filter'] = array(
648
- 'object' => $activity_post_object->comments_tracking->component_id,
649
- 'action' => $activity_post_object->comments_tracking->action_id,
650
- 'secondary_id' => implode( ',', $comment_ids ),
651
- );
652
-
653
- $activities = bp_activity_get( $args );
654
- if ( ! empty( $activities['activities'] ) ) {
655
- $activity_ids = (array) wp_list_pluck( $activities['activities'], 'id' );
656
- }
657
-
658
- // Query for activity comments connected to a blog post.
659
- unset( $args['filter'] );
660
- $args['meta_query'] = array( array(
661
- 'key' => 'bp_blogs_' . $post->post_type . '_comment_id',
662
- 'value' => $comment_ids,
663
- 'compare' => 'IN',
664
- ) );
665
- $args['type'] = 'activity_comment';
666
- $args['display_comments'] = 'stream';
667
-
668
- $activities = bp_activity_get( $args );
669
- if ( ! empty( $activities['activities'] ) ) {
670
- $activity_ids = array_merge( $activity_ids, (array) wp_list_pluck( $activities['activities'], 'id' ) );
671
- }
672
-
673
- // Update activity meta for all found activity items.
674
- if ( ! empty( $activity_ids ) ) {
675
- foreach ( $activity_ids as $aid ) {
676
- bp_activity_update_meta( $aid, 'post_title', $post->post_title );
677
- }
678
- }
679
-
680
- unset( $activities, $activity_ids, $comment_ids, $comments );
681
- }
682
- }
683
- }
684
-
685
- // Add post comment status to activity meta if closed.
686
- if( 'closed' == $post->comment_status ) {
687
- bp_activity_update_meta( $activity->id, 'post_comment_status', $post->comment_status );
688
- } else {
689
- bp_activity_delete_meta( $activity->id, 'post_comment_status' );
690
- }
691
- }
692
- add_action( 'bp_activity_post_type_updated', 'bp_blogs_update_post_activity_meta', 10, 3 );
693
-
694
- /**
695
- * Update Activity and blogs meta and eventually sync comment with activity comment
696
- *
697
- * @since 2.5.0
698
- *
699
- * @param int|bool $activity_id ID of recorded activity, or false if sync is active.
700
- * @param WP_Comment|null $comment The comment object.
701
- * @param array $activity_args Array of activity arguments.
702
- * @param object|null $activity_post_object The post type tracking args object.
703
- * @return WP_Error|bool|int Returns false if no activity, the activity id otherwise.
704
- */
705
- function bp_blogs_comment_sync_activity_comment( &$activity_id, $comment = null, $activity_args = array(), $activity_post_object = null ) {
706
- if ( empty( $activity_args ) || empty( $comment->post->ID ) || empty( $activity_post_object->comment_action_id ) ) {
707
- return false;
708
- }
709
-
710
- // Set the current blog id.
711
- $blog_id = get_current_blog_id();
712
-
713
- // These activity metadatas are used to build the new_blog_comment action string
714
- if ( ! empty( $activity_id ) && ! empty( $activity_args['item_id'] ) && 'new_blog_comment' === $activity_post_object->comment_action_id ) {
715
- // add some post info in activity meta
716
- bp_activity_update_meta( $activity_id, 'post_title', $comment->post->post_title );
717
- bp_activity_update_meta( $activity_id, 'post_url', esc_url_raw( add_query_arg( 'p', $comment->post->ID, home_url( '/' ) ) ) );
718
- }
719
-
720
- // Sync comment - activity comment
721
- if ( ! bp_disable_blogforum_comments() ) {
722
-
723
- if ( ! empty( $_REQUEST['action'] ) ) {
724
- $existing_activity_id = get_comment_meta( $comment->comment_ID, 'bp_activity_comment_id', true );
725
-
726
- if ( ! empty( $existing_activity_id ) ) {
727
- $activity_args['id'] = $existing_activity_id;
728
- }
729
- }
730
-
731
- if ( empty( $activity_post_object ) ) {
732
- $activity_post_object = bp_activity_get_post_type_tracking_args( $comment->post->post_type );
733
- }
734
-
735
- if ( isset( $activity_post_object->action_id ) && isset( $activity_post_object->component_id ) ) {
736
- // find the parent 'new_post_type' activity entry
737
- $parent_activity_id = bp_activity_get_activity_id( array(
738
- 'component' => $activity_post_object->component_id,
739
- 'type' => $activity_post_object->action_id,
740
- 'item_id' => $blog_id,
741
- 'secondary_item_id' => $comment->comment_post_ID
742
- ) );
743
-
744
- // Try to create a new activity item for the parent blog post.
745
- if ( empty( $parent_activity_id ) ) {
746
- $parent_activity_id = bp_activity_post_type_publish( $comment->post->ID, $comment->post );
747
- }
748
- }
749
-
750
- // we found the parent activity entry
751
- // so let's go ahead and reconfigure some activity args
752
- if ( ! empty( $parent_activity_id ) ) {
753
- // set the parent activity entry ID
754
- $activity_args['activity_id'] = $parent_activity_id;
755
-
756
- // now see if the WP parent comment has a BP activity ID
757
- $comment_parent = 0;
758
- if ( ! empty( $comment->comment_parent ) ) {
759
- $comment_parent = get_comment_meta( $comment->comment_parent, 'bp_activity_comment_id', true );
760
- }
761
-
762
- // WP parent comment does not have a BP activity ID
763
- // so set to 'new_' . post_type activity ID
764
- if ( empty( $comment_parent ) ) {
765
- $comment_parent = $parent_activity_id;
766
- }
767
-
768
- $activity_args['parent_id'] = $comment_parent;
769
- $activity_args['skip_notification'] = true;
770
-
771
- // could not find corresponding parent activity entry
772
- // so wipe out $args array
773
- } else {
774
- $activity_args = array();
775
- }
776
-
777
- // Record in activity streams
778
- if ( ! empty( $activity_args ) ) {
779
- $activity_id = bp_activity_new_comment( $activity_args );
780
-
781
- if ( empty( $activity_args['id'] ) ) {
782
- // The activity metadata to inform about the corresponding comment ID
783
- bp_activity_update_meta( $activity_id, "bp_blogs_{$comment->post->post_type}_comment_id", $comment->comment_ID );
784
-
785
- // The comment metadata to inform about the corresponding activity ID
786
- add_comment_meta( $comment->comment_ID, 'bp_activity_comment_id', $activity_id );
787
-
788
- // These activity metadatas are used to build the new_blog_comment action string
789
- if ( 'new_blog_comment' === $activity_post_object->comment_action_id ) {
790
- bp_activity_update_meta( $activity_id, 'post_title', $comment->post->post_title );
791
- bp_activity_update_meta( $activity_id, 'post_url', esc_url_raw( add_query_arg( 'p', $comment->post->ID, home_url( '/' ) ) ) );
792
- }
793
- }
794
-
795
- /**
796
- * Fires after an activity comment is added from a WP post comment.
797
- *
798
- * @since 2.6.0
799
- *
800
- * @param int $activity_id The activity comment ID.
801
- * @param WP_Comment $post_type_comment WP Comment object.
802
- * @param array $activity_args Activity comment arguments.
803
- * @param object $activity_post_object The post type tracking args object.
804
- */
805
- do_action( 'bp_blogs_comment_sync_activity_comment', $activity_id, $comment, $activity_args, $activity_post_object );
806
- }
807
- }
808
-
809
- // Update the blogs last active date
810
- bp_blogs_update_blogmeta( $blog_id, 'last_activity', bp_core_current_time() );
811
-
812
- if ( 'new_blog_comment' === $activity_post_object->comment_action_id ) {
813
- /**
814
- * Fires after BuddyPress has recorded metadata about a published blog post comment.
815
- *
816
- * @since 2.5.0
817
- *
818
- * @param int $value Comment ID of the blog post comment being recorded.
819
- * @param WP_Post $post WP_Comment object for the current blog post.
820
- * @param string $value ID of the user associated with the current blog post comment.
821
- */
822
- do_action( 'bp_blogs_new_blog_comment', $comment->comment_ID, $comment, bp_loggedin_user_id() );
823
- }
824
-
825
- return $activity_id;
826
- }
827
- add_action( 'bp_activity_post_type_comment', 'bp_blogs_comment_sync_activity_comment', 10, 4 );
828
-
829
- /**
830
- * Record a user's association with a blog.
831
- *
832
- * This function is hooked to several WordPress actions where blog roles are
833
- * set/changed ('add_user_to_blog', 'profile_update', 'user_register'). It
834
- * parses the changes, and records them as necessary in the BP blog tracker.
835
- *
836
- * BuddyPress does not track blogs for users with the 'subscriber' role by
837
- * default, though as of 2.1.0 you can filter 'bp_blogs_get_allowed_roles' to
838
- * modify this behavior.
839
- *
840
- * @param int $user_id The ID of the user.
841
- * @param string|bool $role User's WordPress role for this blog ID.
842
- * @param int $blog_id Blog ID user is being added to.
843
- * @return false|null False on failure.
844
- */
845
- function bp_blogs_add_user_to_blog( $user_id, $role = false, $blog_id = 0 ) {
846
- global $wpdb;
847
-
848
- // If no blog ID was passed, use the root blog ID.
849
- if ( empty( $blog_id ) ) {
850
- $blog_id = isset( $wpdb->blogid ) ? $wpdb->blogid : bp_get_root_blog_id();
851
- }
852
-
853
- // If no role was passed, try to find the blog role.
854
- if ( empty( $role ) ) {
855
-
856
- // Get user capabilities.
857
- $key = $wpdb->get_blog_prefix( $blog_id ). 'capabilities';
858
- $user_roles = array_keys( (array) bp_get_user_meta( $user_id, $key, true ) );
859
-
860
- // User has roles so lets.
861
- if ( ! empty( $user_roles ) ) {
862
-
863
- // Get blog roles.
864
- $blog_roles = array_keys( bp_get_current_blog_roles() );
865
-
866
- // Look for blog only roles of the user.
867
- $intersect_roles = array_intersect( $user_roles, $blog_roles );
868
-
869
- // If there's a role in the array, use the first one. This isn't
870
- // very smart, but since roles aren't exactly hierarchical, and
871
- // WordPress does not yet have a UI for multiple user roles, it's
872
- // fine for now.
873
- if ( ! empty( $intersect_roles ) ) {
874
- $role = array_shift( $intersect_roles );
875
- }
876
- }
877
- }
878
-
879
- // Bail if no role was found or role is not in the allowed roles array.
880
- if ( empty( $role ) || ! in_array( $role, bp_blogs_get_allowed_roles() ) ) {
881
- return false;
882
- }
883
-
884
- // Record the blog activity for this user being added to this blog.
885
- bp_blogs_record_blog( $blog_id, $user_id, true );
886
- }
887
- add_action( 'add_user_to_blog', 'bp_blogs_add_user_to_blog', 10, 3 );
888
- add_action( 'profile_update', 'bp_blogs_add_user_to_blog' );
889
- add_action( 'user_register', 'bp_blogs_add_user_to_blog' );
890
-
891
- /**
892
- * The allowed blog roles a member must have to be recorded into the
893
- * `bp_user_blogs` pointer table.
894
- *
895
- * This added and was made filterable in BuddyPress 2.1.0 to make it easier
896
- * to extend the functionality of the Blogs component.
897
- *
898
- * @since 2.1.0
899
- *
900
- * @return string
901
- */
902
- function bp_blogs_get_allowed_roles() {
903
-
904
- /**
905
- * Filters the allowed roles a member must have to be recorded into bp_user_blogs pointer table.
906
- *
907
- * @since 2.1.0
908
- *
909
- * @param array $value Array of potential roles user needs.
910
- */
911
- return apply_filters( 'bp_blogs_get_allowed_roles', array( 'contributor', 'author', 'editor', 'administrator' ) );
912
- }
913
-
914
- /**
915
- * Remove a blog-user pair from BP's blog tracker.
916
- *
917
- * @param int $user_id ID of the user whose blog is being removed.
918
- * @param int $blog_id Optional. ID of the blog being removed. Default: current blog ID.
919
- */
920
- function bp_blogs_remove_user_from_blog( $user_id, $blog_id = 0 ) {
921
- global $wpdb;
922
-
923
- if ( empty( $blog_id ) ) {
924
- $blog_id = $wpdb->blogid;
925
- }
926
-
927
- bp_blogs_remove_blog_for_user( $user_id, $blog_id );
928
- }
929
- add_action( 'remove_user_from_blog', 'bp_blogs_remove_user_from_blog', 10, 2 );
930
-
931
- /**
932
- * Rehook WP's maybe_add_existing_user_to_blog with a later priority.
933
- *
934
- * WordPress catches add-user-to-blog requests at init:10. In some cases, this
935
- * can precede BP's Blogs component. This function bumps the priority of the
936
- * core function, so that we can be sure that the Blogs component is loaded
937
- * first. See https://buddypress.trac.wordpress.org/ticket/3916.
938
- *
939
- * @since 1.6.0
940
- */
941
- function bp_blogs_maybe_add_user_to_blog() {
942
- if ( ! is_multisite() )
943
- return;
944
-
945
- remove_action( 'init', 'maybe_add_existing_user_to_blog' );
946
- add_action( 'init', 'maybe_add_existing_user_to_blog', 20 );
947
- }
948
- add_action( 'init', 'bp_blogs_maybe_add_user_to_blog', 1 );
949
-
950
- /**
951
- * Remove the "blog created" item from the BP blogs tracker and activity stream.
952
- *
953
- * @param int $blog_id ID of the blog being removed.
954
- */
955
- function bp_blogs_remove_blog( $blog_id ) {
956
-
957
- $blog_id = (int) $blog_id;
958
-
959
- /**
960
- * Fires before a "blog created" item is removed from blogs
961
- * tracker and activity stream.
962
- *
963
- * @since 1.5.0
964
- *
965
- * @param int $blog_id ID of the blog having its item removed.
966
- */
967
- do_action( 'bp_blogs_before_remove_blog', $blog_id );
968
-
969
- BP_Blogs_Blog::delete_blog_for_all( $blog_id );
970
-
971
- /**
972
- * Fires after a "blog created" item has been removed from blogs
973
- * tracker and activity stream.
974
- *
975
- * @since 1.0.0
976
- *
977
- * @param int $blog_id ID of the blog who had its item removed.
978
- */
979
- do_action( 'bp_blogs_remove_blog', $blog_id );
980
- }
981
- add_action( 'delete_blog', 'bp_blogs_remove_blog' );
982
-
983
- /**
984
- * Remove a blog from the tracker for a specific user.
985
- *
986
- * @param int $user_id ID of the user for whom the blog is being removed.
987
- * @param int $blog_id ID of the blog being removed.
988
- */
989
- function bp_blogs_remove_blog_for_user( $user_id, $blog_id ) {
990
-
991
- $blog_id = (int) $blog_id;
992
- $user_id = (int) $user_id;
993
-
994
- /**
995
- * Fires before a blog is removed from the tracker for a specific user.
996
- *
997
- * @since 1.5.0
998
- *
999
- * @param int $blog_id ID of the blog being removed.
1000
- * @param int $user_id ID of the user having the blog removed for.
1001
- */
1002
- do_action( 'bp_blogs_before_remove_blog_for_user', $blog_id, $user_id );
1003
-
1004
- BP_Blogs_Blog::delete_blog_for_user( $blog_id, $user_id );
1005
-
1006
- /**
1007
- * Fires after a blog has been removed from the tracker for a specific user.
1008
- *
1009
- * @since 1.0.0
1010
- *
1011
- * @param int $blog_id ID of the blog that was removed.
1012
- * @param int $user_id ID of the user having the blog removed for.
1013
- */
1014
- do_action( 'bp_blogs_remove_blog_for_user', $blog_id, $user_id );
1015
- }
1016
- add_action( 'remove_user_from_blog', 'bp_blogs_remove_blog_for_user', 10, 2 );
1017
-
1018
- /**
1019
- * Remove a synced activity comment from the activity stream.
1020
- *
1021
- * @since 2.5.0
1022
- *
1023
- * @param bool $deleted True when a comment post type activity was successfully removed.
1024
- * @param int $comment_id ID of the comment to be removed.
1025
- * @param object $activity_post_object The post type tracking args object.
1026
- * @param string $activity_type The post type comment activity type.
1027
- *
1028
- * @return bool True on success. False on error.
1029
- */
1030
- function bp_blogs_post_type_remove_comment( $deleted, $comment_id, $activity_post_object, $activity_type = '' ) {
1031
- // Remove synced activity comments, if needed.
1032
- if ( ! bp_disable_blogforum_comments() ) {
1033
- // Get associated activity ID from comment meta
1034
- $activity_id = get_comment_meta( $comment_id, 'bp_activity_comment_id', true );
1035
-
1036
- /**
1037
- * Delete the associated activity comment & also remove
1038
- * child post comments and associated activity comments.
1039
- */
1040
- if ( ! empty( $activity_id ) ) {
1041
- // fetch the activity comments for the activity item
1042
- $activity = bp_activity_get( array(
1043
- 'in' => $activity_id,
1044
- 'display_comments' => 'stream',
1045
- 'spam' => 'all',
1046
- ) );
1047
-
1048
- // get all activity comment IDs for the pending deleted item
1049
- if ( ! empty( $activity['activities'] ) ) {
1050
- $activity_ids = bp_activity_recurse_comments_activity_ids( $activity );
1051
- $activity_ids[] = $activity_id;
1052
-
1053
- // delete activity items
1054
- foreach ( $activity_ids as $activity_id ) {
1055
- bp_activity_delete( array(
1056
- 'id' => $activity_id
1057
- ) );
1058
- }
1059
-
1060
- // remove associated blog comments
1061
- bp_blogs_remove_associated_blog_comments( $activity_ids );
1062
-
1063
- // rebuild activity comment tree
1064
- BP_Activity_Activity::rebuild_activity_comment_tree( $activity['activities'][0]->item_id );
1065
-
1066
- // Set the result
1067
- $deleted = true;
1068
- }
1069
- }
1070
- }
1071
-
1072
- // Backcompat for comments about the 'post' post type.
1073
- if ( 'new_blog_comment' === $activity_type ) {
1074
- /**
1075
- * Fires after a blog comment activity item was removed from activity stream.
1076
- *
1077
- * @since 1.0.0
1078
- *
1079
- * @param int $value ID for the blog associated with the removed comment.
1080
- * @param int $comment_id ID of the comment being removed.
1081
- * @param int $value ID of the current logged in user.
1082
- */
1083
- do_action( 'bp_blogs_remove_comment', get_current_blog_id(), $comment_id, bp_loggedin_user_id() );
1084
- }
1085
-
1086
- return $deleted;
1087
- }
1088
- add_action( 'bp_activity_post_type_remove_comment', 'bp_blogs_post_type_remove_comment', 10, 4 );
1089
-
1090
- /**
1091
- * Removes blog comments that are associated with activity comments.
1092
- *
1093
- * @since 2.0.0
1094
- *
1095
- * @see bp_blogs_remove_synced_comment()
1096
- * @see bp_blogs_sync_delete_from_activity_comment()
1097
- *
1098
- * @param array $activity_ids The activity IDs to check association with blog
1099
- * comments.
1100
- * @param bool $force_delete Whether to force delete the comments. If false,
1101
- * comments are trashed instead.
1102
- */
1103
- function bp_blogs_remove_associated_blog_comments( $activity_ids = array(), $force_delete = true ) {
1104
- // Query args.
1105
- $query_args = array(
1106
- 'meta_query' => array(
1107
- array(
1108
- 'key' => 'bp_activity_comment_id',
1109
- 'value' => implode( ',', (array) $activity_ids ),
1110
- 'compare' => 'IN',
1111
- )
1112
- )
1113
- );
1114
-
1115
- // Get comment.
1116
- $comment_query = new WP_Comment_Query;
1117
- $comments = $comment_query->query( $query_args );
1118
-
1119
- // Found the corresponding comments
1120
- // let's delete them!
1121
- foreach ( $comments as $comment ) {
1122
- wp_delete_comment( $comment->comment_ID, $force_delete );
1123
-
1124
- // If we're trashing the comment, remove the meta key as well.
1125
- if ( empty( $force_delete ) ) {
1126
- delete_comment_meta( $comment->comment_ID, 'bp_activity_comment_id' );
1127
- }
1128
- }
1129
- }
1130
-
1131
- /**
1132
- * Get the total number of blogs being tracked by BuddyPress.
1133
- *
1134
- * @return int $count Total blog count.
1135
- */
1136
- function bp_blogs_total_blogs() {
1137
- $count = wp_cache_get( 'bp_total_blogs', 'bp' );
1138
-
1139
- if ( false === $count ) {
1140
- $blogs = BP_Blogs_Blog::get_all();
1141
- $count = $blogs['total'];
1142
- wp_cache_set( 'bp_total_blogs', $count, 'bp' );
1143
- }
1144
- return $count;
1145
- }
1146
-
1147
- /**
1148
- * Get the total number of blogs being tracked by BP for a specific user.
1149
- *
1150
- * @since 1.2.0
1151
- *
1152
- * @param int $user_id ID of the user being queried. Default: on a user page,
1153
- * the displayed user. Otherwise, the logged-in user.
1154
- * @return int $count Total blog count for the user.
1155
- */
1156
- function bp_blogs_total_blogs_for_user( $user_id = 0 ) {
1157
- if ( empty( $user_id ) ) {
1158
- $user_id = ( bp_displayed_user_id() ) ? bp_displayed_user_id() : bp_loggedin_user_id();
1159
- }
1160
-
1161
- // No user ID? do not attempt to look at cache.
1162
- if ( empty( $user_id ) ) {
1163
- return 0;
1164
- }
1165
-
1166
- $count = wp_cache_get( 'bp_total_blogs_for_user_' . $user_id, 'bp' );
1167
- if ( false === $count ) {
1168
- $count = BP_Blogs_Blog::total_blog_count_for_user( $user_id );
1169
- wp_cache_set( 'bp_total_blogs_for_user_' . $user_id, $count, 'bp' );
1170
- }
1171
-
1172
- return $count;
1173
- }
1174
-
1175
- /**
1176
- * Remove the all data related to a given blog from the BP blogs tracker and activity stream.
1177
- *
1178
- * @param int $blog_id The ID of the blog to expunge.
1179
- */
1180
- function bp_blogs_remove_data_for_blog( $blog_id ) {
1181
-
1182
- /**
1183
- * Fires before all data related to a given blog is removed from blogs tracker
1184
- * and activity stream.
1185
- *
1186
- * @since 1.5.0
1187
- *
1188
- * @param int $blog_id ID of the blog whose data is being removed.
1189
- */
1190
- do_action( 'bp_blogs_before_remove_data_for_blog', $blog_id );
1191
-
1192
- // If this is regular blog, delete all data for that blog.
1193
- BP_Blogs_Blog::delete_blog_for_all( $blog_id );
1194
-
1195
- /**
1196
- * Fires after all data related to a given blog has been removed from blogs tracker
1197
- * and activity stream.
1198
- *
1199
- * @since 1.0.0
1200
- *
1201
- * @param int $blog_id ID of the blog whose data is being removed.
1202
- */
1203
- do_action( 'bp_blogs_remove_data_for_blog', $blog_id );
1204
- }
1205
- add_action( 'delete_blog', 'bp_blogs_remove_data_for_blog', 1 );
1206
-
1207
- /**
1208
- * Get all of a user's blogs, as tracked by BuddyPress.
1209
- *
1210
- * @see BP_Blogs_Blog::get_blogs_for_user() for a description of parameters
1211
- * and return values.
1212
- *
1213
- * @param int $user_id See {@BP_Blogs_Blog::get_blogs_for_user()}.
1214
- * @param bool $show_hidden See {@BP_Blogs_Blog::get_blogs_for_user()}.
1215
- * @return array See {@BP_Blogs_Blog::get_blogs_for_user()}.
1216
- */
1217
- function bp_blogs_get_blogs_for_user( $user_id, $show_hidden = false ) {
1218
- return BP_Blogs_Blog::get_blogs_for_user( $user_id, $show_hidden );
1219
- }
1220
-
1221
- /**
1222
- * Retrieve a list of all blogs.
1223
- *
1224
- * @see BP_Blogs_Blog::get_all() for a description of parameters and return values.
1225
- *
1226
- * @param int|null $limit See {@BP_Blogs_Blog::get_all()}.
1227
- * @param int|null $page See {@BP_Blogs_Blog::get_all()}.
1228
- * @return array See {@BP_Blogs_Blog::get_all()}.
1229
- */
1230
- function bp_blogs_get_all_blogs( $limit = null, $page = null ) {
1231
- return BP_Blogs_Blog::get_all( $limit, $page );
1232
- }
1233
-
1234
- /**
1235
- * Retrieve a random list of blogs.
1236
- *
1237
- * @see BP_Blogs_Blog::get() for a description of parameters and return values.
1238
- *
1239
- * @param int|null $limit See {@BP_Blogs_Blog::get()}.
1240
- * @param int|null $page See {@BP_Blogs_Blog::get()}.
1241
- * @return array See {@BP_Blogs_Blog::get()}.
1242
- */
1243
- function bp_blogs_get_random_blogs( $limit = null, $page = null ) {
1244
- return BP_Blogs_Blog::get( 'random', $limit, $page );
1245
- }
1246
-
1247
- /**
1248
- * Check whether a given blog is hidden.
1249
- *
1250
- * @see BP_Blogs_Blog::is_hidden() for a description of parameters and return values.
1251
- *
1252
- * @param int $blog_id See {@BP_Blogs_Blog::is_hidden()}.
1253
- * @return bool See {@BP_Blogs_Blog::is_hidden()}.
1254
- */
1255
- function bp_blogs_is_blog_hidden( $blog_id ) {
1256
- return BP_Blogs_Blog::is_hidden( $blog_id );
1257
- }
1258
-
1259
- /*
1260
- * Blog meta functions
1261
- *
1262
- * These functions are used to store specific blogmeta in one global table,
1263
- * rather than in each blog's options table. Significantly speeds up global blog
1264
- * queries. By default each blog's name, description and last updated time are
1265
- * stored and synced here.
1266
- */
1267
-
1268
- /**
1269
- * Delete a metadata from the DB for a blog.
1270
- *
1271
- * @global object $wpdb WordPress database access object.
1272
- *
1273
- * @param int $blog_id ID of the blog whose metadata is being deleted.
1274
- * @param string|bool $meta_key Optional. The key of the metadata being deleted. If
1275
- * omitted, all BP metadata associated with the blog will
1276
- * be deleted.
1277
- * @param string|bool $meta_value Optional. If present, the metadata will only be
1278
- * deleted if the meta_value matches this parameter.
1279
- * @param bool $delete_all Optional. If true, delete matching metadata entries for
1280
- * all objects, ignoring the specified blog_id. Otherwise, only
1281
- * delete matching metadata entries for the specified blog.
1282
- * Default: false.
1283
- * @return bool True on success, false on failure.
1284
- */
1285
- function bp_blogs_delete_blogmeta( $blog_id, $meta_key = false, $meta_value = false, $delete_all = false ) {
1286
- global $wpdb;
1287
-
1288
- // Legacy - if no meta_key is passed, delete all for the blog_id.
1289
- if ( empty( $meta_key ) ) {
1290
- $keys = $wpdb->get_col( $wpdb->prepare( "SELECT meta_key FROM {$wpdb->blogmeta} WHERE blog_id = %d", $blog_id ) );
1291
- $delete_all = false;
1292
- } else {
1293
- $keys = array( $meta_key );
1294
- }
1295
-
1296
- add_filter( 'query', 'bp_filter_metaid_column_name' );
1297
-
1298
- $retval = false;
1299
- foreach ( $keys as $key ) {
1300
- $retval = delete_metadata( 'blog', $blog_id, $key, $meta_value, $delete_all );
1301
- }
1302
-
1303
- remove_filter( 'query', 'bp_filter_metaid_column_name' );
1304
-
1305
- return $retval;
1306
- }
1307
-
1308
- /**
1309
- * Get metadata for a given blog.
1310
- *
1311
- * @since 1.2.0
1312
- *
1313
- * @global object $wpdb WordPress database access object.
1314
- *
1315
- * @param int $blog_id ID of the blog whose metadata is being requested.
1316
- * @param string $meta_key Optional. If present, only the metadata matching
1317
- * that meta key will be returned. Otherwise, all
1318
- * metadata for the blog will be fetched.
1319
- * @param bool $single Optional. If true, return only the first value of the
1320
- * specified meta_key. This parameter has no effect if
1321
- * meta_key is not specified. Default: true.
1322
- * @return mixed The meta value(s) being requested.
1323
- */
1324
- function bp_blogs_get_blogmeta( $blog_id, $meta_key = '', $single = true ) {
1325
- add_filter( 'query', 'bp_filter_metaid_column_name' );
1326
- $retval = get_metadata( 'blog', $blog_id, $meta_key, $single );
1327
- remove_filter( 'query', 'bp_filter_metaid_column_name' );
1328
-
1329
- return $retval;
1330
- }
1331
-
1332
- /**
1333
- * Update a piece of blog meta.
1334
- *
1335
- * @global object $wpdb WordPress database access object.
1336
- *
1337
- * @param int $blog_id ID of the blog whose metadata is being updated.
1338
- * @param string $meta_key Key of the metadata being updated.
1339
- * @param mixed $meta_value Value to be set.
1340
- * @param mixed $prev_value Optional. If specified, only update existing
1341
- * metadata entries with the specified value.
1342
- * Otherwise, update all entries.
1343
- * @return bool|int Returns false on failure. On successful update of existing
1344
- * metadata, returns true. On successful creation of new metadata,
1345
- * returns the integer ID of the new metadata row.
1346
- */
1347
- function bp_blogs_update_blogmeta( $blog_id, $meta_key, $meta_value, $prev_value = '' ) {
1348
- add_filter( 'query', 'bp_filter_metaid_column_name' );
1349
- $retval = update_metadata( 'blog', $blog_id, $meta_key, $meta_value, $prev_value );
1350
- remove_filter( 'query', 'bp_filter_metaid_column_name' );
1351
-
1352
- return $retval;
1353
- }
1354
-
1355
- /**
1356
- * Add a piece of blog metadata.
1357
- *
1358
- * @since 2.0.0
1359
- *
1360
- * @param int $blog_id ID of the blog.
1361
- * @param string $meta_key Metadata key.
1362
- * @param mixed $meta_value Metadata value.
1363
- * @param bool $unique Optional. Whether to enforce a single metadata value
1364
- * for the given key. If true, and the object already has a value for
1365
- * the key, no change will be made. Default: false.
1366
- * @return int|bool The meta ID on successful update, false on failure.
1367
- */
1368
- function bp_blogs_add_blogmeta( $blog_id, $meta_key, $meta_value, $unique = false ) {
1369
- add_filter( 'query', 'bp_filter_metaid_column_name' );
1370
- $retval = add_metadata( 'blog', $blog_id, $meta_key, $meta_value, $unique );
1371
- remove_filter( 'query', 'bp_filter_metaid_column_name' );
1372
-
1373
- return $retval;
1374
- }
1375
- /**
1376
- * Remove all blog associations for a given user.
1377
- *
1378
- * @param int $user_id ID whose blog data should be removed.
1379
- * @return bool Returns false on failure.
1380
- */
1381
- function bp_blogs_remove_data( $user_id ) {
1382
- if ( !is_multisite() )
1383
- return false;
1384
-
1385
- /**
1386
- * Fires before all blog associations are removed for a given user.
1387
- *
1388
- * @since 1.5.0
1389
- *
1390
- * @param int $user_id ID of the user whose blog associations are being removed.
1391
- */
1392
- do_action( 'bp_blogs_before_remove_data', $user_id );
1393
-
1394
- // If this is regular blog, delete all data for that blog.
1395
- BP_Blogs_Blog::delete_blogs_for_user( $user_id );
1396
-
1397
- /**
1398
- * Fires after all blog associations are removed for a given user.
1399
- *
1400
- * @since 1.0.0
1401
- *
1402
- * @param int $user_id ID of the user whose blog associations were removed.
1403
- */
1404
- do_action( 'bp_blogs_remove_data', $user_id );
1405
- }
1406
- add_action( 'wpmu_delete_user', 'bp_blogs_remove_data' );
1407
- add_action( 'delete_user', 'bp_blogs_remove_data' );
1408
- add_action( 'bp_make_spam_user', 'bp_blogs_remove_data' );
1409
-
1410
- /**
1411
- * Restore all blog associations for a given user.
1412
- *
1413
- * @since 2.2.0
1414
- *
1415
- * @param int $user_id ID whose blog data should be restored.
1416
- */
1417
- function bp_blogs_restore_data( $user_id = 0 ) {
1418
- if ( ! is_multisite() ) {
1419
- return;
1420
- }
1421
-
1422
- // Get the user's blogs.
1423
- $user_blogs = get_blogs_of_user( $user_id );
1424
- if ( empty( $user_blogs ) ) {
1425
- return;
1426
- }
1427
-
1428
- $blogs = array_keys( $user_blogs );
1429
-
1430
- foreach ( $blogs as $blog_id ) {
1431
- bp_blogs_add_user_to_blog( $user_id, false, $blog_id );
1432
- }
1433
- }
1434
- add_action( 'bp_make_ham_user', 'bp_blogs_restore_data', 10, 1 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-blogs/bp-blogs-loader.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Blogs Loader
4
- *
5
- * The blogs component tracks posts and comments to member activity streams,
6
- * shows blogs the member can post to in their profiles, and caches useful
7
- * information from those blogs to make querying blogs in bulk more performant.
8
- *
9
- * @package BuddyPress
10
- * @subpackage BlogsCore
11
- * @since 1.5.0
12
- */
13
-
14
- // Exit if accessed directly.
15
- defined( 'ABSPATH' ) || exit;
16
-
17
- /**
18
- * Set up the bp-blogs component.
19
- *
20
- * @since 1.5.0
21
- */
22
- function bp_setup_blogs() {
23
- buddypress()->blogs = new BP_Blogs_Component();
24
- }
25
- add_action( 'bp_setup_components', 'bp_setup_blogs', 6 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-blogs/bp-blogs-screens.php DELETED
@@ -1,73 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Blogs Screens.
4
- *
5
- * @package BuddyPress
6
- * @subpackage BlogsScreens
7
- * @since 1.5.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Load the "My Blogs" screen.
15
- */
16
- function bp_blogs_screen_my_blogs() {
17
- if ( !is_multisite() )
18
- return false;
19
-
20
- /**
21
- * Fires right before the loading of the My Blogs screen template file.
22
- *
23
- * @since 1.0.0
24
- */
25
- do_action( 'bp_blogs_screen_my_blogs' );
26
-
27
- bp_core_load_template( apply_filters( 'bp_blogs_template_my_blogs', 'members/single/home' ) );
28
- }
29
-
30
- /**
31
- * Load the "Create a Blog" screen.
32
- */
33
- function bp_blogs_screen_create_a_blog() {
34
-
35
- if ( !is_multisite() || !bp_is_blogs_component() || !bp_is_current_action( 'create' ) )
36
- return false;
37
-
38
- if ( !is_user_logged_in() || !bp_blog_signup_enabled() )
39
- return false;
40
-
41
- /**
42
- * Fires right before the loading of the Create A Blog screen template file.
43
- *
44
- * @since 1.0.0
45
- */
46
- do_action( 'bp_blogs_screen_create_a_blog' );
47
-
48
- bp_core_load_template( apply_filters( 'bp_blogs_template_create_a_blog', 'blogs/create' ) );
49
- }
50
- add_action( 'bp_screens', 'bp_blogs_screen_create_a_blog', 3 );
51
-
52
- /**
53
- * Load the top-level Blogs directory.
54
- */
55
- function bp_blogs_screen_index() {
56
- if ( bp_is_blogs_directory() ) {
57
- bp_update_is_directory( true, 'blogs' );
58
-
59
- /**
60
- * Fires right before the loading of the top-level Blogs screen template file.
61
- *
62
- * @since 1.0.0
63
- */
64
- do_action( 'bp_blogs_screen_index' );
65
-
66
- bp_core_load_template( apply_filters( 'bp_blogs_screen_index', 'blogs/index' ) );
67
- }
68
- }
69
- add_action( 'bp_screens', 'bp_blogs_screen_index', 2 );
70
-
71
- /** Theme Compatibility *******************************************************/
72
-
73
- new BP_Blogs_Theme_Compat();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-blogs/bp-blogs-template.php DELETED
@@ -1,1544 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Blogs Template Tags.
4
- *
5
- * @package BuddyPress
6
- * @subpackage BlogsTemplate
7
- * @since 1.5.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Output the blogs component slug.
15
- *
16
- * @since 1.5.0
17
- *
18
- */
19
- function bp_blogs_slug() {
20
- echo bp_get_blogs_slug();
21
- }
22
- /**
23
- * Return the blogs component slug.
24
- *
25
- * @since 1.5.0
26
- *
27
- * @return string The 'blogs' slug.
28
- */
29
- function bp_get_blogs_slug() {
30
-
31
- /**
32
- * Filters the blogs component slug.
33
- *
34
- * @since 1.5.0
35
- *
36
- * @param string $slug Slug for the blogs component.
37
- */
38
- return apply_filters( 'bp_get_blogs_slug', buddypress()->blogs->slug );
39
- }
40
-
41
- /**
42
- * Output the blogs component root slug.
43
- *
44
- * @since 1.5.0
45
- *
46
- */
47
- function bp_blogs_root_slug() {
48
- echo bp_get_blogs_root_slug();
49
- }
50
- /**
51
- * Return the blogs component root slug.
52
- *
53
- * @since 1.5.0
54
- *
55
- * @return string The 'blogs' root slug.
56
- */
57
- function bp_get_blogs_root_slug() {
58
-
59
- /**
60
- * Filters the blogs component root slug.
61
- *
62
- * @since 1.5.0
63
- *
64
- * @param string $root_slug Root slug for the blogs component.
65
- */
66
- return apply_filters( 'bp_get_blogs_root_slug', buddypress()->blogs->root_slug );
67
- }
68
-
69
- /**
70
- * Output blog directory permalink.
71
- *
72
- * @since 1.5.0
73
- *
74
- */
75
- function bp_blogs_directory_permalink() {
76
- echo esc_url( bp_get_blogs_directory_permalink() );
77
- }
78
- /**
79
- * Return blog directory permalink.
80
- *
81
- * @since 1.5.0
82
- *
83
- *
84
- * @return string The URL of the Blogs directory.
85
- */
86
- function bp_get_blogs_directory_permalink() {
87
-
88
- /**
89
- * Filters the blog directory permalink.
90
- *
91
- * @since 1.5.0
92
- *
93
- * @param string $value Permalink URL for the blog directory.
94
- */
95
- return apply_filters( 'bp_get_blogs_directory_permalink', trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() ) );
96
- }
97
-
98
- /**
99
- * Rewind the blogs and reset blog index.
100
- */
101
- function bp_rewind_blogs() {
102
- global $blogs_template;
103
-
104
- $blogs_template->rewind_blogs();
105
- }
106
-
107
- /**
108
- * Initialize the blogs loop.
109
- *
110
- * Based on the $args passed, bp_has_blogs() populates the $blogs_template
111
- * global, enabling the use of BuddyPress templates and template functions to
112
- * display a list of activity items.
113
- *
114
- * @global object $blogs_template {@link BP_Blogs_Template}
115
- *
116
- * @param array|string $args {
117
- * Arguments for limiting the contents of the blogs loop. Most arguments
118
- * are in the same format as {@link BP_Blogs_Blog::get()}. However, because
119
- * the format of the arguments accepted here differs in a number of ways,
120
- * and because bp_has_blogs() determines some default arguments in a
121
- * dynamic fashion, we list all accepted arguments here as well.
122
- *
123
- * Arguments can be passed as an associative array, or as a URL query
124
- * string (eg, 'user_id=4&per_page=3').
125
- *
126
- * @type int $page Which page of results to fetch. Using page=1 without
127
- * per_page will result in no pagination. Default: 1.
128
- * @type int|bool $per_page Number of results per page. Default: 20.
129
- * @type string $page_arg The string used as a query parameter in
130
- * pagination links. Default: 'bpage'.
131
- * @type int|bool $max Maximum number of results to return.
132
- * Default: false (unlimited).
133
- * @type string $type The order in which results should be fetched.
134
- * 'active', 'alphabetical', 'newest', or 'random'.
135
- * @type array $include_blog_ids Array of blog IDs to limit results to.
136
- * @type string $sort 'ASC' or 'DESC'. Default: 'DESC'.
137
- * @type string $search_terms Limit results by a search term. Default: the value of `$_REQUEST['s']` or
138
- * `$_REQUEST['sites_search']`, if present.
139
- * @type int $user_id The ID of the user whose blogs should be retrieved.
140
- * When viewing a user profile page, 'user_id' defaults to the
141
- * ID of the displayed user. Otherwise the default is false.
142
- * }
143
- * @return bool Returns true when blogs are found, otherwise false.
144
- */
145
- function bp_has_blogs( $args = '' ) {
146
- global $blogs_template;
147
-
148
- // Check for and use search terms.
149
- $search_terms_default = false;
150
- $search_query_arg = bp_core_get_component_search_query_arg( 'blogs' );
151
- if ( ! empty( $_REQUEST[ $search_query_arg ] ) ) {
152
- $search_terms_default = stripslashes( $_REQUEST[ $search_query_arg ] );
153
- } elseif ( ! empty( $_REQUEST['s'] ) ) {
154
- $search_terms_default = stripslashes( $_REQUEST['s'] );
155
- }
156
-
157
- // Parse arguments.
158
- $r = bp_parse_args( $args, array(
159
- 'type' => 'active',
160
- 'page_arg' => 'bpage', // See https://buddypress.trac.wordpress.org/ticket/3679.
161
- 'page' => 1,
162
- 'per_page' => 20,
163
- 'max' => false,
164
- 'user_id' => bp_displayed_user_id(), // Pass a user_id to limit to only blogs this user is a member of.
165
- 'include_blog_ids' => false,
166
- 'search_terms' => $search_terms_default,
167
- 'update_meta_cache' => true
168
- ), 'has_blogs' );
169
-
170
- // Set per_page to maximum if max is enforced.
171
- if ( ! empty( $r['max'] ) && ( (int) $r['per_page'] > (int) $r['max'] ) ) {
172
- $r['per_page'] = (int) $r['max'];
173
- }
174
-
175
- // Get the blogs.
176
- $blogs_template = new BP_Blogs_Template( $r['type'], $r['page'], $r['per_page'], $r['max'], $r['user_id'], $r['search_terms'], $r['page_arg'], $r['update_meta_cache'], $r['include_blog_ids'] );
177
-
178
- /**
179
- * Filters whether or not there are blogs to list.
180
- *
181
- * @since 1.1.0
182
- *
183
- * @param bool $value Whether or not there are blogs to list.
184
- * @param BP_Blogs_Template $blogs_template Current blogs template object.
185
- * @param array $r Parsed arguments used in blogs template query.
186
- */
187
- return apply_filters( 'bp_has_blogs', $blogs_template->has_blogs(), $blogs_template, $r );
188
- }
189
-
190
- /**
191
- * Determine if there are still blogs left in the loop.
192
- *
193
- * @global object $blogs_template {@link BP_Blogs_Template}
194
- *
195
- * @return bool Returns true when blogs are found.
196
- */
197
- function bp_blogs() {
198
- global $blogs_template;
199
-
200
- return $blogs_template->blogs();
201
- }
202
-
203
- /**
204
- * Get the current blog object in the loop.
205
- *
206
- * @global object $blogs_template {@link BP_Blogs_Template}
207
- *
208
- * @return object The current blog within the loop.
209
- */
210
- function bp_the_blog() {
211
- global $blogs_template;
212
-
213
- return $blogs_template->the_blog();
214
- }
215
-
216
- /**
217
- * Output the blogs pagination count.
218
- *
219
- * @since 1.0.0
220
- */
221
- function bp_blogs_pagination_count() {
222
- echo bp_get_blogs_pagination_count();
223
- }
224
-
225
- /**
226
- * Get the blogs pagination count.
227
- *
228
- * @since 2.7.0
229
- *
230
- * @global object $blogs_template {@link BP_Blogs_Template}
231
- *
232
- * @return string
233
- */
234
- function bp_get_blogs_pagination_count() {
235
- global $blogs_template;
236
-
237
- $start_num = intval( ( $blogs_template->pag_page - 1 ) * $blogs_template->pag_num ) + 1;
238
- $from_num = bp_core_number_format( $start_num );
239
- $to_num = bp_core_number_format( ( $start_num + ( $blogs_template->pag_num - 1 ) > $blogs_template->total_blog_count ) ? $blogs_template->total_blog_count : $start_num + ( $blogs_template->pag_num - 1 ) );
240
- $total = bp_core_number_format( $blogs_template->total_blog_count );
241
-
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
-
248
- /**
249
- * Filters the "Viewing x-y of z blogs" pagination message.
250
- *
251
- * @since 2.7.0
252
- *
253
- * @param string $message "Viewing x-y of z blogs" text.
254
- * @param string $from_num Total amount for the low value in the range.
255
- * @param string $to_num Total amount for the high value in the range.
256
- * @param string $total Total amount of blogs found.
257
- */
258
- return apply_filters( 'bp_get_blogs_pagination_count', $message, $from_num, $to_num, $total );
259
- }
260
-
261
- /**
262
- * Output the blogs pagination links.
263
- */
264
- function bp_blogs_pagination_links() {
265
- echo bp_get_blogs_pagination_links();
266
- }
267
- /**
268
- * Return the blogs pagination links.
269
- *
270
- * @global object $blogs_template {@link BP_Blogs_Template}
271
- *
272
- * @return string HTML pagination links.
273
- */
274
- function bp_get_blogs_pagination_links() {
275
- global $blogs_template;
276
-
277
- /**
278
- * Filters the blogs pagination links.
279
- *
280
- * @since 1.0.0
281
- *
282
- * @param string $pag_links HTML pagination links.
283
- */
284
- return apply_filters( 'bp_get_blogs_pagination_links', $blogs_template->pag_links );
285
- }
286
-
287
- /**
288
- * Output a blog's avatar.
289
- *
290
- * @see bp_get_blog_avatar() for description of arguments.
291
- *
292
- * @param array|string $args See {@link bp_get_blog_avatar()}.
293
- */
294
- function bp_blog_avatar( $args = '' ) {
295
- echo bp_get_blog_avatar( $args );
296
- }
297
- /**
298
- * Get a blog's avatar.
299
- *
300
- * At the moment, blog avatars are simply the user avatars of the blog
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.
307
- *
308
- * @param array|string $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
- */
322
- function bp_get_blog_avatar( $args = '' ) {
323
- global $blogs_template;
324
-
325
- // Bail if avatars are turned off
326
- // @todo Should we maybe still filter this?
327
- if ( ! buddypress()->avatar->show_avatars ) {
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(
335
- 'type' => 'full',
336
- 'width' => false,
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'] ) {
355
- $size = bp_core_avatar_thumb_width();
356
- $save_size = 'thumb';
357
- } else {
358
- $size = bp_core_avatar_full_width();
359
- $save_size = 'full';
360
- }
361
-
362
- $site_icon = get_site_icon_url( $size );
363
- // Empty site icons get saved as integer 0.
364
- if ( empty( $site_icon ) ) {
365
- $site_icon = 0;
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 ) {
373
- $size = 'full' === $r['type'] ? bp_core_avatar_full_width() : bp_core_avatar_thumb_width();
374
- $site_icon = get_site_icon_url( $size );
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
- }
382
-
383
- // We have a site icon.
384
- if ( ! is_numeric( $site_icon ) ) {
385
- if ( empty( $r['width'] ) && ! isset( $size ) ) {
386
- $size = 'full' === $r['type'] ? bp_core_avatar_full_width() : bp_core_avatar_thumb_width();
387
- } else {
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
- }
399
-
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'],
407
- 'alt' => $r['alt'],
408
- 'css_id' => $r['id'],
409
- 'class' => $r['class'],
410
- 'width' => $r['width'],
411
- 'height' => $r['height']
412
- ) );
413
- }
414
-
415
- /**
416
- * In future BuddyPress versions you will be able to set the avatar for a blog.
417
- * Right now you can use a filter with the ID of the blog to change it if you wish.
418
- * By default it will return the avatar for the primary blog admin.
419
- *
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.
427
- *
428
- * @since 1.5.0
429
- *
430
- * @param string $avatar Formatted HTML <img> element, or raw avatar
431
- * URL based on $html arg.
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() {
439
- echo bp_get_blog_permalink();
440
- }
441
- function bp_get_blog_permalink() {
442
- global $blogs_template;
443
-
444
- if ( empty( $blogs_template->blog->domain ) )
445
- $permalink = bp_get_root_domain() . $blogs_template->blog->path;
446
- else {
447
- $protocol = 'http://';
448
- if ( is_ssl() )
449
- $protocol = 'https://';
450
-
451
- $permalink = $protocol . $blogs_template->blog->domain . $blogs_template->blog->path;
452
- }
453
-
454
- /**
455
- * Filters the blog permalink.
456
- *
457
- * @since 1.0.0
458
- *
459
- * @param string $permalink Permalink URL for the blog.
460
- */
461
- return apply_filters( 'bp_get_blog_permalink', $permalink );
462
- }
463
-
464
- /**
465
- * Output the name of the current blog in the loop.
466
- */
467
- function bp_blog_name() {
468
- echo bp_get_blog_name();
469
- }
470
- /**
471
- * Return the name of the current blog in the loop.
472
- *
473
- * @return string The name of the current blog in the loop.
474
- */
475
- function bp_get_blog_name() {
476
- global $blogs_template;
477
-
478
- /**
479
- * Filters the name of the current blog in the loop.
480
- *
481
- * @since 1.2.0
482
- *
483
- * @param string $name Name of the current blog in the loop.
484
- */
485
- return apply_filters( 'bp_get_blog_name', $blogs_template->blog->name );
486
- }
487
-
488
- /**
489
- * Output the ID of the current blog in the loop.
490
- *
491
- * @since 1.7.0
492
- */
493
- function bp_blog_id() {
494
- echo bp_get_blog_id();
495
- }
496
- /**
497
- * Return the ID of the current blog in the loop.
498
- *
499
- * @since 1.7.0
500
- *
501
- * @return int ID of the current blog in the loop.
502
- */
503
- function bp_get_blog_id() {
504
- global $blogs_template;
505
-
506
- /**
507
- * Filters the ID of the current blog in the loop.
508
- *
509
- * @since 1.7.0
510
- *
511
- * @param int $blog_id ID of the current blog in the loop.
512
- */
513
- return apply_filters( 'bp_get_blog_id', $blogs_template->blog->blog_id );
514
- }
515
-
516
- /**
517
- * Output the description of the current blog in the loop.
518
- */
519
- function bp_blog_description() {
520
-
521
- /**
522
- * Filters the description of the current blog in the loop.
523
- *
524
- * @since 1.2.0
525
- *
526
- * @param string $value Description of the current blog in the loop.
527
- */
528
- echo apply_filters( 'bp_blog_description', bp_get_blog_description() );
529
- }
530
- /**
531
- * Return the description of the current blog in the loop.
532
- *
533
- * @return string Description of the current blog in the loop.
534
- */
535
- function bp_get_blog_description() {
536
- global $blogs_template;
537
-
538
- /**
539
- * Filters the description of the current blog in the loop.
540
- *
541
- * @since 1.0.0
542
- *
543
- * @param string $value Description of the current blog in the loop.
544
- */
545
- return apply_filters( 'bp_get_blog_description', $blogs_template->blog->description );
546
- }
547
-
548
- /**
549
- * Output the row class of the current blog in the loop.
550
- *
551
- * @since 1.7.0
552
- *
553
- * @param array $classes Array of custom classes.
554
- */
555
- function bp_blog_class( $classes = array() ) {
556
- echo bp_get_blog_class( $classes );
557
- }
558
- /**
559
- * Return the row class of the current blog in the loop.
560
- *
561
- * @since 1.7.0
562
- *
563
- * @global BP_Blogs_Template $blogs_template
564
- *
565
- * @param array $classes Array of custom classes.
566
- * @return string Row class of the site.
567
- */
568
- function bp_get_blog_class( $classes = array() ) {
569
- global $blogs_template;
570
-
571
- // Add even/odd classes, but only if there's more than 1 group.
572
- if ( $blogs_template->blog_count > 1 ) {
573
- $pos_in_loop = (int) $blogs_template->current_blog;
574
- $classes[] = ( $pos_in_loop % 2 ) ? 'even' : 'odd';
575
-
576
- // If we've only one site in the loop, don't bother with odd and even.
577
- } else {
578
- $classes[] = 'bp-single-blog';
579
- }
580
-
581
- /**
582
- * Filters the row class of the current blog in the loop.
583
- *
584
- * @since 1.7.0
585
- *
586
- * @param array $classes Array of classes to be applied to row.
587
- */
588
- $classes = apply_filters( 'bp_get_blog_class', $classes );
589
- $classes = array_merge( $classes, array() );
590
- $retval = 'class="' . join( ' ', $classes ) . '"';
591
-
592
- return $retval;
593
- }
594
-
595
- /**
596
- * Output the last active date of the current blog in the loop.
597
- *
598
- * @param array $args See {@link bp_get_blog_last_active()}.
599
- */
600
- function bp_blog_last_active( $args = array() ) {
601
- echo bp_get_blog_last_active( $args );
602
- }
603
- /**
604
- * Return the last active date of the current blog in the loop.
605
- *
606
- * @param array $args {
607
- * Array of optional arguments.
608
- * @type bool $active_format If true, formatted "Active 5 minutes ago".
609
- * If false, formatted "5 minutes ago".
610
- * Default: true.
611
- * }
612
- * @return string Last active date.
613
- */
614
- function bp_get_blog_last_active( $args = array() ) {
615
- global $blogs_template;
616
-
617
- // Parse the activity format.
618
- $r = bp_parse_args( $args, array(
619
- 'active_format' => true
620
- ) );
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.
628
- if ( isset( $blogs_template->blog->last_activity ) ) {
629
-
630
- // Backwards compatibility for pre 1.5 'ago' strings.
631
- $last_activity = ! empty( $r['active_format'] )
632
- ? bp_core_get_last_activity( $blogs_template->blog->last_activity, $r['active_format'] )
633
- : bp_core_time_since( $blogs_template->blog->last_activity );
634
-
635
- // Blog has never been posted to.
636
- } else {
637
- $last_activity = __( 'Never active', 'buddypress' );
638
- }
639
-
640
- /**
641
- * Filters the last active date of the current blog in the loop.
642
- *
643
- * @since 1.2.0
644
- *
645
- * @param string $last_activity Last active date.
646
- * @param array $r Array of parsed args used to determine formatting.
647
- */
648
- return apply_filters( 'bp_blog_last_active', $last_activity, $r );
649
- }
650
-
651
- /**
652
- * Output the latest post from the current blog in the loop.
653
- *
654
- * @param array $args See {@link bp_get_blog_latest_post()}.
655
- */
656
- function bp_blog_latest_post( $args = array() ) {
657
- echo bp_get_blog_latest_post( $args );
658
- }
659
- /**
660
- * Return the latest post from the current blog in the loop.
661
- *
662
- * @param array $args {
663
- * Array of optional arguments.
664
- * @type bool $latest_format If true, formatted "Latest post: [link to post]".
665
- * If false, formatted "[link to post]".
666
- * Default: true.
667
- * }
668
- * @return string $retval String of the form 'Latest Post: [link to post]'.
669
- */
670
- function bp_get_blog_latest_post( $args = array() ) {
671
- global $blogs_template;
672
-
673
- $r = wp_parse_args( $args, array(
674
- 'latest_format' => true,
675
- ) );
676
-
677
- $retval = bp_get_blog_latest_post_title();
678
-
679
- if ( ! empty( $retval ) ) {
680
- if ( ! empty( $r['latest_format'] ) ) {
681
-
682
- /**
683
- * Filters the title text of the latest post for the current blog in loop.
684
- *
685
- * @since 1.0.0
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 */
693
- $retval = '<a href="' . $blogs_template->blog->latest_post->guid . '">' . apply_filters( 'the_title', $retval ) . '</a>';
694
- }
695
- }
696
-
697
- /**
698
- * Filters the HTML markup result for the latest blog post in loop.
699
- *
700
- * @since 1.2.0
701
- * @since 2.6.0 Added the `$r` parameter.
702
- *
703
- * @param string $retval HTML markup for the latest post.
704
- * @param array $r Array of parsed arguments.
705
- */
706
- return apply_filters( 'bp_get_blog_latest_post', $retval, $r );
707
- }
708
-
709
- /**
710
- * Output the title of the latest post on the current blog in the loop.
711
- *
712
- * @since 1.7.0
713
- *
714
- * @see bp_get_blog_latest_post_title()
715
- */
716
- function bp_blog_latest_post_title() {
717
- echo bp_get_blog_latest_post_title();
718
- }
719
- /**
720
- * Return the title of the latest post on the current blog in the loop.
721
- *
722
- * @since 1.7.0
723
- *
724
- * @global BP_Blogs_Template
725
- *
726
- * @return string Post title.
727
- */
728
- function bp_get_blog_latest_post_title() {
729
- global $blogs_template;
730
-
731
- $retval = '';
732
-
733
- if ( ! empty( $blogs_template->blog->latest_post ) && ! empty( $blogs_template->blog->latest_post->post_title ) )
734
- $retval = $blogs_template->blog->latest_post->post_title;
735
-
736
- /**
737
- * Filters the title text of the latest post on the current blog in the loop.
738
- *
739
- * @since 1.7.0
740
- *
741
- * @param string $retval Title text for the latest post.
742
- */
743
- return apply_filters( 'bp_get_blog_latest_post_title', $retval );
744
- }
745
-
746
- /**
747
- * Output the permalink of the latest post on the current blog in the loop.
748
- *
749
- * @since 1.7.0
750
- *
751
- * @see bp_get_blog_latest_post_title()
752
- */
753
- function bp_blog_latest_post_permalink() {
754
- echo esc_url( bp_get_blog_latest_post_permalink() );
755
- }
756
- /**
757
- * Return the permalink of the latest post on the current blog in the loop.
758
- *
759
- * @since 1.7.0
760
- *
761
- * @global BP_Blogs_Template
762
- *
763
- * @return string URL of the blog's latest post.
764
- */
765
- function bp_get_blog_latest_post_permalink() {
766
- global $blogs_template;
767
-
768
- $retval = '';
769
-
770
- if ( ! empty( $blogs_template->blog->latest_post ) && ! empty( $blogs_template->blog->latest_post->ID ) )
771
- $retval = add_query_arg( 'p', $blogs_template->blog->latest_post->ID, bp_get_blog_permalink() );
772
-
773
- /**
774
- * Filters the permalink of the latest post on the current blog in the loop.
775
- *
776
- * @since 1.7.0
777
- *
778
- * @param string $retval Permalink URL of the latest post.
779
- */
780
- return apply_filters( 'bp_get_blog_latest_post_permalink', $retval );
781
- }
782
-
783
- /**
784
- * Output the content of the latest post on the current blog in the loop.
785
- *
786
- * @since 1.7.0
787
- *
788
- */
789
- function bp_blog_latest_post_content() {
790
- echo bp_get_blog_latest_post_content();
791
- }
792
- /**
793
- * Return the content of the latest post on the current blog in the loop.
794
- *
795
- * @since 1.7.0
796
- *
797
- * @global BP_Blogs_Template
798
- *
799
- * @return string Content of the blog's latest post.
800
- */
801
- function bp_get_blog_latest_post_content() {
802
- global $blogs_template;
803
-
804
- $retval = '';
805
-
806
- if ( ! empty( $blogs_template->blog->latest_post ) && ! empty( $blogs_template->blog->latest_post->post_content ) )
807
- $retval = $blogs_template->blog->latest_post->post_content;
808
-
809
- /**
810
- * Filters the content of the latest post on the current blog in the loop.
811
- *
812
- * @since 1.7.0
813
- *
814
- * @param string $retval Content of the latest post on the current blog in the loop.
815
- */
816
- return apply_filters( 'bp_get_blog_latest_post_content', $retval );
817
- }
818
-
819
- /**
820
- * Output the featured image of the latest post on the current blog in the loop.
821
- *
822
- * @since 1.7.0
823
- *
824
- * @see bp_get_blog_latest_post_content() For description of parameters.
825
- *
826
- * @param string $size See {@link bp_get_blog_latest_post_featured_image()}.
827
- */
828
- function bp_blog_latest_post_featured_image( $size = 'thumbnail' ) {
829
- echo bp_get_blog_latest_post_featured_image( $size );
830
- }
831
- /**
832
- * Return the featured image of the latest post on the current blog in the loop.
833
- *
834
- * @since 1.7.0
835
- *
836
- * @global BP_Blogs_Template
837
- *
838
- * @param string $size Image version to return. 'thumbnail', 'medium',
839
- * 'large', or 'post-thumbnail'. Default: 'thumbnail'.
840
- * @return string URL of the image.
841
- */
842
- function bp_get_blog_latest_post_featured_image( $size = 'thumbnail' ) {
843
- global $blogs_template;
844
-
845
- $retval = '';
846
-
847
- if ( ! empty( $blogs_template->blog->latest_post ) && ! empty( $blogs_template->blog->latest_post->images[$size] ) )
848
- $retval = $blogs_template->blog->latest_post->images[$size];
849
-
850
- /**
851
- * Filters the featured image of the latest post on the current blog in the loop.
852
- *
853
- * @since 1.7.0
854
- *
855
- * @param string $retval The featured image of the latest post on the current blog in the loop.
856
- */
857
- return apply_filters( 'bp_get_blog_latest_post_featured_image', $retval );
858
- }
859
-
860
- /**
861
- * Does the latest blog post have a featured image?
862
- *
863
- * @since 1.7.0
864
- *
865
- * @param string $thumbnail Image version to return. 'thumbnail', 'medium', 'large',
866
- * or 'post-thumbnail'. Default: 'thumbnail'.
867
- * @return bool True if the latest blog post from the current blog has a
868
- * featured image of the given size.
869
- */
870
- function bp_blog_latest_post_has_featured_image( $thumbnail = 'thumbnail' ) {
871
- $image = bp_get_blog_latest_post_featured_image( $thumbnail );
872
-
873
- /**
874
- * Filters whether or not the latest blog post has a featured image.
875
- *
876
- * @since 1.7.0
877
- *
878
- * @param bool $value Whether or not the latest blog post has a featured image.
879
- * @param string $thumbnail Image version to return.
880
- * @param string $image Returned value from bp_get_blog_latest_post_featured_image.
881
- */
882
- return apply_filters( 'bp_blog_latest_post_has_featured_image', ! empty( $image ), $thumbnail, $image );
883
- }
884
-
885
- /**
886
- * Output hidden fields to help with form submissions in Sites directory.
887
- *
888
- * This function detects whether 's', 'letter', or 'blogs_search' requests are
889
- * currently being made (as in a URL parameter), and creates corresponding
890
- * hidden fields.
891
- */
892
- function bp_blog_hidden_fields() {
893
- if ( isset( $_REQUEST['s'] ) )
894
- echo '<input type="hidden" id="search_terms" value="' . esc_attr( $_REQUEST['s'] ). '" name="search_terms" />';
895
-
896
- if ( isset( $_REQUEST['letter'] ) )
897
- echo '<input type="hidden" id="selected_letter" value="' . esc_attr( $_REQUEST['letter'] ) . '" name="selected_letter" />';
898
-
899
- if ( isset( $_REQUEST['blogs_search'] ) )
900
- echo '<input type="hidden" id="search_terms" value="' . esc_attr( $_REQUEST['blogs_search'] ) . '" name="search_terms" />';
901
- }
902
-
903
- /**
904
- * Output the total number of blogs on the site.
905
- */
906
- function bp_total_blog_count() {
907
- echo bp_get_total_blog_count();
908
- }
909
- /**
910
- * Return the total number of blogs on the site.
911
- *
912
- * @return int Total number of blogs.
913
- */
914
- function bp_get_total_blog_count() {
915
-
916
- /**
917
- * Filters the total number of blogs on the site.
918
- *
919
- * @since 1.2.0
920
- *
921
- * @param int $value Total number of blogs on the site.
922
- */
923
- return apply_filters( 'bp_get_total_blog_count', bp_blogs_total_blogs() );
924
- }
925
- add_filter( 'bp_get_total_blog_count', 'bp_core_number_format' );
926
-
927
- /**
928
- * Output the total number of blogs for a given user.
929
- *
930
- * @param int $user_id ID of the user.
931
- */
932
- function bp_total_blog_count_for_user( $user_id = 0 ) {
933
- echo bp_get_total_blog_count_for_user( $user_id );
934
- }
935
- /**
936
- * Return the total number of blogs for a given user.
937
- *
938
- * @param int $user_id ID of the user.
939
- * @return int Total number of blogs for the user.
940
- */
941
- function bp_get_total_blog_count_for_user( $user_id = 0 ) {
942
-
943
- /**
944
- * Filters the total number of blogs for a given user.
945
- *
946
- * @since 1.2.0
947
- * @since 2.6.0 Added the `$user_id` parameter.
948
- *
949
- * @param int $value Total number of blogs for a given user.
950
- * @param int $user_id ID of the queried user.
951
- */
952
- return apply_filters( 'bp_get_total_blog_count_for_user', bp_blogs_total_blogs_for_user( $user_id ), $user_id );
953
- }
954
- add_filter( 'bp_get_total_blog_count_for_user', 'bp_core_number_format' );
955
-
956
-
957
- /** Blog Registration ********************************************************/
958
-
959
- /**
960
- * Checks whether blog creation is enabled.
961
- *
962
- * Returns true when blog creation is enabled for logged-in users only, or
963
- * when it's enabled for new registrations.
964
- *
965
- * @return bool True if blog registration is enabled.
966
- */
967
- function bp_blog_signup_enabled() {
968
- $bp = buddypress();
969
-
970
- $active_signup = isset( $bp->site_options['registration'] )
971
- ? $bp->site_options['registration']
972
- : 'all';
973
-
974
- /**
975
- * Filters whether or not blog creation is enabled.
976
- *
977
- * Return "all", "none", "blog" or "user".
978
- *
979
- * @since 1.0.0
980
- *
981
- * @param string $active_signup Value of the registration site option creation status.
982
- */
983
- $active_signup = apply_filters( 'wpmu_active_signup', $active_signup );
984
-
985
- if ( 'none' == $active_signup || 'user' == $active_signup )
986
- return false;
987
-
988
- return true;
989
- }
990
-
991
- /**
992
- * Output the wrapper markup for the blog signup form.
993
- *
994
- * @param string $blogname Optional. The default blog name (path or domain).
995
- * @param string $blog_title Optional. The default blog title.
996
- * @param string|WP_Error $errors Optional. The WP_Error object returned by a previous
997
- * submission attempt.
998
- */
999
- function bp_show_blog_signup_form($blogname = '', $blog_title = '', $errors = '') {
1000
- global $current_user;
1001
-
1002
- if ( isset($_POST['submit']) ) {
1003
- bp_blogs_validate_blog_signup();
1004
- } else {
1005
- if ( ! is_wp_error($errors) ) {
1006
- $errors = new WP_Error();
1007
- }
1008
-
1009
- /**
1010
- * Filters the default values for Blog name, title, and any current errors.
1011
- *
1012
- * @since 1.0.0
1013
- *
1014
- * @param array $value {
1015
- * string $blogname Default blog name provided.
1016
- * string $blog_title Default blog title provided.
1017
- * WP_Error $errors WP_Error object.
1018
- * }
1019
- */
1020
- $filtered_results = apply_filters('signup_another_blog_init', array('blogname' => $blogname, 'blog_title' => $blog_title, 'errors' => $errors ));
1021
- $blogname = $filtered_results['blogname'];
1022
- $blog_title = $filtered_results['blog_title'];
1023
- $errors = $filtered_results['errors'];
1024
-
1025
- if ( $errors->get_error_code() ) {
1026
- echo "<p>" . __('There was a problem; please correct the form below and try again.', 'buddypress') . "</p>";
1027
- }
1028
- ?>
1029
- <p><?php printf(__("By filling out the form below, you can <strong>add a site to your account</strong>. There is no limit to the number of sites that you can have, so create to your heart's content, but blog responsibly!", 'buddypress'), $current_user->display_name) ?></p>
1030
-
1031
- <p><?php _e("If you&#8217;re not going to use a great domain, leave it for a new user. Now have at it!", 'buddypress') ?></p>
1032
-
1033
- <form class="standard-form" id="setupform" method="post" action="">
1034
-
1035
- <input type="hidden" name="stage" value="gimmeanotherblog" />
1036
- <?php
1037
-
1038
- /**
1039
- * Fires after the default hidden fields in blog signup form markup.
1040
- *
1041
- * @since 1.0.0
1042
- */
1043
- do_action( 'signup_hidden_fields' ); ?>
1044
-
1045
- <?php bp_blogs_signup_blog($blogname, $blog_title, $errors); ?>
1046
- <p>
1047
- <input id="submit" type="submit" name="submit" class="submit" value="<?php esc_attr_e('Create Site', 'buddypress') ?>" />
1048
- </p>
1049
-
1050
- <?php wp_nonce_field( 'bp_blog_signup_form' ) ?>
1051
- </form>
1052
- <?php
1053
- }
1054
- }
1055
-
1056
- /**
1057
- * Output the input fields for the blog creation form.
1058
- *
1059
- * @param string $blogname Optional. The default blog name (path or domain).
1060
- * @param string $blog_title Optional. The default blog title.
1061
- * @param string|WP_Error $errors Optional. The WP_Error object returned by a previous
1062
- * submission attempt.
1063
- */
1064
- function bp_blogs_signup_blog( $blogname = '', $blog_title = '', $errors = '' ) {
1065
- global $current_site;
1066
-
1067
- // Blog name.
1068
- if( !is_subdomain_install() )
1069
- echo '<label for="blogname">' . __('Site Name:', 'buddypress') . '</label>';
1070
- else
1071
- echo '<label for="blogname">' . __('Site Domain:', 'buddypress') . '</label>';
1072
-
1073
- if ( $errmsg = $errors->get_error_message('blogname') ) { ?>
1074
-
1075
- <p class="error"><?php echo $errmsg ?></p>
1076
-
1077
- <?php }
1078
-
1079
- if ( !is_subdomain_install() )
1080
- echo '<span class="prefix_address">' . $current_site->domain . $current_site->path . '</span> <input name="blogname" type="text" id="blogname" value="'.$blogname.'" maxlength="63" /><br />';
1081
- else
1082
- echo '<input name="blogname" type="text" id="blogname" value="'.$blogname.'" maxlength="63" ' . bp_get_form_field_attributes( 'blogname' ) . '/> <span class="suffix_address">.' . bp_signup_get_subdomain_base() . '</span><br />';
1083
-
1084
- if ( !is_user_logged_in() ) {
1085
- print '(<strong>' . __( 'Your address will be ' , 'buddypress');
1086
-
1087
- if ( !is_subdomain_install() ) {
1088
- print $current_site->domain . $current_site->path . __( 'blogname' , 'buddypress');
1089
- } else {
1090
- print __( 'domain.' , 'buddypress') . $current_site->domain . $current_site->path;
1091
- }
1092
-
1093
- echo '.</strong> ' . __( 'Must be at least 4 characters, letters and numbers only. It cannot be changed so choose carefully!)' , 'buddypress') . '</p>';
1094
- }
1095
-
1096
- // Blog Title.
1097
- ?>
1098
-
1099
- <label for="blog_title"><?php _e('Site Title:', 'buddypress') ?></label>
1100
-
1101
- <?php if ( $errmsg = $errors->get_error_message('blog_title') ) { ?>
1102
-
1103
- <p class="error"><?php echo $errmsg ?></p>
1104
-
1105
- <?php }
1106
- echo '<input name="blog_title" type="text" id="blog_title" value="'.esc_html($blog_title, 1).'" /></p>';
1107
- ?>
1108
-
1109
- <fieldset class="create-site">
1110
- <legend class="label"><?php _e('Privacy: I would like my site to appear in search engines, and in public listings around this network', 'buddypress') ?></legend>
1111
-
1112
- <label class="checkbox" for="blog_public_on">
1113
- <input type="radio" id="blog_public_on" name="blog_public" value="1" <?php if( !isset( $_POST['blog_public'] ) || '1' == $_POST['blog_public'] ) { ?>checked="checked"<?php } ?> />
1114
- <strong><?php _e( 'Yes' , 'buddypress'); ?></strong>
1115
- </label>
1116
- <label class="checkbox" for="blog_public_off">
1117
- <input type="radio" id="blog_public_off" name="blog_public" value="0" <?php if( isset( $_POST['blog_public'] ) && '0' == $_POST['blog_public'] ) { ?>checked="checked"<?php } ?> />
1118
- <strong><?php _e( 'No' , 'buddypress'); ?></strong>
1119
- </label>
1120
- </fieldset>
1121
-
1122
- <?php
1123
-
1124
- /**
1125
- * Fires at the end of all of the default input fields for blog creation form.
1126
- *
1127
- * @since 1.0.0
1128
- *
1129
- * @param WP_Error $errors WP_Error object if any present.
1130
- */
1131
- do_action('signup_blogform', $errors);
1132
- }
1133
-
1134
- /**
1135
- * Process a blog registration submission.
1136
- *
1137
- * Passes submitted values to {@link wpmu_create_blog()}.
1138
- *
1139
- * @return bool True on success, false on failure.
1140
- */
1141
- function bp_blogs_validate_blog_signup() {
1142
- global $wpdb, $current_user, $blogname, $blog_title, $errors, $domain, $path, $current_site;
1143
-
1144
- if ( !check_admin_referer( 'bp_blog_signup_form' ) )
1145
- return false;
1146
-
1147
- $current_user = wp_get_current_user();
1148
-
1149
- if( !is_user_logged_in() )
1150
- die();
1151
-
1152
- $result = bp_blogs_validate_blog_form();
1153
- extract($result);
1154
-
1155
- if ( $errors->get_error_code() ) {
1156
- unset($_POST['submit']);
1157
- bp_show_blog_signup_form( $blogname, $blog_title, $errors );
1158
- return false;
1159
- }
1160
-
1161
- $public = (int) $_POST['blog_public'];
1162
-
1163
- // Depreciated.
1164
- $meta = apply_filters( 'signup_create_blog_meta', array( 'lang_id' => 1, 'public' => $public ) );
1165
-
1166
- /**
1167
- * Filters the default values for Blog meta.
1168
- *
1169
- * @since 1.0.0
1170
- *
1171
- * @param array $meta {
1172
- * string $value Default blog language ID.
1173
- * string $public Default public status.
1174
- * }
1175
- */
1176
- $meta = apply_filters( 'add_signup_meta', $meta );
1177
-
1178
- // If this is a subdomain install, set up the site inside the root domain.
1179
- if ( is_subdomain_install() )
1180
- $domain = $blogname . '.' . preg_replace( '|^www\.|', '', $current_site->domain );
1181
-
1182
- $blog_id = wpmu_create_blog( $domain, $path, $blog_title, $current_user->ID, $meta, $wpdb->siteid );
1183
- bp_blogs_confirm_blog_signup( $domain, $path, $blog_title, $current_user->user_login, $current_user->user_email, $meta, $blog_id );
1184
- return true;
1185
- }
1186
-
1187
- /**
1188
- * Validate a blog creation submission.
1189
- *
1190
- * Essentially, a wrapper for {@link wpmu_validate_blog_signup()}.
1191
- *
1192
- * @return array Contains the new site data and error messages.
1193
- */
1194
- function bp_blogs_validate_blog_form() {
1195
- $user = '';
1196
- if ( is_user_logged_in() )
1197
- $user = wp_get_current_user();
1198
-
1199
- return wpmu_validate_blog_signup($_POST['blogname'], $_POST['blog_title'], $user);
1200
- }
1201
-
1202
- /**
1203
- * Display a message after successful blog registration.
1204
- *
1205
- * @since 2.6.0 Introduced `$blog_id` parameter.
1206
- *
1207
- * @param string $domain The new blog's domain.
1208
- * @param string $path The new blog's path.
1209
- * @param string $blog_title The new blog's title.
1210
- * @param string $user_name The user name of the user who created the blog. Unused.
1211
- * @param string $user_email The email of the user who created the blog. Unused.
1212
- * @param string|array $meta Meta values associated with the new blog. Unused.
1213
- * @param int|null $blog_id ID of the newly created blog.
1214
- */
1215
- function bp_blogs_confirm_blog_signup( $domain, $path, $blog_title, $user_name, $user_email = '', $meta = '', $blog_id = null ) {
1216
- switch_to_blog( $blog_id );
1217
- $blog_url = set_url_scheme( home_url() );
1218
- $login_url = set_url_scheme( wp_login_url() );
1219
- restore_current_blog();
1220
-
1221
- ?>
1222
- <p><?php _e( 'Congratulations! You have successfully registered a new site.', 'buddypress' ) ?></p>
1223
- <p>
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
- ),
1230
- sprintf(
1231
- /* translators: 1: Login URL, 2: User name */
1232
- __( '<a href="%1$s">Log in</a> as "%2$s" using your existing password.', 'buddypress' ),
1233
- esc_url( $login_url ),
1234
- esc_html( $user_name )
1235
- )
1236
- ); ?>
1237
- </p>
1238
-
1239
- <?php
1240
-
1241
- /**
1242
- * Fires after the default successful blog registration message markup.
1243
- *
1244
- * @since 1.0.0
1245
- */
1246
- do_action('signup_finished');
1247
- }
1248
-
1249
- /**
1250
- * Output a "Create a Site" link for users viewing their own profiles.
1251
- *
1252
- * This function is not used by BuddyPress as of 1.2, but is kept here for older
1253
- * themes that may still be using it.
1254
- */
1255
- function bp_create_blog_link() {
1256
-
1257
- // Don't show this link when not on your own profile.
1258
- if ( ! bp_is_my_profile() ) {
1259
- return;
1260
- }
1261
-
1262
- /**
1263
- * Filters "Create a Site" links for users viewing their own profiles.
1264
- *
1265
- * @since 1.0.0
1266
- *
1267
- * @param string $value HTML link for creating a site.
1268
- */
1269
- echo apply_filters( 'bp_create_blog_link', '<a href="' . trailingslashit( bp_get_blogs_directory_permalink() . 'create' ) . '">' . __( 'Create a Site', 'buddypress' ) . '</a>' );
1270
- }
1271
-
1272
- /**
1273
- * Output navigation tabs for a user Blogs page.
1274
- *
1275
- * Currently unused by BuddyPress.
1276
- */
1277
- function bp_blogs_blog_tabs() {
1278
-
1279
- // Don't show these tabs on a user's own profile.
1280
- if ( bp_is_my_profile() ) {
1281
- return false;
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
1291
-
1292
- /**
1293
- * Fires after the markup for the navigation tabs for a user Blogs page.
1294
- *
1295
- * @since 1.0.0
1296
- */
1297
- do_action( 'bp_blogs_blog_tabs' );
1298
- }
1299
-
1300
- /**
1301
- * Output the blog directory search form.
1302
- */
1303
- function bp_directory_blogs_search_form() {
1304
-
1305
- $query_arg = bp_core_get_component_search_query_arg( 'blogs' );
1306
-
1307
- if ( ! empty( $_REQUEST[ $query_arg ] ) ) {
1308
- $search_value = stripslashes( $_REQUEST[ $query_arg ] );
1309
- } else {
1310
- $search_value = bp_get_search_default_text( 'blogs' );
1311
- }
1312
-
1313
- $search_form_html = '<form action="" method="get" id="search-blogs-form">
1314
- <label for="blogs_search"><input type="text" name="' . esc_attr( $query_arg ) . '" id="blogs_search" placeholder="'. esc_attr( $search_value ) .'" /></label>
1315
- <input type="submit" id="blogs_search_submit" name="blogs_search_submit" value="' . __( 'Search', 'buddypress' ) . '" />
1316
- </form>';
1317
-
1318
- /**
1319
- * Filters the output for the blog directory search form.
1320
- *
1321
- * @since 1.9.0
1322
- *
1323
- * @param string $search_form_html HTML markup for blog directory search form.
1324
- */
1325
- echo apply_filters( 'bp_directory_blogs_search_form', $search_form_html );
1326
- }
1327
-
1328
- /**
1329
- * Output the Create a Site button.
1330
- *
1331
- * @since 2.0.0
1332
- */
1333
- function bp_blog_create_button() {
1334
- echo bp_get_blog_create_button();
1335
- }
1336
- /**
1337
- * Get the Create a Site button.
1338
- *
1339
- * @since 2.0.0
1340
- *
1341
- * @return false|string
1342
- */
1343
- function bp_get_blog_create_button() {
1344
- if ( ! is_user_logged_in() ) {
1345
- return false;
1346
- }
1347
-
1348
- if ( ! bp_blog_signup_enabled() ) {
1349
- return false;
1350
- }
1351
-
1352
- $button_args = array(
1353
- 'id' => 'create_blog',
1354
- 'component' => 'blogs',
1355
- 'link_text' => __( 'Create a Site', 'buddypress' ),
1356
- 'link_class' => 'blog-create no-ajax',
1357
- 'link_href' => trailingslashit( bp_get_blogs_directory_permalink() . 'create' ),
1358
- 'wrapper' => false,
1359
- 'block_self' => false,
1360
- );
1361
-
1362
- /**
1363
- * Filters the Create a Site button.
1364
- *
1365
- * @since 2.0.0
1366
- *
1367
- * @param array $button_args Array of arguments to be used for the Create a Site button.
1368
- */
1369
- return bp_get_button( apply_filters( 'bp_get_blog_create_button', $button_args ) );
1370
- }
1371
-
1372
- /**
1373
- * Output the Create a Site nav item.
1374
- *
1375
- * @since 2.2.0
1376
- */
1377
- function bp_blog_create_nav_item() {
1378
- echo bp_get_blog_create_nav_item();
1379
- }
1380
-
1381
- /**
1382
- * Get the Create a Site nav item.
1383
- *
1384
- * @since 2.2.0
1385
- *
1386
- * @return string
1387
- */
1388
- function bp_get_blog_create_nav_item() {
1389
- // Get the create a site button.
1390
- $create_blog_button = bp_get_blog_create_button();
1391
-
1392
- // Make sure the button is available.
1393
- if ( empty( $create_blog_button ) ) {
1394
- return;
1395
- }
1396
-
1397
- $output = '<li id="blog-create-nav">' . $create_blog_button . '</li>';
1398
-
1399
- /**
1400
- * Filters the Create A Site nav item output.
1401
- *
1402
- * @since 2.2.0
1403
- *
1404
- * @param string $output Nav item output.
1405
- */
1406
- return apply_filters( 'bp_get_blog_create_nav_item', $output );
1407
- }
1408
-
1409
- /**
1410
- * Checks if a specific theme is still filtering the Blogs directory title
1411
- * if so, transform the title button into a Blogs directory nav item.
1412
- *
1413
- * @since 2.2.0
1414
- *
1415
- * @return string|null HTML Output
1416
- */
1417
- function bp_blog_backcompat_create_nav_item() {
1418
- // Bail if Blogs nav item is already used by bp-legacy.
1419
- if ( has_action( 'bp_blogs_directory_blog_types', 'bp_legacy_theme_blog_create_nav', 999 ) ) {
1420
- return;
1421
- }
1422
-
1423
- // Bail if the theme is not filtering the Blogs directory title.
1424
- if ( ! has_filter( 'bp_blogs_directory_header' ) ) {
1425
- return;
1426
- }
1427
-
1428
- bp_blog_create_nav_item();
1429
- }
1430
- add_action( 'bp_blogs_directory_blog_types', 'bp_blog_backcompat_create_nav_item', 1000 );
1431
-
1432
- /**
1433
- * Output button for visiting a blog in a loop.
1434
- *
1435
- * @see bp_get_blogs_visit_blog_button() for description of arguments.
1436
- *
1437
- * @param array|string $args See {@link bp_get_blogs_visit_blog_button()}.
1438
- */
1439
- function bp_blogs_visit_blog_button( $args = '' ) {
1440
- echo bp_get_blogs_visit_blog_button( $args );
1441
- }
1442
- /**
1443
- * Return button for visiting a blog in a loop.
1444
- *
1445
- * @see BP_Button for a complete description of arguments and return
1446
- * value.
1447
- *
1448
- * @param array|string $args {
1449
- * Arguments are listed below, with their default values. For a
1450
- * complete description of arguments, see {@link BP_Button}.
1451
- * @type string $id Default: 'visit_blog'.
1452
- * @type string $component Default: 'blogs'.
1453
- * @type bool $must_be_logged_in Default: false.
1454
- * @type bool $block_self Default: false.
1455
- * @type string $wrapper_class Default: 'blog-button visit'.
1456
- * @type string $link_href Permalink of the current blog in the loop.
1457
- * @type string $link_class Default: 'blog-button visit'.
1458
- * @type string $link_text Default: 'Visit Site'.
1459
- * }
1460
- * @return string The HTML for the Visit button.
1461
- */
1462
- function bp_get_blogs_visit_blog_button( $args = '' ) {
1463
- $defaults = array(
1464
- 'id' => 'visit_blog',
1465
- 'component' => 'blogs',
1466
- 'must_be_logged_in' => false,
1467
- 'block_self' => false,
1468
- 'wrapper_class' => 'blog-button visit',
1469
- 'link_href' => bp_get_blog_permalink(),
1470
- 'link_class' => 'blog-button visit',
1471
- 'link_text' => __( 'Visit Site', 'buddypress' ),
1472
- );
1473
-
1474
- $button = wp_parse_args( $args, $defaults );
1475
-
1476
- /**
1477
- * Filters the button for visiting a blog in a loop.
1478
- *
1479
- * @since 1.2.10
1480
- *
1481
- * @param array $button Array of arguments to be used for the button to visit a blog.
1482
- */
1483
- return bp_get_button( apply_filters( 'bp_get_blogs_visit_blog_button', $button ) );
1484
- }
1485
-
1486
- /** Stats **********************************************************************/
1487
-
1488
- /**
1489
- * Display the number of blogs in user's profile.
1490
- *
1491
- * @since 2.0.0
1492
- *
1493
- * @param array|string $args Before|after|user_id.
1494
- */
1495
- function bp_blogs_profile_stats( $args = '' ) {
1496
- echo bp_blogs_get_profile_stats( $args );
1497
- }
1498
- add_action( 'bp_members_admin_user_stats', 'bp_blogs_profile_stats', 9, 1 );
1499
-
1500
- /**
1501
- * Return the number of blogs in user's profile.
1502
- *
1503
- * @since 2.0.0
1504
- *
1505
- * @param array|string $args Before|after|user_id.
1506
- * @return string HTML for stats output.
1507
- */
1508
- function bp_blogs_get_profile_stats( $args = '' ) {
1509
-
1510
- // Parse the args.
1511
- $r = bp_parse_args( $args, array(
1512
- 'before' => '<li class="bp-blogs-profile-stats">',
1513
- 'after' => '</li>',
1514
- 'user_id' => bp_displayed_user_id(),
1515
- 'blogs' => 0,
1516
- 'output' => ''
1517
- ), 'blogs_get_profile_stats' );
1518
-
1519
- // Allow completely overloaded output.
1520
- if ( is_multisite() && empty( $r['output'] ) ) {
1521
-
1522
- // Only proceed if a user ID was passed.
1523
- if ( ! empty( $r['user_id'] ) ) {
1524
-
1525
- // Get the user's blogs.
1526
- if ( empty( $r['blogs'] ) ) {
1527
- $r['blogs'] = absint( bp_blogs_total_blogs_for_user( $r['user_id'] ) );
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
-
1535
- /**
1536
- * Filters the number of blogs in user's profile.
1537
- *
1538
- * @since 2.0.0
1539
- *
1540
- * @param string $value Output determined for the profile stats.
1541
- * @param array $r Array of arguments used for default output if none provided.
1542
- */
1543
- return apply_filters( 'bp_blogs_get_profile_stats', $r['output'], $r );
1544
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-blogs/bp-blogs-templatetags.php ADDED
@@ -0,0 +1,544 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**********************************************************************
4
+ * Blog listing template class.
5
+ */
6
+
7
+ class BP_Blogs_Template {
8
+ var $current_blog = -1;
9
+ var $blog_count;
10
+ var $blogs;
11
+ var $blog;
12
+
13
+ var $in_the_loop;
14
+
15
+ var $pag_page;
16
+ var $pag_num;
17
+ var $pag_links;
18
+ var $total_blog_count;
19
+
20
+ function bp_blogs_template( $type, $page, $per_page, $max, $user_id, $search_terms ) {
21
+ global $bp;
22
+
23
+ $this->pag_page = isset( $_REQUEST['bpage'] ) ? intval( $_REQUEST['bpage'] ) : $page;
24
+ $this->pag_num = isset( $_REQUEST['num'] ) ? intval( $_REQUEST['num'] ) : $per_page;
25
+
26
+ if ( isset( $_REQUEST['letter'] ) && '' != $_REQUEST['letter'] )
27
+ $this->blogs = BP_Blogs_Blog::get_by_letter( $_REQUEST['letter'], $this->pag_num, $this->pag_page );
28
+ else
29
+ $this->blogs = bp_blogs_get_blogs( array( 'type' => $type, 'per_page' => $this->pag_num, 'page' => $this->pag_page, 'user_id' => $user_id, 'search_terms' => $search_terms ) );
30
+
31
+ if ( !$max || $max >= (int)$this->blogs['total'] )
32
+ $this->total_blog_count = (int)$this->blogs['total'];
33
+ else
34
+ $this->total_blog_count = (int)$max;
35
+
36
+ $this->blogs = $this->blogs['blogs'];
37
+
38
+ if ( $max ) {
39
+ if ( $max >= count($this->blogs) ) {
40
+ $this->blog_count = count( $this->blogs );
41
+ } else {
42
+ $this->blog_count = (int)$max;
43
+ }
44
+ } else {
45
+ $this->blog_count = count( $this->blogs );
46
+ }
47
+
48
+ if ( (int)$this->total_blog_count && (int)$this->pag_num ) {
49
+ $this->pag_links = paginate_links( array(
50
+ 'base' => add_query_arg( 'bpage', '%#%' ),
51
+ 'format' => '',
52
+ 'total' => ceil( (int)$this->total_blog_count / (int)$this->pag_num ),
53
+ 'current' => (int)$this->pag_page,
54
+ 'prev_text' => '&larr;',
55
+ 'next_text' => '&rarr;',
56
+ 'mid_size' => 1
57
+ ) );
58
+ }
59
+ }
60
+
61
+ function has_blogs() {
62
+ if ( $this->blog_count )
63
+ return true;
64
+
65
+ return false;
66
+ }
67
+
68
+ function next_blog() {
69
+ $this->current_blog++;
70
+ $this->blog = $this->blogs[$this->current_blog];
71
+
72
+ return $this->blog;
73
+ }
74
+
75
+ function rewind_blogs() {
76
+ $this->current_blog = -1;
77
+ if ( $this->blog_count > 0 ) {
78
+ $this->blog = $this->blogs[0];
79
+ }
80
+ }
81
+
82
+ function blogs() {
83
+ if ( $this->current_blog + 1 < $this->blog_count ) {
84
+ return true;
85
+ } elseif ( $this->current_blog + 1 == $this->blog_count ) {
86
+ do_action('loop_end');
87
+ // Do some cleaning up after the loop
88
+ $this->rewind_blogs();
89
+ }
90
+
91
+ $this->in_the_loop = false;
92
+ return false;
93
+ }
94
+
95
+ function the_blog() {
96
+ global $blog;
97
+
98
+ $this->in_the_loop = true;
99
+ $this->blog = $this->next_blog();
100
+
101
+ if ( 0 == $this->current_blog ) // loop has just started
102
+ do_action('loop_start');
103
+ }
104
+ }
105
+
106
+ function bp_rewind_blogs() {
107
+ global $blogs_template;
108
+
109
+ $blogs_template->rewind_blogs();
110
+ }
111
+
112
+ function bp_has_blogs( $args = '' ) {
113
+ global $bp, $blogs_template;
114
+
115
+ /***
116
+ * Set the defaults based on the current page. Any of these will be overridden
117
+ * if arguments are directly passed into the loop. Custom plugins should always
118
+ * pass their parameters directly to the loop.
119
+ */
120
+ $type = 'active';
121
+ $user_id = false;
122
+ $search_terms = false;
123
+
124
+ /* User filtering */
125
+ if ( !empty( $bp->displayed_user->id ) )
126
+ $user_id = $bp->displayed_user->id;
127
+
128
+ if ( !empty( $_REQUEST['s'] ) )
129
+ $search_terms = $_REQUEST['s'];
130
+
131
+ $defaults = array(
132
+ 'type' => $type,
133
+ 'page' => 1,
134
+ 'per_page' => 20,
135
+ 'max' => false,
136
+
137
+ 'user_id' => $user_id, // Pass a user_id to limit to only blogs this user has higher than subscriber access to
138
+ 'search_terms' => $search_terms // Pass search terms to filter on the blog title or description.
139
+ );
140
+
141
+ $r = wp_parse_args( $args, $defaults );
142
+ extract( $r );
143
+
144
+ if ( $max ) {
145
+ if ( $per_page > $max )
146
+ $per_page = $max;
147
+ }
148
+
149
+ $blogs_template = new BP_Blogs_Template( $type, $page, $per_page, $max, $user_id, $search_terms );
150
+ return apply_filters( 'bp_has_blogs', $blogs_template->has_blogs(), &$blogs_template );
151
+ }
152
+
153
+ function bp_blogs() {
154
+ global $blogs_template;
155
+
156
+ return $blogs_template->blogs();
157
+ }
158
+
159
+ function bp_the_blog() {
160
+ global $blogs_template;
161
+
162
+ return $blogs_template->the_blog();
163
+ }
164
+
165
+ function bp_blogs_pagination_count() {
166
+ global $bp, $blogs_template;
167
+
168
+ $start_num = intval( ( $blogs_template->pag_page - 1 ) * $blogs_template->pag_num ) + 1;
169
+ $from_num = bp_core_number_format( $start_num );
170
+ $to_num = bp_core_number_format( ( $start_num + ( $blogs_template->pag_num - 1 ) > $blogs_template->total_blog_count ) ? $blogs_template->total_blog_count : $start_num + ( $blogs_template->pag_num - 1 ) );
171
+ $total = bp_core_number_format( $blogs_template->total_blog_count );
172
+
173
+ echo sprintf( __( 'Viewing blog %1$s to %2$s (of %3$s blogs)', 'buddypress' ), $from_num, $to_num, $total ); ?> &nbsp;
174
+ <span class="ajax-loader"></span><?php
175
+ }
176
+
177
+ function bp_blogs_pagination_links() {
178
+ echo bp_get_blogs_pagination_links();
179
+ }
180
+ function bp_get_blogs_pagination_links() {
181
+ global $blogs_template;
182
+
183
+ return apply_filters( 'bp_get_blogs_pagination_links', $blogs_template->pag_links );
184
+ }
185
+
186
+ function bp_blog_avatar( $args = '' ) {
187
+ echo bp_get_blog_avatar( $args );
188
+ }
189
+ function bp_get_blog_avatar( $args = '' ) {
190
+ global $blogs_template, $bp;
191
+
192
+ $defaults = array(
193
+ 'type' => 'full',
194
+ 'width' => false,
195
+ 'height' => false,
196
+ 'class' => 'avatar',
197
+ 'id' => false,
198
+ 'alt' => __( 'Blog avatar', 'buddypress' ),
199
+ 'no_grav' => true
200
+ );
201
+
202
+ $r = wp_parse_args( $args, $defaults );
203
+ extract( $r, EXTR_SKIP );
204
+
205
+ /***
206
+ * In future BuddyPress versions you will be able to set the avatar for a blog.
207
+ * Right now you can use a filter with the ID of the blog to change it if you wish.
208
+ * By default it will return the avatar for the primary blog admin.
209
+ */
210
+ return apply_filters( 'bp_get_blog_avatar_' . $blogs_template->blog->blog_id, bp_core_fetch_avatar( array( 'item_id' => $blogs_template->blog->admin_user_id, 'type' => $type, 'alt' => $alt, 'width' => $width, 'height' => $height, 'class' => $class, 'email' => $blogs_template->blog->admin_user_email ) ) );
211
+ }
212
+
213
+ function bp_blog_permalink() {
214
+ echo bp_get_blog_permalink();
215
+ }
216
+ function bp_get_blog_permalink() {
217
+ global $blogs_template;
218
+
219
+ if ( empty( $blogs_template->blog->domain ) )
220
+ $permalink = $bp->root_domain . $blogs_template->blog->path;
221
+ else {
222
+ $protocol = 'http://';
223
+ if ( is_ssl() )
224
+ $protocol = 'https://';
225
+
226
+ $permalink = $protocol . $blogs_template->blog->domain . $blogs_template->blog->path;
227
+ }
228
+
229
+ return apply_filters( 'bp_get_blog_permalink', $permalink );
230
+ }
231
+
232
+ function bp_blog_name() {
233
+ echo bp_get_blog_name();
234
+ }
235
+ function bp_get_blog_name() {
236
+ global $blogs_template;
237
+
238
+ return apply_filters( 'bp_get_blog_name', $blogs_template->blog->name );
239
+ }
240
+
241
+ function bp_blog_description() {
242
+ echo apply_filters( 'bp_blog_description', bp_get_blog_description() );
243
+ }
244
+ function bp_get_blog_description() {
245
+ global $blogs_template;
246
+
247
+ return apply_filters( 'bp_get_blog_description', $blogs_template->blog->description );
248
+ }
249
+
250
+ function bp_blog_last_active() {
251
+ echo bp_get_blog_last_active();
252
+ }
253
+ function bp_get_blog_last_active() {
254
+ global $blogs_template;
255
+
256
+ return apply_filters( 'bp_blog_last_active', bp_core_get_last_activity( $blogs_template->blog->last_activity, __( 'active %s ago', 'buddypress' ) ) );
257
+ }
258
+
259
+ function bp_blog_latest_post() {
260
+ echo bp_get_blog_latest_post();
261
+ }
262
+ function bp_get_blog_latest_post() {
263
+ global $blogs_template;
264
+
265
+ if ( null == $blogs_template->blog->latest_post )
266
+ return false;
267
+
268
+ return apply_filters( 'bp_get_blog_latest_post', sprintf( __( 'Latest Post: %s', 'buddypress' ), '<a href="' . $blogs_template->blog->latest_post->guid . '">' . apply_filters( 'the_title', $blogs_template->blog->latest_post->post_title ) . '</a>' ) );
269
+ }
270
+
271
+ function bp_blog_hidden_fields() {
272
+ if ( isset( $_REQUEST['s'] ) ) {
273
+ echo '<input type="hidden" id="search_terms" value="' . esc_attr( $_REQUEST['s'] ). '" name="search_terms" />';
274
+ }
275
+
276
+ if ( isset( $_REQUEST['letter'] ) ) {
277
+ echo '<input type="hidden" id="selected_letter" value="' . esc_attr( $_REQUEST['letter'] ) . '" name="selected_letter" />';
278
+ }
279
+
280
+ if ( isset( $_REQUEST['blogs_search'] ) ) {
281
+ echo '<input type="hidden" id="search_terms" value="' . esc_attr( $_REQUEST['blogs_search'] ) . '" name="search_terms" />';
282
+ }
283
+ }
284
+
285
+ function bp_total_blog_count() {
286
+ echo bp_get_total_blog_count();
287
+ }
288
+ function bp_get_total_blog_count() {
289
+ return apply_filters( 'bp_get_total_blog_count', bp_blogs_total_blogs() );
290
+ }
291
+ add_filter( 'bp_get_total_blog_count', 'bp_core_number_format' );
292
+
293
+ function bp_total_blog_count_for_user( $user_id = false ) {
294
+ echo bp_get_total_blog_count_for_user( $user_id );
295
+ }
296
+ function bp_get_total_blog_count_for_user( $user_id = false ) {
297
+ return apply_filters( 'bp_get_total_blog_count_for_user', bp_blogs_total_blogs_for_user( $user_id ) );
298
+ }
299
+ add_filter( 'bp_get_total_blog_count_for_user', 'bp_core_number_format' );
300
+
301
+
302
+ /* Blog registration template tags */
303
+
304
+ function bp_blog_signup_enabled() {
305
+ global $bp;
306
+
307
+ $active_signup = $bp->site_options['registration'];
308
+
309
+ if ( !$active_signup )
310
+ $active_signup = 'all';
311
+
312
+ $active_signup = apply_filters( 'wpmu_active_signup', $active_signup ); // return "all", "none", "blog" or "user"
313
+
314
+ if ( 'none' == $active_signup || 'user' == $active_signup )
315
+ return false;
316
+
317
+ return true;
318
+ }
319
+
320
+ function bp_show_blog_signup_form($blogname = '', $blog_title = '', $errors = '') {
321
+ global $current_user, $current_site;
322
+ global $bp;
323
+
324
+ require_once( ABSPATH . WPINC . '/registration.php' );
325
+
326
+ if ( isset($_POST['submit']) ) {
327
+ bp_blogs_validate_blog_signup();
328
+ } else {
329
+ if ( ! is_wp_error($errors) ) {
330
+ $errors = new WP_Error();
331
+ }
332
+
333
+ // allow definition of default variables
334
+ $filtered_results = apply_filters('signup_another_blog_init', array('blogname' => $blogname, 'blog_title' => $blog_title, 'errors' => $errors ));
335
+ $blogname = $filtered_results['blogname'];
336
+ $blog_title = $filtered_results['blog_title'];
337
+ $errors = $filtered_results['errors'];
338
+
339
+ if ( $errors->get_error_code() ) {
340
+ echo "<p>" . __('There was a problem, please correct the form below and try again.', 'buddypress') . "</p>";
341
+ }
342
+ ?>
343
+ <p><?php printf(__("By filling out the form below, you can <strong>add a blog to your account</strong>. There is no limit to the number of blogs you can have, so create to your heart's content, but blog responsibly.", 'buddypress'), $current_user->display_name) ?></p>
344
+
345
+ <p><?php _e("If you&#8217;re not going to use a great blog domain, leave it for a new user. Now have at it!", 'buddypress') ?></p>
346
+
347
+ <form class="standard-form" id="setupform" method="post" action="">
348
+
349
+ <input type="hidden" name="stage" value="gimmeanotherblog" />
350
+ <?php do_action( 'signup_hidden_fields' ); ?>
351
+
352
+ <?php bp_blogs_signup_blog($blogname, $blog_title, $errors); ?>
353
+ <p>
354
+ <input id="submit" type="submit" name="submit" class="submit" value="<?php _e('Create Blog &rarr;', 'buddypress') ?>" />
355
+ </p>
356
+
357
+ <?php wp_nonce_field( 'bp_blog_signup_form' ) ?>
358
+ </form>
359
+ <?php
360
+ }
361
+ }
362
+
363
+ function bp_blogs_signup_blog( $blogname = '', $blog_title = '', $errors = '' ) {
364
+ global $current_site;
365
+
366
+ // Blog name
367
+ if( !is_subdomain_install() )
368
+ echo '<label for="blogname">' . __('Blog Name:', 'buddypress') . '</label>';
369
+ else
370
+ echo '<label for="blogname">' . __('Blog Domain:', 'buddypress') . '</label>';
371
+
372
+ if ( $errmsg = $errors->get_error_message('blogname') ) { ?>
373
+ <p class="error"><?php echo $errmsg ?></p>
374
+ <?php }
375
+
376
+ if ( !is_subdomain_install() )
377
+ echo '<span class="prefix_address">' . $current_site->domain . $current_site->path . '</span> <input name="blogname" type="text" id="blogname" value="'.$blogname.'" maxlength="50" /><br />';
378
+ else
379
+ echo '<input name="blogname" type="text" id="blogname" value="'.$blogname.'" maxlength="50" /> <span class="suffix_address">.' . $current_site->domain . $current_site->path . '</span><br />';
380
+
381
+ if ( !is_user_logged_in() ) {
382
+ print '(<strong>' . __( 'Your address will be ' , 'buddypress');
383
+
384
+ if ( !is_subdomain_install() ) {
385
+ print $current_site->domain . $current_site->path . __( 'blogname' , 'buddypress');
386
+ } else {
387
+ print __( 'domain.' , 'buddypress') . $current_site->domain . $current_site->path;
388
+ }
389
+
390
+ echo '.</strong> ' . __( 'Must be at least 4 characters, letters and numbers only. It cannot be changed so choose carefully!)' , 'buddypress') . '</p>';
391
+ }
392
+
393
+ // Blog Title
394
+ ?>
395
+ <label for="blog_title"><?php _e('Blog Title:', 'buddypress') ?></label>
396
+ <?php if ( $errmsg = $errors->get_error_message('blog_title') ) { ?>
397
+ <p class="error"><?php echo $errmsg ?></p>
398
+ <?php }
399
+ echo '<input name="blog_title" type="text" id="blog_title" value="'.wp_specialchars($blog_title, 1).'" /></p>';
400
+ ?>
401
+
402
+ <p>
403
+ <label for="blog_public_on"><?php _e('Privacy:', 'buddypress') ?></label>
404
+ <?php _e('I would like my blog to appear in search engines like Google and Technorati, and in public listings around this site.', 'buddypress'); ?>
405
+
406
+
407
+ <label class="checkbox" for="blog_public_on">
408
+ <input type="radio" id="blog_public_on" name="blog_public" value="1" <?php if( !isset( $_POST['blog_public'] ) || '1' == $_POST['blog_public'] ) { ?>checked="checked"<?php } ?> />
409
+ <strong><?php _e( 'Yes' , 'buddypress'); ?></strong>
410
+ </label>
411
+ <label class="checkbox" for="blog_public_off">
412
+ <input type="radio" id="blog_public_off" name="blog_public" value="0" <?php if( isset( $_POST['blog_public'] ) && '0' == $_POST['blog_public'] ) { ?>checked="checked"<?php } ?> />
413
+ <strong><?php _e( 'No' , 'buddypress'); ?></strong>
414
+ </label>
415
+ </p>
416
+
417
+ <?php
418
+ do_action('signup_blogform', $errors);
419
+ }
420
+
421
+ function bp_blogs_validate_blog_signup() {
422
+ global $wpdb, $current_user, $blogname, $blog_title, $errors, $domain, $path;
423
+
424
+ if ( !check_admin_referer( 'bp_blog_signup_form' ) )
425
+ return false;
426
+
427
+ $current_user = wp_get_current_user();
428
+
429
+ if( !is_user_logged_in() )
430
+ die();
431
+
432
+ $result = bp_blogs_validate_blog_form();
433
+ extract($result);
434
+
435
+ if ( $errors->get_error_code() ) {
436
+ unset($_POST['submit']);
437
+ bp_show_blog_signup_form( $blogname, $blog_title, $errors );
438
+ return false;
439
+ }
440
+
441
+ $public = (int) $_POST['blog_public'];
442
+
443
+ $meta = apply_filters( 'signup_create_blog_meta', array( 'lang_id' => 1, 'public' => $public ) ); // depreciated
444
+ $meta = apply_filters( 'add_signup_meta', $meta );
445
+
446
+ /* If this is a VHOST install, remove the username from the domain as we are setting this blog
447
+ up inside a user domain, not the root domain. */
448
+
449
+ wpmu_create_blog( $domain, $path, $blog_title, $current_user->id, $meta, $wpdb->siteid );
450
+ bp_blogs_confirm_blog_signup($domain, $path, $blog_title, $current_user->user_login, $current_user->user_email, $meta);
451
+ return true;
452
+ }
453
+
454
+ function bp_blogs_validate_blog_form() {
455
+ $user = '';
456
+ if ( is_user_logged_in() )
457
+ $user = wp_get_current_user();
458
+
459
+ return wpmu_validate_blog_signup($_POST['blogname'], $_POST['blog_title'], $user);
460
+ }
461
+
462
+ function bp_blogs_confirm_blog_signup( $domain, $path, $blog_title, $user_name, $user_email = '', $meta = '' ) {
463
+ ?>
464
+ <p><?php _e('Congratulations! You have successfully registered a new blog.', 'buddypress') ?></p>
465
+ <p>
466
+ <?php printf(__('<a href="http://%1$s">http://%2$s</a> is your new blog. <a href="%3$s">Login</a> as "%4$s" using your existing password.', 'buddypress'), $domain.$path, $domain.$path, "http://" . $domain.$path . "wp-login.php", $user_name) ?>
467
+ </p>
468
+ <?php
469
+ do_action('signup_finished');
470
+ }
471
+
472
+ function bp_create_blog_link() {
473
+ global $bp;
474
+
475
+ if ( bp_is_my_profile() ) {
476
+ echo apply_filters( 'bp_create_blog_link', '<a href="' . $bp->root_domain . '/' . $bp->blogs->slug . '/create">' . __('Create a Blog', 'buddypress') . '</a>' );
477
+ }
478
+ }
479
+
480
+ function bp_blogs_blog_tabs() {
481
+ global $bp, $groups_template;
482
+
483
+ // Don't show these tabs on a user's own profile
484
+ if ( bp_is_my_profile() )
485
+ return false;
486
+
487
+ $current_tab = $bp->current_action
488
+ ?>
489
+ <ul class="content-header-nav">
490
+ <li<?php if ( 'my-blogs' == $current_tab || empty( $current_tab ) ) : ?> class="current"<?php endif; ?>><a href="<?php echo $bp->displayed_user->domain . $bp->blogs->slug ?>/my-blogs"><?php printf( __( "%s's Blogs", 'buddypress' ), $bp->displayed_user->fullname ) ?></a></li>
491
+ <li<?php if ( 'recent-posts' == $current_tab ) : ?> class="current"<?php endif; ?>><a href="<?php echo $bp->displayed_user->domain . $bp->blogs->slug ?>/recent-posts"><?php printf( __( "%s's Recent Posts", 'buddypress' ), $bp->displayed_user->fullname ) ?></a></li>
492
+ <li<?php if ( 'recent-comments' == $current_tab ) : ?> class="current"<?php endif; ?>><a href="<?php echo $bp->displayed_user->domain . $bp->blogs->slug ?>/recent-comments"><?php printf( __( "%s's Recent Comments", 'buddypress' ), $bp->displayed_user->fullname ) ?></a></li>
493
+ </ul>
494
+ <?php
495
+ do_action( 'bp_blogs_blog_tabs', $current_tab );
496
+ }
497
+
498
+ function bp_directory_blogs_search_form() {
499
+ global $bp; ?>
500
+ <form action="" method="get" id="search-blogs-form">
501
+ <label><input type="text" name="s" id="blogs_search" value="<?php if ( isset( $_GET['s'] ) ) { echo $_GET['s']; } else { _e( 'Search anything...', 'buddypress' ); } ?>" onfocus="if (this.value == '<?php _e( 'Search anything...', 'buddypress' ) ?>') {this.value = '';}" onblur="if (this.value == '') {this.value = '<?php _e( 'Search anything...', 'buddypress' ) ?>';}" /></label>
502
+ <input type="submit" id="blogs_search_submit" name="blogs_search_submit" value="<?php _e( 'Search', 'buddypress' ) ?>" />
503
+ </form>
504
+ <?php
505
+ }
506
+
507
+ /**
508
+ * bp_blogs_visit_blog_button()
509
+ *
510
+ * Output button for visiting a blog in a loop
511
+ *
512
+ * @param array $args Custom button properties
513
+ */
514
+ function bp_blogs_visit_blog_button( $args = '' ) {
515
+ echo bp_get_blogs_visit_blog_button( $args );
516
+ }
517
+ /**
518
+ * bp_get_blogs_visit_blog_button()
519
+ *
520
+ * Return button for visiting a blog in a loop
521
+ *
522
+ * @param array $args Custom button properties
523
+ * @return string
524
+ */
525
+ function bp_get_blogs_visit_blog_button( $args = '' ) {
526
+ $defaults = array(
527
+ 'id' => 'visit_blog',
528
+ 'component' => 'blogs',
529
+ 'must_be_logged_in' => false,
530
+ 'block_self' => false,
531
+ 'wrapper_class' => 'blog-button visit',
532
+ 'link_href' => bp_get_blog_permalink(),
533
+ 'link_class' => 'visit',
534
+ 'link_text' => __( 'Visit Blog', 'buddypress' ),
535
+ 'link_title' => __( 'Visit Blog', 'buddypress' ),
536
+ );
537
+
538
+ $button = wp_parse_args( $args, $defaults );
539
+
540
+ // Filter and return the HTML button
541
+ return bp_get_button( apply_filters( 'bp_get_blogs_visit_blog_button', $button ) );
542
+ }
543
+
544
+ ?>
bp-blogs/bp-blogs-widgets.php CHANGED
@@ -1,23 +1,84 @@
1
  <?php
2
- /**
3
- * BuddyPress Blogs Widgets.
4
- *
5
- * @package BuddyPress
6
- * @subpackage BlogsWidgets
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
 
13
- /**
14
- * Register the widgets for the Blogs component.
 
15
  */
 
16
  function bp_blogs_register_widgets() {
17
- global $wpdb;
18
 
19
- if ( bp_is_active( 'activity' ) && bp_is_root_blog( $wpdb->blogid ) ) {
20
- add_action( 'widgets_init', function() { register_widget( 'BP_Blogs_Recent_Posts_Widget' ); } );
21
- }
22
  }
23
  add_action( 'bp_register_widgets', 'bp_blogs_register_widgets' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
 
 
 
 
 
 
 
 
 
 
2
 
3
+ /***
4
+ * The recent blogs widget is actually just the activity feed filtered on "new_blog_post".
5
+ * Why not make some of your own widgets using a filtered activity stream?
6
  */
7
+
8
  function bp_blogs_register_widgets() {
9
+ global $current_blog, $bp;
10
 
11
+ if ( bp_is_active( 'activity' ) && (int)$current_blog->blog_id == BP_ROOT_BLOG )
12
+ add_action('widgets_init', create_function('', 'return register_widget("BP_Blogs_Recent_Posts_Widget");') );
 
13
  }
14
  add_action( 'bp_register_widgets', 'bp_blogs_register_widgets' );
15
+
16
+ class BP_Blogs_Recent_Posts_Widget extends WP_Widget {
17
+ function bp_blogs_recent_posts_widget() {
18
+ parent::WP_Widget( false, $name = __( 'Recent Site Wide Posts', 'buddypress' ) );
19
+ }
20
+
21
+ function widget($args, $instance) {
22
+ global $bp;
23
+
24
+ extract( $args );
25
+
26
+ echo $before_widget;
27
+ echo $before_title . $widget_name . $after_title;
28
+
29
+ if ( empty( $instance['max_posts'] ) || !$instance['max_posts'] )
30
+ $instance['max_posts'] = 10; ?>
31
+
32
+ <?php if ( bp_has_activities( 'action=new_blog_post&max=' . $instance['max_posts'] . '&per_page=' . $instance['max_posts'] ) ) : ?>
33
+
34
+ <ul id="blog-post-list" class="activity-list item-list">
35
+
36
+ <?php while ( bp_activities() ) : bp_the_activity(); ?>
37
+
38
+ <li>
39
+ <div class="activity-content" style="margin: 0">
40
+
41
+ <div class="activity-header">
42
+ <?php bp_activity_action() ?>
43
+ </div>
44
+
45
+ <?php if ( bp_get_activity_content_body() ) : ?>
46
+ <div class="activity-inner">
47
+ <?php bp_activity_content_body() ?>
48
+ </div>
49
+ <?php endif; ?>
50
+
51
+ </div>
52
+ </li>
53
+
54
+ <?php endwhile; ?>
55
+
56
+ </ul>
57
+
58
+ <?php else : ?>
59
+ <div id="message" class="info">
60
+ <p><?php _e( 'Sorry, there were no blog posts found. Why not write one?', 'buddypress' ) ?></p>
61
+ </div>
62
+ <?php endif; ?>
63
+
64
+ <?php echo $after_widget; ?>
65
+ <?php
66
+ }
67
+
68
+ function update( $new_instance, $old_instance ) {
69
+ $instance = $old_instance;
70
+ $instance['max_posts'] = strip_tags( $new_instance['max_posts'] );
71
+
72
+ return $instance;
73
+ }
74
+
75
+ function form( $instance ) {
76
+ $instance = wp_parse_args( (array) $instance, array( 'max_posts' => 10 ) );
77
+ $max_posts = strip_tags( $instance['max_posts'] );
78
+ ?>
79
+
80
+ <p><label for="bp-blogs-widget-posts-max"><?php _e('Max posts to show:', 'buddypress'); ?> <input class="widefat" id="<?php echo $this->get_field_id( 'max_posts' ); ?>" name="<?php echo $this->get_field_name( 'max_posts' ); ?>" type="text" value="<?php echo esc_attr( $max_posts ); ?>" style="width: 30%" /></label></p>
81
+ <?php
82
+ }
83
+ }
84
+ ?>
bp-blogs/classes/class-bp-blogs-blog.php DELETED
@@ -1,665 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Blogs Classes.
4
- *
5
- * @package BuddyPress
6
- * @subpackage BlogsClasses
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * The main BuddyPress blog class.
15
- *
16
- * A BP_Blogs_Object represents a link between a specific WordPress blog on a
17
- * network and a specific user on that blog.
18
- *
19
- * @since 1.0.0
20
- */
21
- class BP_Blogs_Blog {
22
-
23
- /**
24
- * Site ID.
25
- *
26
- * @var int|null
27
- */
28
- public $id;
29
-
30
- /**
31
- * User ID.
32
- *
33
- * @var int
34
- */
35
- public $user_id;
36
-
37
- /**
38
- * Blog ID.
39
- *
40
- * @var int
41
- */
42
- public $blog_id;
43
-
44
- /**
45
- * Constructor method.
46
- *
47
- * @param int|null $id Optional. The ID of the blog.
48
- */
49
- public function __construct( $id = null ) {
50
- if ( !empty( $id ) ) {
51
- $this->id = (int) $id;
52
- $this->populate();
53
- }
54
- }
55
-
56
- /**
57
- * Populate the object with data about the specific activity item.
58
- */
59
- public function populate() {
60
- global $wpdb;
61
-
62
- $bp = buddypress();
63
-
64
- $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->blogs->table_name} WHERE id = %d", $this->id ) );
65
-
66
- $this->user_id = (int) $blog->user_id;
67
- $this->blog_id = (int) $blog->blog_id;
68
- }
69
-
70
- /**
71
- * Save the BP blog data to the database.
72
- *
73
- * @return bool True on success, false on failure.
74
- */
75
- public function save() {
76
- global $wpdb;
77
-
78
- /**
79
- * Filters the blog user ID before save.
80
- *
81
- * @since 1.0.0
82
- *
83
- * @param int $value User ID.
84
- * @param int $value Site ID.
85
- */
86
- $this->user_id = apply_filters( 'bp_blogs_blog_user_id_before_save', $this->user_id, $this->id );
87
-
88
- /**
89
- * Filters the blog blog ID before save.
90
- *
91
- * @since 1.0.0
92
- *
93
- * @param int $value Blog ID.
94
- * @param int $value Site ID.
95
- */
96
- $this->blog_id = apply_filters( 'bp_blogs_blog_id_before_save', $this->blog_id, $this->id );
97
-
98
- /**
99
- * Fires before the current blog item gets saved.
100
- *
101
- * Please use this hook to filter the properties above. Each part will be passed in.
102
- *
103
- * @since 1.0.0
104
- *
105
- * @param BP_Blogs_Blog $this Current instance of the blog item being saved. Passed by reference.
106
- */
107
- do_action_ref_array( 'bp_blogs_blog_before_save', array( &$this ) );
108
-
109
- // Don't try and save if there is no user ID or blog ID set.
110
- if ( !$this->user_id || !$this->blog_id )
111
- return false;
112
-
113
- // Don't save if this blog has already been recorded for the user.
114
- if ( !$this->id && $this->exists() )
115
- return false;
116
-
117
- $bp = buddypress();
118
-
119
- if ( $this->id ) {
120
- // Update.
121
- $sql = $wpdb->prepare( "UPDATE {$bp->blogs->table_name} SET user_id = %d, blog_id = %d WHERE id = %d", $this->user_id, $this->blog_id, $this->id );
122
- } else {
123
- // Save.
124
- $sql = $wpdb->prepare( "INSERT INTO {$bp->blogs->table_name} ( user_id, blog_id ) VALUES ( %d, %d )", $this->user_id, $this->blog_id );
125
- }
126
-
127
- if ( !$wpdb->query($sql) )
128
- return false;
129
-
130
- /**
131
- * Fires after the current blog item gets saved.
132
- *
133
- * Please use this hook to filter the properties above. Each part will be passed in.
134
- *
135
- * @since 1.0.0
136
- *
137
- * @param BP_Blogs_Blog $this Current instance of the blog item being saved. Passed by reference.
138
- */
139
- do_action_ref_array( 'bp_blogs_blog_after_save', array( &$this ) );
140
-
141
- if ( $this->id )
142
- return $this->id;
143
- else
144
- return $wpdb->insert_id;
145
- }
146
-
147
- /**
148
- * Check whether an association between this user and this blog exists.
149
- *
150
- * @return int $value The number of associations between the user and blog
151
- * saved in the blog component tables.
152
- */
153
- public function exists() {
154
- global $wpdb;
155
-
156
- $bp = buddypress();
157
-
158
- return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->blogs->table_name} WHERE user_id = %d AND blog_id = %d", $this->user_id, $this->blog_id ) );
159
- }
160
-
161
- /** Static Methods ***************************************************/
162
-
163
- /**
164
- * Retrieve a set of blog-user associations.
165
- *
166
- * @param string $type The order in which results should be returned.
167
- * 'active', 'alphabetical', 'newest', or 'random'.
168
- * @param int|bool $limit Optional. The maximum records to return.
169
- * Default: false.
170
- * @param int|bool $page Optional. The page of records to return.
171
- * Default: false (unlimited results).
172
- * @param int $user_id Optional. ID of the user whose blogs are being
173
- * retrieved. Default: 0.
174
- * @param string|bool $search_terms Optional. Search by text stored in
175
- * blogmeta (such as the blog name). Default: false.
176
- * @param bool $update_meta_cache Whether to pre-fetch metadata for
177
- * blogs. Default: true.
178
- * @param array|bool $include_blog_ids Array of blog IDs to include.
179
- * @return array Multidimensional results array, structured as follows:
180
- * 'blogs' - Array of located blog objects
181
- * 'total' - A count of the total blogs matching the filter params
182
- */
183
- public static function get( $type, $limit = false, $page = false, $user_id = 0, $search_terms = false, $update_meta_cache = true, $include_blog_ids = false ) {
184
- global $wpdb;
185
-
186
- $bp = buddypress();
187
-
188
- if ( !is_user_logged_in() || ( !bp_current_user_can( 'bp_moderate' ) && ( $user_id != bp_loggedin_user_id() ) ) )
189
- $hidden_sql = "AND wb.public = 1";
190
- else
191
- $hidden_sql = '';
192
-
193
- $pag_sql = ( $limit && $page ) ? $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) ) : '';
194
-
195
- $user_sql = !empty( $user_id ) ? $wpdb->prepare( " AND b.user_id = %d", $user_id ) : '';
196
-
197
- switch ( $type ) {
198
- case 'active': default:
199
- $order_sql = "ORDER BY bm.meta_value DESC";
200
- break;
201
- case 'alphabetical':
202
- $order_sql = "ORDER BY bm_name.meta_value ASC";
203
- break;
204
- case 'newest':
205
- $order_sql = "ORDER BY wb.registered DESC";
206
- break;
207
- case 'random':
208
- $order_sql = "ORDER BY RAND()";
209
- break;
210
- }
211
-
212
- $include_sql = '';
213
- $include_blog_ids = array_filter( wp_parse_id_list( $include_blog_ids ) );
214
- if ( ! empty( $include_blog_ids ) ) {
215
- $blog_ids_sql = implode( ',', $include_blog_ids );
216
- $include_sql = " AND b.blog_id IN ({$blog_ids_sql})";
217
- }
218
-
219
- if ( ! empty( $search_terms ) ) {
220
- $search_terms_like = '%' . bp_esc_like( $search_terms ) . '%';
221
- $search_terms_sql = $wpdb->prepare( 'AND (bm_name.meta_value LIKE %s OR bm_description.meta_value LIKE %s)', $search_terms_like, $search_terms_like );
222
- } else {
223
- $search_terms_sql = '';
224
- }
225
-
226
- $paged_blogs = $wpdb->get_results( "
227
- SELECT b.blog_id, b.user_id as admin_user_id, u.user_email as admin_user_email, wb.domain, wb.path, bm.meta_value as last_activity, bm_name.meta_value as name
228
- FROM
229
- {$bp->blogs->table_name} b
230
- LEFT JOIN {$bp->blogs->table_name_blogmeta} bm ON (b.blog_id = bm.blog_id)
231
- LEFT JOIN {$bp->blogs->table_name_blogmeta} bm_name ON (b.blog_id = bm_name.blog_id)
232
- LEFT JOIN {$bp->blogs->table_name_blogmeta} bm_description ON (b.blog_id = bm_description.blog_id)
233
- LEFT JOIN {$wpdb->base_prefix}blogs wb ON (b.blog_id = wb.blog_id)
234
- LEFT JOIN {$wpdb->users} u ON (b.user_id = u.ID)
235
- WHERE
236
- wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$hidden_sql}
237
- AND bm.meta_key = 'last_activity' AND bm_name.meta_key = 'name' AND bm_description.meta_key = 'description'
238
- {$search_terms_sql} {$user_sql} {$include_sql}
239
- GROUP BY b.blog_id {$order_sql} {$pag_sql}
240
- " );
241
-
242
- $total_blogs = $wpdb->get_var( "
243
- SELECT COUNT(DISTINCT b.blog_id)
244
- FROM
245
- {$bp->blogs->table_name} b
246
- LEFT JOIN {$wpdb->base_prefix}blogs wb ON (b.blog_id = wb.blog_id)
247
- LEFT JOIN {$bp->blogs->table_name_blogmeta} bm_name ON (b.blog_id = bm_name.blog_id)
248
- LEFT JOIN {$bp->blogs->table_name_blogmeta} bm_description ON (b.blog_id = bm_description.blog_id)
249
- WHERE
250
- wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$hidden_sql}
251
- AND
252
- bm_name.meta_key = 'name' AND bm_description.meta_key = 'description'
253
- {$search_terms_sql} {$user_sql} {$include_sql}
254
- " );
255
-
256
- $blog_ids = array();
257
- foreach ( (array) $paged_blogs as $blog ) {
258
- $blog_ids[] = (int) $blog->blog_id;
259
- }
260
-
261
- $paged_blogs = BP_Blogs_Blog::get_blog_extras( $paged_blogs, $blog_ids, $type );
262
-
263
- // Integer casting.
264
- foreach ( (array) $paged_blogs as $key => $data ) {
265
- $paged_blogs[ $key ]->blog_id = (int) $paged_blogs[ $key ]->blog_id;
266
- $paged_blogs[ $key ]->admin_user_id = (int) $paged_blogs[ $key ]->admin_user_id;
267
- }
268
-
269
- if ( $update_meta_cache ) {
270
- bp_blogs_update_meta_cache( $blog_ids );
271
- }
272
-
273
- return array( 'blogs' => $paged_blogs, 'total' => $total_blogs );
274
- }
275
-
276
- /**
277
- * Delete the record of a given blog for all users.
278
- *
279
- * @param int $blog_id The blog being removed from all users.
280
- * @return int|bool Number of rows deleted on success, false on failure.
281
- */
282
- public static function delete_blog_for_all( $blog_id ) {
283
- global $wpdb;
284
-
285
- bp_blogs_delete_blogmeta( $blog_id );
286
-
287
- $bp = buddypress();
288
-
289
- return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name} WHERE blog_id = %d", $blog_id ) );
290
- }
291
-
292
- /**
293
- * Delete the record of a given blog for a specific user.
294
- *
295
- * @param int $blog_id The blog being removed.
296
- * @param int|null $user_id Optional. The ID of the user from whom the blog is
297
- * being removed. If absent, defaults to the logged-in user ID.
298
- * @return int|bool Number of rows deleted on success, false on failure.
299
- */
300
- public static function delete_blog_for_user( $blog_id, $user_id = null ) {
301
- global $wpdb;
302
-
303
- if ( !$user_id )
304
- $user_id = bp_loggedin_user_id();
305
-
306
- $bp = buddypress();
307
-
308
- return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name} WHERE user_id = %d AND blog_id = %d", $user_id, $blog_id ) );
309
- }
310
-
311
- /**
312
- * Delete all of a user's blog associations in the BP tables.
313
- *
314
- * @param int|null $user_id Optional. The ID of the user whose blog associations
315
- * are being deleted. If absent, defaults to logged-in user ID.
316
- * @return int|bool Number of rows deleted on success, false on failure.
317
- */
318
- public static function delete_blogs_for_user( $user_id = null ) {
319
- global $wpdb;
320
-
321
- if ( !$user_id )
322
- $user_id = bp_loggedin_user_id();
323
-
324
- $bp = buddypress();
325
-
326
- return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name} WHERE user_id = %d", $user_id ) );
327
- }
328
-
329
- /**
330
- * Get all of a user's blogs, as tracked by BuddyPress.
331
- *
332
- * Note that this is different from the WordPress function
333
- * {@link get_blogs_of_user()}; the current method returns only those
334
- * blogs that have been recorded by BuddyPress, while the WP function
335
- * does a true query of a user's blog capabilities.
336
- *
337
- * @param int $user_id Optional. ID of the user whose blogs are being
338
- * queried. Defaults to logged-in user.
339
- * @param bool $show_hidden Optional. Whether to include blogs that are not marked
340
- * public. Defaults to true when viewing one's own profile.
341
- * @return array Multidimensional results array, structured as follows:
342
- * 'blogs' - Array of located blog objects.
343
- * 'total' - A count of the total blogs for the user.
344
- */
345
- public static function get_blogs_for_user( $user_id = 0, $show_hidden = false ) {
346
- global $wpdb;
347
-
348
- $bp = buddypress();
349
-
350
- if ( !$user_id )
351
- $user_id = bp_displayed_user_id();
352
-
353
- // Show logged in users their hidden blogs.
354
- if ( !bp_is_my_profile() && !$show_hidden )
355
- $blogs = $wpdb->get_results( $wpdb->prepare( "SELECT DISTINCT b.blog_id, b.id, bm1.meta_value as name, wb.domain, wb.path FROM {$bp->blogs->table_name} b, {$wpdb->base_prefix}blogs wb, {$bp->blogs->table_name_blogmeta} bm1 WHERE b.blog_id = wb.blog_id AND b.blog_id = bm1.blog_id AND bm1.meta_key = 'name' AND wb.public = 1 AND wb.deleted = 0 AND wb.spam = 0 AND wb.mature = 0 AND wb.archived = '0' AND b.user_id = %d ORDER BY b.blog_id", $user_id ) );
356
- else
357
- $blogs = $wpdb->get_results( $wpdb->prepare( "SELECT DISTINCT b.blog_id, b.id, bm1.meta_value as name, wb.domain, wb.path FROM {$bp->blogs->table_name} b, {$wpdb->base_prefix}blogs wb, {$bp->blogs->table_name_blogmeta} bm1 WHERE b.blog_id = wb.blog_id AND b.blog_id = bm1.blog_id AND bm1.meta_key = 'name' AND wb.deleted = 0 AND wb.spam = 0 AND wb.mature = 0 AND wb.archived = '0' AND b.user_id = %d ORDER BY b.blog_id", $user_id ) );
358
-
359
- $total_blog_count = BP_Blogs_Blog::total_blog_count_for_user( $user_id );
360
-
361
- $user_blogs = array();
362
- foreach ( (array) $blogs as $blog ) {
363
- $user_blogs[$blog->blog_id] = new stdClass;
364
- $user_blogs[$blog->blog_id]->id = (int) $blog->id;
365
- $user_blogs[$blog->blog_id]->blog_id = (int) $blog->blog_id;
366
- $user_blogs[$blog->blog_id]->siteurl = ( is_ssl() ) ? 'https://' . $blog->domain . $blog->path : 'http://' . $blog->domain . $blog->path;
367
- $user_blogs[$blog->blog_id]->name = $blog->name;
368
- }
369
-
370
- return array( 'blogs' => $user_blogs, 'count' => $total_blog_count );
371
- }
372
-
373
- /**
374
- * Get IDs of all of a user's blogs, as tracked by BuddyPress.
375
- *
376
- * This method always includes hidden blogs.
377
- *
378
- * @param int $user_id Optional. ID of the user whose blogs are being
379
- * queried. Defaults to logged-in user.
380
- * @return int The number of blogs associated with the user.
381
- */
382
- public static function get_blog_ids_for_user( $user_id = 0 ) {
383
- global $wpdb;
384
-
385
- $bp = buddypress();
386
-
387
- if ( !$user_id )
388
- $user_id = bp_displayed_user_id();
389
-
390
- return array_map( 'intval', $wpdb->get_col( $wpdb->prepare( "SELECT blog_id FROM {$bp->blogs->table_name} WHERE user_id = %d", $user_id ) ) );
391
- }
392
-
393
- /**
394
- * Check whether a blog has been recorded by BuddyPress.
395
- *
396
- * @param int $blog_id ID of the blog being queried.
397
- * @return int|null The ID of the first located entry in the BP table
398
- * on success, otherwise null.
399
- */
400
- public static function is_recorded( $blog_id ) {
401
- global $wpdb;
402
-
403
- $bp = buddypress();
404
-
405
- $query = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->blogs->table_name} WHERE blog_id = %d", $blog_id ) );
406
-
407
- return is_numeric( $query ) ? (int) $query : $query;
408
- }
409
-
410
- /**
411
- * Return a count of associated blogs for a given user.
412
- *
413
- * Includes hidden blogs when the logged-in user is the same as the
414
- * $user_id parameter, or when the logged-in user has the bp_moderate
415
- * cap.
416
- *
417
- * @param int|null $user_id Optional. ID of the user whose blogs are being
418
- * queried. Defaults to logged-in user.
419
- * @return int Blog count for the user.
420
- */
421
- public static function total_blog_count_for_user( $user_id = null ) {
422
- global $wpdb;
423
-
424
- $bp = buddypress();
425
-
426
- if ( !$user_id )
427
- $user_id = bp_displayed_user_id();
428
-
429
- // If the user is logged in return the blog count including their hidden blogs.
430
- if ( ( is_user_logged_in() && $user_id == bp_loggedin_user_id() ) || bp_current_user_can( 'bp_moderate' ) ) {
431
- return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT b.blog_id) FROM {$bp->blogs->table_name} b LEFT JOIN {$wpdb->base_prefix}blogs wb ON b.blog_id = wb.blog_id WHERE wb.deleted = 0 AND wb.spam = 0 AND wb.mature = 0 AND wb.archived = '0' AND user_id = %d", $user_id ) );
432
- } else {
433
- return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT b.blog_id) FROM {$bp->blogs->table_name} b LEFT JOIN {$wpdb->base_prefix}blogs wb ON b.blog_id = wb.blog_id WHERE wb.public = 1 AND wb.deleted = 0 AND wb.spam = 0 AND wb.mature = 0 AND wb.archived = '0' AND user_id = %d", $user_id ) );
434
- }
435
- }
436
-
437
- /**
438
- * Return a list of blogs matching a search term.
439
- *
440
- * Matches against blog names and descriptions, as stored in the BP
441
- * blogmeta table.
442
- *
443
- * @param string $filter The search term.
444
- * @param int|null $limit Optional. The maximum number of items to return.
445
- * Default: null (no limit).
446
- * @param int|null $page Optional. The page of results to return. Default:
447
- * null (no limit).
448
- * @return array Multidimensional results array, structured as follows:
449
- * 'blogs' - Array of located blog objects.
450
- * 'total' - A count of the total blogs matching the query.
451
- */
452
- public static function search_blogs( $filter, $limit = null, $page = null ) {
453
- global $wpdb;
454
-
455
- $search_terms_like = '%' . bp_esc_like( $filter ) . '%';
456
- $search_terms_sql = $wpdb->prepare( 'bm.meta_value LIKE %s', $search_terms_like );
457
-
458
- $hidden_sql = '';
459
- if ( !bp_current_user_can( 'bp_moderate' ) )
460
- $hidden_sql = "AND wb.public = 1";
461
-
462
- $pag_sql = '';
463
- if ( $limit && $page ) {
464
- $pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
465
- }
466
-
467
- $bp = buddypress();
468
-
469
- $paged_blogs = $wpdb->get_results( "SELECT DISTINCT bm.blog_id FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE ( ( bm.meta_key = 'name' OR bm.meta_key = 'description' ) AND {$search_terms_sql} ) {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY meta_value ASC{$pag_sql}" );
470
- $total_blogs = $wpdb->get_var( "SELECT COUNT(DISTINCT bm.blog_id) FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE ( ( bm.meta_key = 'name' OR bm.meta_key = 'description' ) AND {$search_terms_sql} ) {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY meta_value ASC" );
471
-
472
- // Integer casting.
473
- foreach ( (array) $paged_blogs as $key => $data ) {
474
- $paged_blogs[ $key ]->blog_id = (int) $paged_blogs[ $key ]->blog_id;
475
- }
476
-
477
- return array( 'blogs' => $paged_blogs, 'total' => (int) $total_blogs );
478
- }
479
-
480
- /**
481
- * Retrieve a list of all blogs.
482
- *
483
- * Query will include hidden blogs if the logged-in user has the
484
- * 'bp_moderate' cap.
485
- *
486
- * @param int|null $limit Optional. The maximum number of items to return.
487
- * Default: null (no limit).
488
- * @param int|null $page Optional. The page of results to return. Default:
489
- * null (no limit).
490
- * @return array Multidimensional results array, structured as follows:
491
- * 'blogs' - Array of located blog objects.
492
- * 'total' - A count of the total blogs.
493
- */
494
- public static function get_all( $limit = null, $page = null ) {
495
- global $wpdb;
496
-
497
- $bp = buddypress();
498
-
499
- $hidden_sql = !bp_current_user_can( 'bp_moderate' ) ? "AND wb.public = 1" : '';
500
- $pag_sql = ( $limit && $page ) ? $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) ) : '';
501
-
502
- $paged_blogs = $wpdb->get_results( "SELECT DISTINCT b.blog_id FROM {$bp->blogs->table_name} b LEFT JOIN {$wpdb->base_prefix}blogs wb ON b.blog_id = wb.blog_id WHERE wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 {$hidden_sql} {$pag_sql}" );
503
- $total_blogs = $wpdb->get_var( "SELECT COUNT(DISTINCT b.blog_id) FROM {$bp->blogs->table_name} b LEFT JOIN {$wpdb->base_prefix}blogs wb ON b.blog_id = wb.blog_id WHERE wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 {$hidden_sql}" );
504
-
505
- // Integer casting.
506
- foreach ( (array) $paged_blogs as $key => $data ) {
507
- $paged_blogs[ $key ]->blog_id = (int) $paged_blogs[ $key ]->blog_id;
508
- }
509
-
510
- return array( 'blogs' => $paged_blogs, 'total' => (int) $total_blogs );
511
- }
512
-
513
- /**
514
- * Retrieve a list of blogs whose names start with a given letter.
515
- *
516
- * Query will include hidden blogs if the logged-in user has the
517
- * 'bp_moderate' cap.
518
- *
519
- * @param string $letter The letter you're looking for.
520
- * @param int|null $limit Optional. The maximum number of items to return.
521
- * Default: null (no limit).
522
- * @param int|null $page Optional. The page of results to return. Default:
523
- * null (no limit).
524
- * @return array Multidimensional results array, structured as follows:
525
- * 'blogs' - Array of located blog objects.
526
- * 'total' - A count of the total blogs matching the query.
527
- */
528
- public static function get_by_letter( $letter, $limit = null, $page = null ) {
529
- global $wpdb;
530
-
531
- $bp = buddypress();
532
-
533
- $letter_like = '%' . bp_esc_like( $letter ) . '%';
534
- $letter_sql = $wpdb->prepare( 'bm.meta_value LIKE %s', $letter_like );
535
-
536
- $hidden_sql = '';
537
- if ( !bp_current_user_can( 'bp_moderate' ) )
538
- $hidden_sql = "AND wb.public = 1";
539
-
540
- $pag_sql = '';
541
- if ( $limit && $page )
542
- $pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
543
-
544
- $paged_blogs = $wpdb->get_results( "SELECT DISTINCT bm.blog_id FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE bm.meta_key = 'name' AND {$letter_sql} {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY bm.meta_value ASC{$pag_sql}" );
545
- $total_blogs = $wpdb->get_var( "SELECT COUNT(DISTINCT bm.blog_id) FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE bm.meta_key = 'name' AND {$letter_sql} {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY bm.meta_value ASC" );
546
-
547
- // Integer casting.
548
- foreach ( (array) $paged_blogs as $key => $data ) {
549
- $paged_blogs[ $key ]->blog_id = (int) $paged_blogs[ $key ]->blog_id;
550
- }
551
-
552
- return array( 'blogs' => $paged_blogs, 'total' => (int) $total_blogs );
553
- }
554
-
555
- /**
556
- * Fetch blog data not caught in the main query and append it to results array.
557
- *
558
- * Gets the following information, which is either unavailable at the
559
- * time of the original query, or is more efficient to look up in one
560
- * fell swoop:
561
- * - The latest post for each blog, include Featured Image data
562
- * - The blog description
563
- *
564
- * @param array $paged_blogs Array of results from the original query.
565
- * @param array $blog_ids Array of IDs returned from the original query.
566
- * @param string|bool $type Not currently used. Default: false.
567
- * @return array $paged_blogs The located blogs array, with the extras added.
568
- */
569
- public static function get_blog_extras( &$paged_blogs, &$blog_ids, $type = false ) {
570
- global $wpdb;
571
-
572
- $bp = buddypress();
573
-
574
- if ( empty( $blog_ids ) )
575
- return $paged_blogs;
576
-
577
- $blog_ids = implode( ',', wp_parse_id_list( $blog_ids ) );
578
-
579
- for ( $i = 0, $count = count( $paged_blogs ); $i < $count; ++$i ) {
580
- $blog_prefix = $wpdb->get_blog_prefix( $paged_blogs[$i]->blog_id );
581
- $paged_blogs[$i]->latest_post = $wpdb->get_row( "SELECT ID, post_content, post_title, post_excerpt, guid FROM {$blog_prefix}posts WHERE post_status = 'publish' AND post_type = 'post' AND id != 1 ORDER BY id DESC LIMIT 1" );
582
- $images = array();
583
-
584
- // Add URLs to any Featured Image this post might have.
585
- if ( ! empty( $paged_blogs[$i]->latest_post ) && has_post_thumbnail( $paged_blogs[$i]->latest_post->ID ) ) {
586
-
587
- // Grab 4 sizes of the image. Thumbnail.
588
- $image = wp_get_attachment_image_src( get_post_thumbnail_id( $paged_blogs[$i]->latest_post->ID ), 'thumbnail', false );
589
- if ( ! empty( $image ) )
590
- $images['thumbnail'] = $image[0];
591
-
592
- // Medium.
593
- $image = wp_get_attachment_image_src( get_post_thumbnail_id( $paged_blogs[$i]->latest_post->ID ), 'medium', false );
594
- if ( ! empty( $image ) )
595
- $images['medium'] = $image[0];
596
-
597
- // Large.
598
- $image = wp_get_attachment_image_src( get_post_thumbnail_id( $paged_blogs[$i]->latest_post->ID ), 'large', false );
599
- if ( ! empty( $image ) )
600
- $images['large'] = $image[0];
601
-
602
- // Post thumbnail.
603
- $image = wp_get_attachment_image_src( get_post_thumbnail_id( $paged_blogs[$i]->latest_post->ID ), 'post-thumbnail', false );
604
- if ( ! empty( $image ) )
605
- $images['post-thumbnail'] = $image[0];
606
-
607
- // Add the images to the latest_post object.
608
- $paged_blogs[$i]->latest_post->images = $images;
609
- }
610
- }
611
-
612
- /* Fetch the blog description for each blog (as it may be empty we can't fetch it in the main query). */
613
- $blog_descs = $wpdb->get_results( "SELECT blog_id, meta_value as description FROM {$bp->blogs->table_name_blogmeta} WHERE meta_key = 'description' AND blog_id IN ( {$blog_ids} )" );
614
-
615
- for ( $i = 0, $count = count( $paged_blogs ); $i < $count; ++$i ) {
616
- foreach ( (array) $blog_descs as $desc ) {
617
- if ( $desc->blog_id == $paged_blogs[$i]->blog_id )
618
- $paged_blogs[$i]->description = $desc->description;
619
- }
620
- }
621
-
622
- return $paged_blogs;
623
- }
624
-
625
- /**
626
- * Check whether a given blog is hidden.
627
- *
628
- * Checks the 'public' column in the wp_blogs table.
629
- *
630
- * @param int $blog_id The ID of the blog being checked.
631
- * @return bool True if hidden (public = 0), false otherwise.
632
- */
633
- public static function is_hidden( $blog_id ) {
634
- global $wpdb;
635
-
636
- if ( !(int) $wpdb->get_var( $wpdb->prepare( "SELECT public FROM {$wpdb->base_prefix}blogs WHERE blog_id = %d", $blog_id ) ) ) {
637
- return true;
638
- }
639
-
640
- return false;
641
- }
642
-
643
- /**
644
- * Get ID of user-blog link.
645
- *
646
- * @param int $user_id ID of user.
647
- * @param int $blog_id ID of blog.
648
- * @return int|bool ID of user-blog link, or false if not found.
649
- */
650
- public static function get_user_blog( $user_id, $blog_id ) {
651
- global $wpdb;
652
-
653
- $bp = buddypress();
654
-
655
- $user_blog = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->blogs->table_name} WHERE user_id = %d AND blog_id = %d", $user_id, $blog_id ) );
656
-
657
- if ( empty( $user_blog ) ) {
658
- $user_blog = false;
659
- } else {
660
- $user_blog = intval( $user_blog );
661
- }
662
-
663
- return $user_blog;
664
- }
665
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-blogs/classes/class-bp-blogs-component.php DELETED
@@ -1,317 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Blogs Loader
4
- *
5
- * The blogs component tracks posts and comments to member activity streams,
6
- * shows blogs the member can post to in their profiles, and caches useful
7
- * information from those blogs to make querying blogs in bulk more performant.
8
- *
9
- * @package BuddyPress
10
- * @subpackage BlogsCore
11
- * @since 1.5.0
12
- */
13
-
14
- // Exit if accessed directly.
15
- defined( 'ABSPATH' ) || exit;
16
-
17
- /**
18
- * Creates our Blogs component.
19
- */
20
- class BP_Blogs_Component extends BP_Component {
21
-
22
- /**
23
- * Start the blogs component creation process.
24
- *
25
- * @since 1.5.0
26
- */
27
- public function __construct() {
28
- parent::start(
29
- 'blogs',
30
- __( 'Site Directory', 'buddypress' ),
31
- buddypress()->plugin_dir,
32
- array(
33
- 'adminbar_myaccount_order' => 30,
34
- 'search_query_arg' => 'sites_search',
35
- 'features' => array( 'site-icon' )
36
- )
37
- );
38
- }
39
-
40
- /**
41
- * Set up global settings for the blogs component.
42
- *
43
- * The BP_BLOGS_SLUG constant is deprecated, and only used here for
44
- * backwards compatibility.
45
- *
46
- * @since 1.5.0
47
- *
48
- * @see BP_Component::setup_globals() for description of parameters.
49
- *
50
- * @param array $args See {@link BP_Component::setup_globals()}.
51
- */
52
- public function setup_globals( $args = array() ) {
53
- $bp = buddypress();
54
-
55
- if ( ! defined( 'BP_BLOGS_SLUG' ) ) {
56
- define ( 'BP_BLOGS_SLUG', $this->id );
57
- }
58
-
59
- // Global tables for messaging component.
60
- $global_tables = array(
61
- 'table_name' => $bp->table_prefix . 'bp_user_blogs',
62
- 'table_name_blogmeta' => $bp->table_prefix . 'bp_user_blogs_blogmeta',
63
- );
64
-
65
- $meta_tables = array(
66
- 'blog' => $bp->table_prefix . 'bp_user_blogs_blogmeta',
67
- );
68
-
69
- // Fetch the default directory title.
70
- $default_directory_titles = bp_core_get_directory_page_default_titles();
71
- $default_directory_title = $default_directory_titles[$this->id];
72
-
73
- // All globals for blogs component.
74
- $args = array(
75
- 'slug' => BP_BLOGS_SLUG,
76
- 'root_slug' => isset( $bp->pages->blogs->slug ) ? $bp->pages->blogs->slug : BP_BLOGS_SLUG,
77
- 'has_directory' => is_multisite(), // Non-multisite installs don't need a top-level Sites directory, since there's only one site.
78
- 'directory_title' => isset( $bp->pages->blogs->title ) ? $bp->pages->blogs->title : $default_directory_title,
79
- 'notification_callback' => 'bp_blogs_format_notifications',
80
- 'search_string' => __( 'Search sites...', 'buddypress' ),
81
- 'autocomplete_all' => defined( 'BP_MESSAGES_AUTOCOMPLETE_ALL' ),
82
- 'global_tables' => $global_tables,
83
- 'meta_tables' => $meta_tables,
84
- );
85
-
86
- // Setup the globals.
87
- parent::setup_globals( $args );
88
-
89
- /**
90
- * Filters if a blog is public.
91
- *
92
- * In case the config is not multisite, the blog_public option is ignored.
93
- *
94
- * @since 2.3.0
95
- *
96
- * @param int $value Whether or not the blog is public.
97
- */
98
- if ( 0 !== apply_filters( 'bp_is_blog_public', (int) get_option( 'blog_public' ) ) || ! is_multisite() ) {
99
-
100
- /**
101
- * Filters the post types to track for the Blogs component.
102
- *
103
- * @since 1.5.0
104
- * @deprecated 2.3.0
105
- *
106
- * @param array $value Array of post types to track.
107
- */
108
- $post_types = apply_filters( 'bp_blogs_record_post_post_types', array( 'post' ) );
109
-
110
- foreach ( $post_types as $post_type ) {
111
- add_post_type_support( $post_type, 'buddypress-activity' );
112
- }
113
- }
114
- }
115
-
116
- /**
117
- * Include bp-blogs files.
118
- *
119
- * @see BP_Component::includes() for description of parameters.
120
- *
121
- * @param array $includes See {@link BP_Component::includes()}.
122
- */
123
- public function includes( $includes = array() ) {
124
-
125
- // Files to include.
126
- $includes = array(
127
- 'cache',
128
- 'actions',
129
- 'screens',
130
- 'template',
131
- 'filters',
132
- 'functions',
133
- );
134
-
135
- if ( bp_is_active( 'activity' ) ) {
136
- $includes[] = 'activity';
137
- }
138
-
139
- if ( is_multisite() ) {
140
- $includes[] = 'widgets';
141
- }
142
-
143
- // Include the files.
144
- parent::includes( $includes );
145
- }
146
-
147
- /**
148
- * Set up component navigation for bp-blogs.
149
- *
150
- * @see BP_Component::setup_nav() for a description of arguments.
151
- *
152
- * @param array $main_nav Optional. See BP_Component::setup_nav() for
153
- * description.
154
- * @param array $sub_nav Optional. See BP_Component::setup_nav() for
155
- * description.
156
- */
157
- public function setup_nav( $main_nav = array(), $sub_nav = array() ) {
158
-
159
- /**
160
- * Blog/post/comment menus should not appear on single WordPress setups.
161
- * Although comments and posts made by users will still show on their
162
- * activity stream.
163
- */
164
- if ( ! is_multisite() ) {
165
- return false;
166
- }
167
-
168
- // Determine user to use.
169
- if ( bp_displayed_user_domain() ) {
170
- $user_domain = bp_displayed_user_domain();
171
- } elseif ( bp_loggedin_user_domain() ) {
172
- $user_domain = bp_loggedin_user_domain();
173
- } else {
174
- return;
175
- }
176
-
177
- $slug = bp_get_blogs_slug();
178
- $parent_url = trailingslashit( $user_domain . $slug );
179
-
180
- // Add 'Sites' to the main navigation.
181
- $count = (int) bp_get_total_blog_count_for_user();
182
- $class = ( 0 === $count ) ? 'no-count' : 'count';
183
- $nav_text = sprintf(
184
- /* translators: %s: Site count for the current user */
185
- __( 'Sites %s', 'buddypress' ),
186
- sprintf(
187
- '<span class="%s">%s</span>',
188
- esc_attr( $class ),
189
- bp_core_number_format( $count )
190
- )
191
- );
192
- $main_nav = array(
193
- 'name' => $nav_text,
194
- 'slug' => $slug,
195
- 'position' => 30,
196
- 'screen_function' => 'bp_blogs_screen_my_blogs',
197
- 'default_subnav_slug' => 'my-sites',
198
- 'item_css_id' => $this->id
199
- );
200
-
201
- $sub_nav[] = array(
202
- 'name' => __( 'My Sites', 'buddypress' ),
203
- 'slug' => 'my-sites',
204
- 'parent_url' => $parent_url,
205
- 'parent_slug' => $slug,
206
- 'screen_function' => 'bp_blogs_screen_my_blogs',
207
- 'position' => 10
208
- );
209
-
210
- // Setup navigation.
211
- parent::setup_nav( $main_nav, $sub_nav );
212
- }
213
-
214
- /**
215
- * Set up bp-blogs integration with the WordPress admin bar.
216
- *
217
- * @since 1.5.0
218
- *
219
- * @see BP_Component::setup_admin_bar() for a description of arguments.
220
- *
221
- * @param array $wp_admin_nav See BP_Component::setup_admin_bar()
222
- * for description.
223
- * @return bool
224
- */
225
- public function setup_admin_bar( $wp_admin_nav = array() ) {
226
-
227
- /**
228
- * Site/post/comment menus should not appear on single WordPress setups.
229
- *
230
- * Comments and posts made by users will still show in their activity.
231
- */
232
- if ( ! is_multisite() ) {
233
- return false;
234
- }
235
-
236
- // Menus for logged in user.
237
- if ( is_user_logged_in() ) {
238
-
239
- // Setup the logged in user variables.
240
- $blogs_link = trailingslashit( bp_loggedin_user_domain() . bp_get_blogs_slug() );
241
-
242
- // Add the "Sites" sub menu.
243
- $wp_admin_nav[] = array(
244
- 'parent' => buddypress()->my_account_menu_id,
245
- 'id' => 'my-account-' . $this->id,
246
- 'title' => __( 'Sites', 'buddypress' ),
247
- 'href' => $blogs_link
248
- );
249
-
250
- // My Sites.
251
- $wp_admin_nav[] = array(
252
- 'parent' => 'my-account-' . $this->id,
253
- 'id' => 'my-account-' . $this->id . '-my-sites',
254
- 'title' => __( 'My Sites', 'buddypress' ),
255
- 'href' => $blogs_link,
256
- 'position' => 10
257
- );
258
-
259
- // Create a Site.
260
- if ( bp_blog_signup_enabled() ) {
261
- $wp_admin_nav[] = array(
262
- 'parent' => 'my-account-' . $this->id,
263
- 'id' => 'my-account-' . $this->id . '-create',
264
- 'title' => __( 'Create a Site', 'buddypress' ),
265
- 'href' => trailingslashit( bp_get_blogs_directory_permalink() . 'create' ),
266
- 'position' => 99
267
- );
268
- }
269
- }
270
-
271
- parent::setup_admin_bar( $wp_admin_nav );
272
- }
273
-
274
- /**
275
- * Set up the title for pages and <title>.
276
- */
277
- public function setup_title() {
278
-
279
- // Set up the component options navigation for Site.
280
- if ( bp_is_blogs_component() ) {
281
- $bp = buddypress();
282
-
283
- if ( bp_is_my_profile() ) {
284
- if ( bp_is_active( 'xprofile' ) ) {
285
- $bp->bp_options_title = __( 'My Sites', 'buddypress' );
286
- }
287
-
288
- // If we are not viewing the logged in user, set up the current
289
- // users avatar and name.
290
- } else {
291
- $bp->bp_options_avatar = bp_core_fetch_avatar( array(
292
- 'item_id' => bp_displayed_user_id(),
293
- 'type' => 'thumb',
294
- 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_get_displayed_user_fullname() )
295
- ) );
296
- $bp->bp_options_title = bp_get_displayed_user_fullname();
297
- }
298
- }
299
-
300
- parent::setup_title();
301
- }
302
-
303
- /**
304
- * Setup cache groups
305
- *
306
- * @since 2.2.0
307
- */
308
- public function setup_cache_groups() {
309
-
310
- // Global groups.
311
- wp_cache_add_global_groups( array(
312
- 'blog_meta'
313
- ) );
314
-
315
- parent::setup_cache_groups();
316
- }
317
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-blogs/classes/class-bp-blogs-recent-posts-widget.php DELETED
@@ -1,164 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Blogs Recent Posts Widget.
4
- *
5
- * @package BuddyPress
6
- * @subpackage BlogsWidgets
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * The Recent Networkwide Posts widget.
15
- */
16
- class BP_Blogs_Recent_Posts_Widget extends WP_Widget {
17
-
18
- /**
19
- * Constructor method.
20
- */
21
- public function __construct() {
22
- $widget_ops = array(
23
- 'description' => __( 'A list of recently published posts from across your network.', 'buddypress' ),
24
- 'classname' => 'widget_bp_blogs_widget buddypress widget',
25
- 'customize_selective_refresh' => true,
26
- );
27
- parent::__construct( false, $name = _x( '(BuddyPress) Recent Networkwide Posts', 'widget name', 'buddypress' ), $widget_ops );
28
- }
29
-
30
- /**
31
- * Display the networkwide posts widget.
32
- *
33
- * @see WP_Widget::widget() for description of parameters.
34
- *
35
- * @param array $args Widget arguments.
36
- * @param array $instance Widget settings, as saved by the user.
37
- */
38
- public function widget( $args, $instance ) {
39
- global $activities_template;
40
-
41
- $title = ! empty( $instance['title'] )
42
- ? esc_html( $instance['title'] )
43
- : __( 'Recent Networkwide Posts', 'buddypress' );
44
-
45
- if ( ! empty( $instance['link_title'] ) ) {
46
- $title = '<a href="' . bp_get_blogs_directory_permalink() . '">' . esc_html( $title ) . '</a>';
47
- }
48
-
49
- /**
50
- * Filters the Blogs Recent Posts widget title.
51
- *
52
- * @since 2.2.0
53
- * @since 2.3.0 Added 'instance' and 'id_base' to arguments passed to filter.
54
- *
55
- * @param string $title The widget title.
56
- * @param array $instance The settings for the particular instance of the widget.
57
- * @param string $id_base Root ID for all widgets of this type.
58
- */
59
- $title = apply_filters( 'widget_title', $title, $instance, $this->id_base );
60
-
61
- echo $args['before_widget'];
62
- echo $args['before_title'] . $title . $args['after_title'];
63
-
64
- if ( empty( $instance['max_posts'] ) || empty( $instance['max_posts'] ) ) {
65
- $instance['max_posts'] = 10;
66
- }
67
-
68
- $after_widget = $args['after_widget'];
69
-
70
- // Override some of the contextually set parameters for bp_has_activities().
71
- $args = array(
72
- 'action' => 'new_blog_post',
73
- 'max' => $instance['max_posts'],
74
- 'per_page' => $instance['max_posts'],
75
- 'user_id' => 0,
76
- 'scope' => false,
77
- 'object' => false,
78
- 'primary_id' => false
79
- );
80
-
81
- // Back up global.
82
- $old_activities_template = $activities_template;
83
-
84
- ?>
85
-
86
- <?php if ( bp_has_activities( $args ) ) : ?>
87
-
88
- <ul id="blog-post-list" class="activity-list item-list">
89
-
90
- <?php while ( bp_activities() ) : bp_the_activity(); ?>
91
-
92
- <li>
93
- <div class="activity-content" style="margin: 0">
94
- <div class="activity-header"><?php bp_activity_action(); ?></div>
95
-
96
- <?php if ( bp_get_activity_content_body() ) : ?>
97
-
98
- <div class="activity-inner"><?php bp_activity_content_body(); ?></div>
99
-
100
- <?php endif; ?>
101
-
102
- </div>
103
- </li>
104
-
105
- <?php endwhile; ?>
106
-
107
- </ul>
108
-
109
- <?php else : ?>
110
-
111
- <div id="message" class="info">
112
- <p><?php _e( 'Sorry, there were no posts found. Why not write one?', 'buddypress' ); ?></p>
113
- </div>
114
-
115
- <?php endif; ?>
116
-
117
- <?php echo $after_widget;
118
-
119
- // Restore the global.
120
- $activities_template = $old_activities_template;
121
- }
122
-
123
- /**
124
- * Update the networkwide posts widget options.
125
- *
126
- * @param array $new_instance The new instance options.
127
- * @param array $old_instance The old instance options.
128
- * @return array $instance The parsed options to be saved.
129
- */
130
- public function update( $new_instance, $old_instance ) {
131
- $instance = $old_instance;
132
- $instance['title'] = strip_tags( $new_instance['title'] );
133
- $instance['max_posts'] = strip_tags( $new_instance['max_posts'] );
134
- $instance['link_title'] = (bool) $new_instance['link_title'];
135
-
136
- return $instance;
137
- }
138
-
139
- /**
140
- * Output the networkwide posts widget options form.
141
- *
142
- * @param array $instance Settings for this widget.
143
- *
144
- * @return void
145
- */
146
- public function form( $instance ) {
147
- $instance = wp_parse_args( (array) $instance, array(
148
- 'title' => __( 'Recent Networkwide Posts', 'buddypress' ),
149
- 'max_posts' => 10,
150
- 'link_title' => false,
151
- ) );
152
-
153
- $title = strip_tags( $instance['title'] );
154
- $max_posts = strip_tags( $instance['max_posts'] );
155
- $link_title = (bool) $instance['link_title'];
156
-
157
- ?>
158
-
159
- <p><label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _ex( 'Title:', 'Label for the Title field of the Recent Networkwide Posts widget', 'buddypress' ); ?> <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" style="width: 100%;" /></label></p>
160
- <p><label for="<?php echo $this->get_field_id( 'link_title' ); ?>"><input type="checkbox" name="<?php echo $this->get_field_name( 'link_title' ); ?>" value="1" <?php checked( $link_title ); ?> /> <?php _e( 'Link widget title to Blogs directory', 'buddypress' ); ?></label></p>
161
- <p><label for="<?php echo $this->get_field_id( 'max_posts' ); ?>"><?php _e( 'Max posts to show:', 'buddypress' ); ?> <input class="widefat" id="<?php echo $this->get_field_id( 'max_posts' ); ?>" name="<?php echo $this->get_field_name( 'max_posts' ); ?>" type="text" value="<?php echo esc_attr( $max_posts ); ?>" style="width: 30%" /></label></p>
162
- <?php
163
- }
164
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-blogs/classes/class-bp-blogs-template.php DELETED
@@ -1,246 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Blogs Template Class.
4
- *
5
- * @package BuddyPress
6
- * @subpackage BlogsTemplate
7
- * @since 1.5.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * The main blog template loop class.
15
- *
16
- * Responsible for loading a group of blogs into a loop for display.
17
- */
18
- class BP_Blogs_Template {
19
-
20
- /**
21
- * The loop iterator.
22
- *
23
- * @var int
24
- */
25
- public $current_blog = -1;
26
-
27
- /**
28
- * The number of blogs returned by the paged query.
29
- *
30
- * @var int
31
- */
32
- public $blog_count = 0;
33
-
34
- /**
35
- * Array of blogs located by the query..
36
- *
37
- * @var array
38
- */
39
- public $blogs = array();
40
-
41
- /**
42
- * The blog object currently being iterated on.
43
- *
44
- * @var object
45
- */
46
- public $blog;
47
-
48
- /**
49
- * A flag for whether the loop is currently being iterated.
50
- *
51
- * @var bool
52
- */
53
- public $in_the_loop = false;
54
-
55
- /**
56
- * The page number being requested.
57
- *
58
- * @var int
59
- */
60
- public $pag_page = 1;
61
-
62
- /**
63
- * The number of items being requested per page.
64
- *
65
- * @var int
66
- */
67
- public $pag_num = 20;
68
-
69
- /**
70
- * An HTML string containing pagination links.
71
- *
72
- * @var string
73
- */
74
- public $pag_links = '';
75
-
76
- /**
77
- * The total number of blogs matching the query parameters.
78
- *
79
- * @var int
80
- */
81
- public $total_blog_count = 0;
82
-
83
- /**
84
- * Constructor method.
85
- *
86
- * @see BP_Blogs_Blog::get() for a description of parameters.
87
- *
88
- * @param string $type See {@link BP_Blogs_Blog::get()}.
89
- * @param string $page See {@link BP_Blogs_Blog::get()}.
90
- * @param string $per_page See {@link BP_Blogs_Blog::get()}.
91
- * @param string $max See {@link BP_Blogs_Blog::get()}.
92
- * @param string $user_id See {@link BP_Blogs_Blog::get()}.
93
- * @param string $search_terms See {@link BP_Blogs_Blog::get()}.
94
- * @param string $page_arg The string used as a query parameter in
95
- * pagination links. Default: 'bpage'.
96
- * @param bool $update_meta_cache Whether to pre-fetch metadata for
97
- * queried blogs.
98
- * @param array|bool $include_blog_ids Array of blog IDs to include.
99
- */
100
- public function __construct( $type, $page, $per_page, $max, $user_id, $search_terms, $page_arg = 'bpage', $update_meta_cache = true, $include_blog_ids = false ) {
101
-
102
- $this->pag_arg = sanitize_key( $page_arg );
103
- $this->pag_page = bp_sanitize_pagination_arg( $this->pag_arg, $page );
104
- $this->pag_num = bp_sanitize_pagination_arg( 'num', $per_page );
105
-
106
- // Backwards compatibility support for blogs by first letter.
107
- if ( ! empty( $_REQUEST['letter'] ) ) {
108
- $this->blogs = BP_Blogs_Blog::get_by_letter( $_REQUEST['letter'], $this->pag_num, $this->pag_page );
109
-
110
- // Typical blogs query.
111
- } else {
112
- $this->blogs = bp_blogs_get_blogs( array(
113
- 'type' => $type,
114
- 'per_page' => $this->pag_num,
115
- 'page' => $this->pag_page,
116
- 'user_id' => $user_id,
117
- 'search_terms' => $search_terms,
118
- 'update_meta_cache' => $update_meta_cache,
119
- 'include_blog_ids' => $include_blog_ids,
120
- ) );
121
- }
122
-
123
- // Set the total blog count.
124
- if ( empty( $max ) || ( $max >= (int) $this->blogs['total'] ) ) {
125
- $this->total_blog_count = (int) $this->blogs['total'];
126
- } else {
127
- $this->total_blog_count = (int) $max;
128
- }
129
-
130
- // Set the blogs array (to loop through later.
131
- $this->blogs = $this->blogs['blogs'];
132
-
133
- // Get the current blog count to compare maximum against.
134
- $blog_count = count( $this->blogs );
135
-
136
- // Set the current blog count.
137
- if ( empty( $max ) || ( $max >= (int) $blog_count ) ) {
138
- $this->blog_count = (int) $blog_count;
139
- } else {
140
- $this->blog_count = (int) $max;
141
- }
142
-
143
- // Build pagination links based on total blogs and current page number.
144
- if ( ! empty( $this->total_blog_count ) && ! empty( $this->pag_num ) ) {
145
- $this->pag_links = paginate_links( array(
146
- 'base' => add_query_arg( $this->pag_arg, '%#%' ),
147
- 'format' => '',
148
- 'total' => ceil( (int) $this->total_blog_count / (int) $this->pag_num ),
149
- 'current' => (int) $this->pag_page,
150
- 'prev_text' => _x( '&larr;', 'Blog pagination previous text', 'buddypress' ),
151
- 'next_text' => _x( '&rarr;', 'Blog pagination next text', 'buddypress' ),
152
- 'mid_size' => 1,
153
- 'add_args' => array(),
154
- ) );
155
- }
156
- }
157
-
158
- /**
159
- * Whether there are blogs available in the loop.
160
- *
161
- * @see bp_has_blogs()
162
- *
163
- * @return bool True if there are items in the loop, otherwise false.
164
- */
165
- public function has_blogs() {
166
- return (bool) ! empty( $this->blog_count );
167
- }
168
-
169
- /**
170
- * Set up the next blog and iterate index.
171
- *
172
- * @return object The next blog to iterate over.
173
- */
174
- public function next_blog() {
175
- $this->current_blog++;
176
- $this->blog = $this->blogs[ $this->current_blog ];
177
-
178
- return $this->blog;
179
- }
180
-
181
- /**
182
- * Rewind the blogs and reset blog index.
183
- */
184
- public function rewind_blogs() {
185
- $this->current_blog = -1;
186
- if ( $this->blog_count > 0 ) {
187
- $this->blog = $this->blogs[0];
188
- }
189
- }
190
-
191
- /**
192
- * Whether there are blogs left in the loop to iterate over.
193
- *
194
- * This method is used by {@link bp_blogs()} as part of the while loop
195
- * that controls iteration inside the blogs loop, eg:
196
- * while ( bp_blogs() ) { ...
197
- *
198
- * @see bp_blogs()
199
- *
200
- * @return bool True if there are more blogs to show, otherwise false.
201
- */
202
- public function blogs() {
203
- if ( ( $this->current_blog + 1 ) < $this->blog_count ) {
204
- return true;
205
- } elseif ( ( $this->current_blog + 1 ) === $this->blog_count ) {
206
-
207
- /**
208
- * Fires right before the rewinding of blogs listing after all are shown.
209
- *
210
- * @since 1.5.0
211
- */
212
- do_action( 'blog_loop_end' );
213
- // Do some cleaning up after the loop.
214
- $this->rewind_blogs();
215
- }
216
-
217
- $this->in_the_loop = false;
218
- return false;
219
- }
220
-
221
- /**
222
- * Set up the current blog inside the loop.
223
- *
224
- * Used by {@link bp_the_blog()} to set up the current blog data while
225
- * looping, so that template tags used during that iteration make
226
- * reference to the current blog.
227
- *
228
- * @see bp_the_blog()
229
- */
230
- public function the_blog() {
231
-
232
- $this->in_the_loop = true;
233
- $this->blog = $this->next_blog();
234
-
235
- // Loop has just started.
236
- if ( 0 === $this->current_blog ) {
237
-
238
- /**
239
- * Fires if on the first blog in the loop.
240
- *
241
- * @since 1.5.0
242
- */
243
- do_action( 'blog_loop_start' );
244
- }
245
- }
246
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-blogs/classes/class-bp-blogs-theme-compat.php DELETED
@@ -1,201 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Blogs Theme Compatibility.
4
- *
5
- * @package BuddyPress
6
- * @subpackage BlogsScreens
7
- * @since 1.5.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * The main theme compat class for BuddyPress Blogs.
15
- *
16
- * This class sets up the necessary theme compatibility actions to safely output
17
- * group template parts to the_title and the_content areas of a theme.
18
- *
19
- * @since 1.7.0
20
- */
21
- class BP_Blogs_Theme_Compat {
22
-
23
- /**
24
- * Set up theme compatibility for the Blogs component.
25
- *
26
- * @since 1.7.0
27
- */
28
- public function __construct() {
29
- add_action( 'bp_setup_theme_compat', array( $this, 'is_blogs' ) );
30
- }
31
-
32
- /**
33
- * Are we looking at something that needs Blogs theme compatibility?
34
- *
35
- * @since 1.7.0
36
- */
37
- public function is_blogs() {
38
-
39
- // Bail if not looking at a group.
40
- if ( ! bp_is_blogs_component() )
41
- return;
42
-
43
- // Bail if looking at a users sites.
44
- if ( bp_is_user() )
45
- return;
46
-
47
- // Blog Directory.
48
- if ( is_multisite() && ! bp_current_action() ) {
49
- bp_update_is_directory( true, 'blogs' );
50
-
51
- /**
52
- * Fires if in the blog directory and BuddyPress needs Blog theme compatibility,
53
- * before the actions and filters are added.
54
- *
55
- * @since 1.5.0
56
- */
57
- do_action( 'bp_blogs_screen_index' );
58
-
59
- add_filter( 'bp_get_buddypress_template', array( $this, 'directory_template_hierarchy' ) );
60
- add_action( 'bp_template_include_reset_dummy_post_data', array( $this, 'directory_dummy_post' ) );
61
- add_filter( 'bp_replace_the_content', array( $this, 'directory_content' ) );
62
-
63
- // Create blog.
64
- } elseif ( is_user_logged_in() && bp_blog_signup_enabled() ) {
65
- add_filter( 'bp_get_buddypress_template', array( $this, 'create_template_hierarchy' ) );
66
- add_action( 'bp_template_include_reset_dummy_post_data', array( $this, 'create_dummy_post' ) );
67
- add_filter( 'bp_replace_the_content', array( $this, 'create_content' ) );
68
- }
69
- }
70
-
71
- /** Directory *************************************************************/
72
-
73
- /**
74
- * Add template hierarchy to theme compat for the blog directory page.
75
- *
76
- * This is to mirror how WordPress has
77
- * {@link https://codex.wordpress.org/Template_Hierarchy template hierarchy}.
78
- *
79
- * @since 1.8.0
80
- *
81
- * @param string $templates The templates from bp_get_theme_compat_templates().
82
- * @return array $templates Array of custom templates to look for.
83
- */
84
- public function directory_template_hierarchy( $templates ) {
85
-
86
- /**
87
- * Filters the custom templates used for theme compat with the blog directory page.
88
- *
89
- * @since 1.8.0
90
- *
91
- * @param array $value Array of template paths to add to template list to look for.
92
- */
93
- $new_templates = apply_filters( 'bp_template_hierarchy_blogs_create', array(
94
- 'blogs/index-directory.php'
95
- ) );
96
-
97
- // Merge new templates with existing stack
98
- // @see bp_get_theme_compat_templates().
99
- $templates = array_merge( (array) $new_templates, $templates );
100
-
101
- return $templates;
102
- }
103
-
104
- /**
105
- * Update the global $post with directory data.
106
- *
107
- * @since 1.7.0
108
- */
109
- public function directory_dummy_post() {
110
-
111
- bp_theme_compat_reset_post( array(
112
- 'ID' => 0,
113
- 'post_title' => __( 'Sites', 'buddypress' ),
114
- 'post_author' => 0,
115
- 'post_date' => 0,
116
- 'post_content' => '',
117
- 'post_type' => 'page',
118
- 'post_status' => 'publish',
119
- 'is_page' => true,
120
- 'comment_status' => 'closed'
121
- ) );
122
- }
123
-
124
- /**
125
- * Filter the_content with the groups index template part.
126
- *
127
- * @since 1.7.0
128
- */
129
- public function directory_content() {
130
- return bp_buffer_template_part( 'blogs/index', null, false );
131
- }
132
-
133
- /** Create ****************************************************************/
134
-
135
- /**
136
- * Add custom template hierarchy to theme compat for the blog create page.
137
- *
138
- * This is to mirror how WordPress has
139
- * {@link https://codex.wordpress.org/Template_Hierarchy template hierarchy}.
140
- *
141
- * @since 1.8.0
142
- *
143
- * @param string $templates The templates from bp_get_theme_compat_templates().
144
- * @return array $templates Array of custom templates to look for.
145
- */
146
- public function create_template_hierarchy( $templates ) {
147
-
148
- /**
149
- * Filters the custom templates used for theme compat with the blog create page.
150
- *
151
- * @since 1.8.0
152
- *
153
- * @param array $value Array of template paths to add to template list to look for.
154
- */
155
- $new_templates = apply_filters( 'bp_template_hierarchy_blogs_create', array(
156
- 'blogs/index-create.php'
157
- ) );
158
-
159
- // Merge new templates with existing stack
160
- // @see bp_get_theme_compat_templates().
161
- $templates = array_merge( (array) $new_templates, $templates );
162
-
163
- return $templates;
164
- }
165
-
166
- /**
167
- * Update the global $post with create screen data.
168
- *
169
- * @since 1.7.0
170
- */
171
- public function create_dummy_post() {
172
-
173
- // Title based on ability to create blogs.
174
- if ( is_user_logged_in() && bp_blog_signup_enabled() ) {
175
- $title = __( 'Create a Site', 'buddypress' );
176
- } else {
177
- $title = __( 'Sites', 'buddypress' );
178
- }
179
-
180
- bp_theme_compat_reset_post( array(
181
- 'ID' => 0,
182
- 'post_title' => $title,
183
- 'post_author' => 0,
184
- 'post_date' => 0,
185
- 'post_content' => '',
186
- 'post_type' => 'page',
187
- 'post_status' => 'publish',
188
- 'is_page' => true,
189
- 'comment_status' => 'closed'
190
- ) );
191
- }
192
-
193
- /**
194
- * Filter the_content with the create screen template part.
195
- *
196
- * @since 1.7.0
197
- */
198
- public function create_content() {
199
- return bp_buffer_template_part( 'blogs/create', null, false );
200
- }
201
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-core.php ADDED
@@ -0,0 +1,2224 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /* Define the current version number for checking if DB tables are up to date. */
4
+ define( 'BP_CORE_DB_VERSION', '1800' );
5
+
6
+ /***
7
+ * Define the path and url of the BuddyPress plugins directory.
8
+ * It is important to use plugins_url() core function to obtain
9
+ * the correct scheme used (http or https).
10
+ */
11
+ define( 'BP_PLUGIN_DIR', WP_PLUGIN_DIR . '/buddypress' );
12
+ define( 'BP_PLUGIN_URL', plugins_url( $path = '/buddypress' ) );
13
+
14
+ /* Load the WP abstraction file so BuddyPress can run on all WordPress setups. */
15
+ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-wpabstraction.php' );
16
+
17
+ /* Place your custom code (actions/filters) in a file called /plugins/bp-custom.php and it will be loaded before anything else. */
18
+ if ( file_exists( WP_PLUGIN_DIR . '/bp-custom.php' ) )
19
+ require( WP_PLUGIN_DIR . '/bp-custom.php' );
20
+
21
+ /* Define on which blog ID BuddyPress should run */
22
+ if ( !defined( 'BP_ROOT_BLOG' ) )
23
+ define( 'BP_ROOT_BLOG', 1 );
24
+
25
+ /* Define the user and usermeta table names, useful if you are using custom or shared tables. */
26
+ if ( !defined( 'CUSTOM_USER_TABLE' ) )
27
+ define( 'CUSTOM_USER_TABLE', $wpdb->base_prefix . 'users' );
28
+
29
+ if ( !defined( 'CUSTOM_USER_META_TABLE' ) )
30
+ define( 'CUSTOM_USER_META_TABLE', $wpdb->base_prefix . 'usermeta' );
31
+
32
+ /* Load the files containing functions that we globally will need. */
33
+ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-catchuri.php' );
34
+ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-classes.php' );
35
+ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-filters.php' );
36
+ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-cssjs.php' );
37
+ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-avatars.php' );
38
+ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-templatetags.php' );
39
+ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-settings.php' );
40
+ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-widgets.php' );
41
+ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-notifications.php' );
42
+ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-signup.php' );
43
+
44
+ /* If BP_DISABLE_ADMIN_BAR is defined, do not load the global admin bar. */
45
+ if ( !defined( 'BP_DISABLE_ADMIN_BAR' ) )
46
+ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-adminbar.php' );
47
+
48
+ /* Define the slug for member pages and the members directory (e.g. domain.com/[members] ) */
49
+ if ( !defined( 'BP_MEMBERS_SLUG' ) )
50
+ define( 'BP_MEMBERS_SLUG', 'members' );
51
+
52
+ /* Define the slug for the register/signup page */
53
+ if ( !defined( 'BP_REGISTER_SLUG' ) )
54
+ define( 'BP_REGISTER_SLUG', 'register' );
55
+
56
+ /* Define the slug for the activation page */
57
+ if ( !defined( 'BP_ACTIVATION_SLUG' ) )
58
+ define( 'BP_ACTIVATION_SLUG', 'activate' );
59
+
60
+ /* Define the slug for the search page */
61
+ if ( !defined( 'BP_SEARCH_SLUG' ) )
62
+ define( 'BP_SEARCH_SLUG', 'search' );
63
+
64
+ /* Register BuddyPress themes contained within the bp-theme folder */
65
+ if ( function_exists( 'register_theme_directory') )
66
+ register_theme_directory( WP_PLUGIN_DIR . '/buddypress/bp-themes' );
67
+
68
+
69
+ /* "And now for something completely different" .... */
70
+
71
+
72
+ /**
73
+ * bp_core_setup_globals()
74
+ *
75
+ * Sets up default global BuddyPress configuration settings and stores
76
+ * them in a $bp variable.
77
+ *
78
+ * @package BuddyPress Core Core
79
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
80
+ * @global $current_user A WordPress global containing current user information
81
+ * @global $current_component Which is set up in /bp-core/bp-core-catch-uri.php
82
+ * @global $current_action Which is set up in /bp-core/bp-core-catch-uri.php
83
+ * @global $action_variables Which is set up in /bp-core/bp-core-catch-uri.php
84
+ * @uses bp_core_get_user_domain() Returns the domain for a user
85
+ */
86
+ function bp_core_setup_globals() {
87
+ global $bp;
88
+ global $current_user, $current_component, $current_action, $current_blog;
89
+ global $displayed_user_id;
90
+ global $action_variables;
91
+
92
+ $current_user = wp_get_current_user();
93
+
94
+ /* Get the base database prefix */
95
+ $bp->table_prefix = bp_core_get_table_prefix();
96
+
97
+ /* The domain for the root of the site where the main blog resides */
98
+ $bp->root_domain = bp_core_get_root_domain();
99
+
100
+ /* The user ID of the user who is currently logged in. */
101
+ $bp->loggedin_user->id = $current_user->ID;
102
+
103
+ /* The domain for the user currently logged in. eg: http://domain.com/members/andy */
104
+ $bp->loggedin_user->domain = bp_core_get_user_domain( $bp->loggedin_user->id );
105
+
106
+ /* The core userdata of the user who is currently logged in. */
107
+ $bp->loggedin_user->userdata = bp_core_get_core_userdata( $bp->loggedin_user->id );
108
+
109
+ /* is_super_admin() hits the DB on single WP installs, so we need to get this separately so we can call it in a loop. */
110
+ $bp->loggedin_user->is_super_admin = is_super_admin();
111
+ $bp->loggedin_user->is_site_admin = $bp->loggedin_user->is_super_admin; // deprecated 1.2.6
112
+
113
+ /* The user id of the user currently being viewed, set in /bp-core/bp-core-catchuri.php */
114
+ $bp->displayed_user->id = $displayed_user_id;
115
+
116
+ /* The domain for the user currently being displayed */
117
+ $bp->displayed_user->domain = bp_core_get_user_domain( $bp->displayed_user->id );
118
+
119
+ /* The core userdata of the user who is currently being displayed */
120
+ $bp->displayed_user->userdata = bp_core_get_core_userdata( $bp->displayed_user->id );
121
+
122
+ /* The component being used eg: http://domain.com/members/andy/ [profile] */
123
+ $bp->current_component = $current_component; // type: string
124
+
125
+ /* The current action for the component eg: http://domain.com/members/andy/profile/ [edit] */
126
+ $bp->current_action = $current_action; // type: string
127
+
128
+ /* The action variables for the current action eg: http://domain.com/members/andy/profile/edit/ [group] / [6] */
129
+ $bp->action_variables = $action_variables; // type: array
130
+
131
+ /* Only used where a component has a sub item, e.g. groups: http://domain.com/members/andy/groups/ [my-group] / home - manipulated in the actual component not in catch uri code.*/
132
+ $bp->current_item = ''; // type: string
133
+
134
+ /* Used for overriding the 2nd level navigation menu so it can be used to display custom navigation for an item (for example a group) */
135
+ $bp->is_single_item = false;
136
+
137
+ /* The default component to use if none are set and someone visits: http://domain.com/members/andy */
138
+ if ( !defined( 'BP_DEFAULT_COMPONENT' ) ) {
139
+ if ( defined( 'BP_ACTIVITY_SLUG' ) )
140
+ $bp->default_component = BP_ACTIVITY_SLUG;
141
+ else
142
+ $bp->default_component = 'profile';
143
+ } else {
144
+ $bp->default_component = BP_DEFAULT_COMPONENT;
145
+ }
146
+
147
+ /* Fetches all of the core database based BuddyPress settings in one foul swoop */
148
+ $bp->site_options = bp_core_get_site_options();
149
+
150
+ /* Sets up the array container for the component navigation rendered by bp_get_nav() */
151
+ $bp->bp_nav = array();
152
+
153
+ /* Sets up the array container for the component options navigation rendered by bp_get_options_nav() */
154
+ $bp->bp_options_nav = array();
155
+
156
+ /* Contains an array of all the active components. The key is the slug, value the internal ID of the component */
157
+ $bp->active_components = array();
158
+
159
+ /* Fetches the default Gravatar image to use if the user/group/blog has no avatar or gravatar */
160
+ $bp->grav_default->user = apply_filters( 'bp_user_gravatar_default', $bp->site_options['user-avatar-default'] );
161
+ $bp->grav_default->group = apply_filters( 'bp_group_gravatar_default', 'identicon' );
162
+ $bp->grav_default->blog = apply_filters( 'bp_blog_gravatar_default', 'identicon' );
163
+
164
+ /* Fetch the full name for the logged in and current user */
165
+ $bp->loggedin_user->fullname = bp_core_get_user_displayname( $bp->loggedin_user->id );
166
+ $bp->displayed_user->fullname = bp_core_get_user_displayname( $bp->displayed_user->id );
167
+
168
+ /* Used to determine if user has admin rights on current content. If the logged in user is viewing
169
+ their own profile and wants to delete something, is_item_admin is used. This is a
170
+ generic variable so it can be used by other components. It can also be modified, so when viewing a group
171
+ 'is_item_admin' would be 1 if they are a group admin, 0 if they are not. */
172
+ $bp->is_item_admin = bp_user_has_access();
173
+
174
+ /* Used to determine if the logged in user is a moderator for the current content. */
175
+ $bp->is_item_mod = false;
176
+
177
+ $bp->core->table_name_notifications = $bp->table_prefix . 'bp_notifications';
178
+
179
+ if ( !$bp->current_component && $bp->displayed_user->id )
180
+ $bp->current_component = $bp->default_component;
181
+
182
+ do_action( 'bp_core_setup_globals' );
183
+ }
184
+ add_action( 'bp_setup_globals', 'bp_core_setup_globals' );
185
+
186
+ /**
187
+ * bp_core_setup_root_uris()
188
+ *
189
+ * Adds the core URIs that should run in the root of the installation.
190
+ *
191
+ * For example: http://example.org/search/ or http://example.org/members/
192
+ *
193
+ * @package BuddyPress Core
194
+ * @uses bp_core_add_root_component() Adds a slug to the root components global variable.
195
+ */
196
+ function bp_core_setup_root_uris() {
197
+ // Add core root components
198
+ bp_core_add_root_component( BP_MEMBERS_SLUG );
199
+ bp_core_add_root_component( BP_REGISTER_SLUG );
200
+ bp_core_add_root_component( BP_ACTIVATION_SLUG );
201
+ bp_core_add_root_component( BP_SEARCH_SLUG );
202
+ }
203
+ add_action( 'bp_setup_root_components', 'bp_core_setup_root_uris' );
204
+
205
+ /**
206
+ * bp_core_get_table_prefix()
207
+ *
208
+ * Allow filtering of database prefix. Intended for use in multinetwork installations.
209
+ *
210
+ * @global object $wpdb WordPress database object
211
+ * @return string Filtered database prefix
212
+ */
213
+ function bp_core_get_table_prefix() {
214
+ global $wpdb;
215
+
216
+ return apply_filters( 'bp_core_get_table_prefix', $wpdb->base_prefix );
217
+ }
218
+
219
+ /**
220
+ * bp_core_install()
221
+ *
222
+ * Installs the core DB tables for BuddyPress.
223
+ *
224
+ * @package BuddyPress Core
225
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
226
+ * @global $wpdb WordPress DB access object.
227
+ * @uses dbDelta() Performs a table creation, or upgrade based on what already exists in the DB.
228
+ * @uses bp_core_add_illegal_names() Adds illegal blog names to the WP settings
229
+ */
230
+ function bp_core_install() {
231
+ global $wpdb, $bp;
232
+
233
+ if ( !empty($wpdb->charset) )
234
+ $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
235
+
236
+ $sql[] = "CREATE TABLE {$bp->core->table_name_notifications} (
237
+ id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
238
+ user_id bigint(20) NOT NULL,
239
+ item_id bigint(20) NOT NULL,
240
+ secondary_item_id bigint(20),
241
+ component_name varchar(75) NOT NULL,
242
+ component_action varchar(75) NOT NULL,
243
+ date_notified datetime NOT NULL,
244
+ is_new bool NOT NULL DEFAULT 0,
245
+ KEY item_id (item_id),
246
+ KEY secondary_item_id (secondary_item_id),
247
+ KEY user_id (user_id),
248
+ KEY is_new (is_new),
249
+ KEY component_name (component_name),
250
+ KEY component_action (component_action),
251
+ KEY useritem (user_id,is_new)
252
+ ) {$charset_collate};";
253
+
254
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
255
+ dbDelta( $sql );
256
+
257
+ // Add names of root components to the banned name list to avoid conflicts
258
+ bp_core_flush_illegal_names();
259
+
260
+ update_site_option( 'bp-core-db-version', BP_CORE_DB_VERSION );
261
+ }
262
+
263
+ /**
264
+ * bp_core_check_installed()
265
+ *
266
+ * Checks to make sure the database tables are set up for the core component.
267
+ *
268
+ * @package BuddyPress Core
269
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
270
+ * @global $current_user WordPress global variable containing current logged in user information
271
+ * @uses is_super_admin() returns true if the current user is a site admin, false if not
272
+ * @uses get_site_option() fetches the value for a meta_key in the wp_sitemeta table
273
+ * @uses bp_core_install() runs the installation of DB tables for the core component
274
+ */
275
+ function bp_core_check_installed() {
276
+ global $bp;
277
+
278
+ if ( !is_super_admin() )
279
+ return false;
280
+
281
+ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-admin.php' );
282
+
283
+ /* Need to check db tables exist, activate hook no-worky in mu-plugins folder. */
284
+ if ( get_site_option( 'bp-core-db-version' ) < BP_CORE_DB_VERSION )
285
+ bp_core_install();
286
+ }
287
+ add_action( is_multisite() ? 'network_admin_menu' : 'admin_menu', 'bp_core_check_installed' );
288
+
289
+ /**
290
+ * bp_core_add_admin_menu()
291
+ *
292
+ * Adds the "BuddyPress" admin submenu item to the Site Admin tab.
293
+ *
294
+ * @package BuddyPress Core
295
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
296
+ * @uses is_super_admin() returns true if the current user is a site admin, false if not
297
+ * @uses add_submenu_page() WP function to add a submenu item
298
+ */
299
+ function bp_core_add_admin_menu() {
300
+ if ( !is_super_admin() )
301
+ return false;
302
+
303
+ // If this is WP 3.1+ and multisite is enabled, only load on the Network Admin
304
+ if ( is_multisite() && function_exists( 'is_network_admin' ) && ! is_network_admin() )
305
+ return false;
306
+
307
+ // Add the administration tab under the "Site Admin" tab for site administrators
308
+ bp_core_add_admin_menu_page( array(
309
+ 'menu_title' => __( 'BuddyPress', 'buddypress' ),
310
+ 'page_title' => __( 'BuddyPress', 'buddypress' ),
311
+ 'access_level' => 10, 'file' => 'bp-general-settings',
312
+ 'function' => 'bp_core_admin_settings',
313
+ 'position' => 2
314
+ ) );
315
+
316
+ add_submenu_page( 'bp-general-settings', __( 'General Settings', 'buddypress'), __( 'General Settings', 'buddypress' ), 'manage_options', 'bp-general-settings', 'bp_core_admin_settings' );
317
+ add_submenu_page( 'bp-general-settings', __( 'Component Setup', 'buddypress'), __( 'Component Setup', 'buddypress' ), 'manage_options', 'bp-component-setup', 'bp_core_admin_component_setup' );
318
+ }
319
+ add_action( is_multisite() ? 'network_admin_menu' : 'admin_menu', 'bp_core_add_admin_menu' );
320
+
321
+ /**
322
+ * bp_core_is_root_component()
323
+ *
324
+ * Checks to see if a component's URL should be in the root, not under a member page:
325
+ * eg: http://domain.com/groups/the-group NOT http://domain.com/members/andy/groups/the-group
326
+ *
327
+ * @package BuddyPress Core
328
+ * @return true if root component, else false.
329
+ */
330
+ function bp_core_is_root_component( $component_name ) {
331
+ global $bp;
332
+
333
+ return in_array( $component_name, $bp->root_components );
334
+ }
335
+
336
+ /**
337
+ * bp_core_setup_nav()
338
+ *
339
+ * Sets up the profile navigation item if the Xprofile component is not installed.
340
+ *
341
+ * @package BuddyPress Core
342
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
343
+ * @uses bp_core_new_nav_item() Adds a navigation item to the top level buddypress navigation
344
+ * @uses bp_core_new_subnav_item() Adds a sub navigation item to a nav item
345
+ * @uses bp_is_my_profile() Returns true if the current user being viewed is equal the logged in user
346
+ * @uses bp_core_fetch_avatar() Returns the either the thumb or full avatar URL for the user_id passed
347
+ */
348
+ function bp_core_setup_nav() {
349
+ global $bp;
350
+
351
+ /***
352
+ * If the extended profiles component is disabled, we need to revert to using the
353
+ * built in WordPress profile information
354
+ */
355
+ if ( !function_exists( 'xprofile_install' ) ) {
356
+ /* Fallback values if xprofile is disabled */
357
+ $bp->core->profile->slug = 'profile';
358
+ $bp->active_components[$bp->core->profile->slug] = $bp->core->profile->slug;
359
+
360
+ /* Add 'Profile' to the main navigation */
361
+ bp_core_new_nav_item( array(
362
+ 'name' => __('Profile', 'buddypress'),
363
+ 'slug' => $bp->core->profile->slug,
364
+ 'position' => 20,
365
+ 'screen_function' => 'bp_core_catch_profile_uri',
366
+ 'default_subnav_slug' => 'public'
367
+ ) );
368
+
369
+ $profile_link = $bp->loggedin_user->domain . '/profile/';
370
+
371
+ /* Add the subnav items to the profile */
372
+ bp_core_new_subnav_item( array(
373
+ 'name' => __( 'Public', 'buddypress' ),
374
+ 'slug' => 'public',
375
+ 'parent_url' => $profile_link,
376
+ 'parent_slug' => $bp->core->profile->slug,
377
+ 'screen_function' => 'bp_core_catch_profile_uri'
378
+ ) );
379
+
380
+
381
+ if ( 'profile' == $bp->current_component ) {
382
+ if ( bp_is_my_profile() ) {
383
+ $bp->bp_options_title = __('My Profile', 'buddypress');
384
+ } else {
385
+ $bp->bp_options_avatar = bp_core_fetch_avatar( array( 'item_id' => $bp->displayed_user->id, 'type' => 'thumb' ) );
386
+ $bp->bp_options_title = $bp->displayed_user->fullname;
387
+ }
388
+ }
389
+ }
390
+ }
391
+ add_action( 'bp_setup_nav', 'bp_core_setup_nav' );
392
+
393
+ /********************************************************************************
394
+ * Action Functions
395
+ *
396
+ * Action functions are exactly the same as screen functions, however they do not
397
+ * have a template screen associated with them. Usually they will send the user
398
+ * back to the default screen after execution.
399
+ */
400
+
401
+ /**
402
+ * bp_core_action_directory_members()
403
+ *
404
+ * Listens to the $bp component and action variables to determine if the user is viewing the members
405
+ * directory page. If they are, it will set up the directory and load the members directory template.
406
+ *
407
+ * @package BuddyPress Core
408
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
409
+ * @uses wp_enqueue_script() Loads a JS script into the header of the page.
410
+ * @uses bp_core_load_template() Loads a specific template file.
411
+ */
412
+ function bp_core_action_directory_members() {
413
+ global $bp;
414
+
415
+ if ( is_null( $bp->displayed_user->id ) && $bp->current_component == BP_MEMBERS_SLUG ) {
416
+ $bp->is_directory = true;
417
+
418
+ do_action( 'bp_core_action_directory_members' );
419
+ bp_core_load_template( apply_filters( 'bp_core_template_directory_members', 'members/index' ) );
420
+ }
421
+ }
422
+ add_action( 'wp', 'bp_core_action_directory_members', 2 );
423
+
424
+ /**
425
+ * bp_core_action_set_spammer_status()
426
+ *
427
+ * When a site admin selects "Mark as Spammer/Not Spammer" from the admin menu
428
+ * this action will fire and mark or unmark the user and their blogs as spam.
429
+ * Must be a site admin for this function to run.
430
+ *
431
+ * @package BuddyPress Core
432
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
433
+ */
434
+ function bp_core_action_set_spammer_status() {
435
+ global $bp, $wpdb, $wp_version;
436
+
437
+ if ( !is_super_admin() || bp_is_my_profile() || !$bp->displayed_user->id )
438
+ return false;
439
+
440
+ if ( 'admin' == $bp->current_component && ( 'mark-spammer' == $bp->current_action || 'unmark-spammer' == $bp->current_action ) ) {
441
+ /* Check the nonce */
442
+ check_admin_referer( 'mark-unmark-spammer' );
443
+
444
+ /* Get the functions file */
445
+ if ( bp_core_is_multisite() ) {
446
+ if ( $wp_version >= '3.0' )
447
+ require_once( ABSPATH . '/wp-admin/includes/ms.php' );
448
+ else
449
+ require_once( ABSPATH . '/wp-admin/includes/mu.php' );
450
+ }
451
+
452
+ if ( 'mark-spammer' == $bp->current_action )
453
+ $is_spam = 1;
454
+ else
455
+ $is_spam = 0;
456
+
457
+ /* Get the blogs for the user */
458
+ $blogs = get_blogs_of_user( $bp->displayed_user->id, true );
459
+
460
+ foreach ( (array) $blogs as $key => $details ) {
461
+ /* Do not mark the main or current root blog as spam */
462
+ if ( 1 == $details->userblog_id || BP_ROOT_BLOG == $details->userblog_id )
463
+ continue;
464
+
465
+ /* Update the blog status */
466
+ update_blog_status( $details->userblog_id, 'spam', $is_spam );
467
+
468
+ /* Fire the standard WPMU hook */
469
+ do_action( 'make_spam_blog', $details->userblog_id );
470
+ }
471
+
472
+ /* Finally, mark this user as a spammer */
473
+ if ( bp_core_is_multisite() )
474
+ $wpdb->update( $wpdb->users, array( 'spam' => $is_spam ), array( 'ID' => $bp->displayed_user->id ) );
475
+
476
+ $wpdb->update( $wpdb->users, array( 'user_status' => $is_spam ), array( 'ID' => $bp->displayed_user->id ) );
477
+
478
+ if ( $is_spam )
479
+ bp_core_add_message( __( 'User marked as spammer. Spam users are visible only to site admins.', 'buddypress' ) );
480
+ else
481
+ bp_core_add_message( __( 'User removed as spammer.', 'buddypress' ) );
482
+
483
+ /* Hide this user's activity */
484
+ if ( $is_spam && function_exists( 'bp_activity_hide_user_activity' ) )
485
+ bp_activity_hide_user_activity( $bp->displayed_user->id );
486
+
487
+ do_action( 'bp_core_action_set_spammer_status', $bp->displayed_user->id, $is_spam );
488
+
489
+ bp_core_redirect( wp_get_referer() );
490
+ }
491
+ }
492
+ add_action( 'wp', 'bp_core_action_set_spammer_status', 3 );
493
+
494
+ /**
495
+ * bp_core_action_delete_user()
496
+ *
497
+ * Allows a site admin to delete a user from the adminbar menu.
498
+ *
499
+ * @package BuddyPress Core
500
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
501
+ */
502
+ function bp_core_action_delete_user() {
503
+ global $bp;
504
+
505
+ if ( !is_super_admin() || bp_is_my_profile() || !$bp->displayed_user->id )
506
+ return false;
507
+
508
+ if ( 'admin' == $bp->current_component && 'delete-user' == $bp->current_action ) {
509
+ /* Check the nonce */
510
+ check_admin_referer( 'delete-user' );
511
+
512
+ $errors = false;
513
+
514
+ if ( bp_core_delete_account( $bp->displayed_user->id ) ) {
515
+ bp_core_add_message( sprintf( __( '%s has been deleted from the system.', 'buddypress' ), $bp->displayed_user->fullname ) );
516
+ } else {
517
+ bp_core_add_message( sprintf( __( 'There was an error deleting %s from the system. Please try again.', 'buddypress' ), $bp->displayed_user->fullname ), 'error' );
518
+ $errors = true;
519
+ }
520
+
521
+ do_action( 'bp_core_action_delete_user', $errors );
522
+
523
+ if ( $errors )
524
+ bp_core_redirect( $bp->displayed_user->domain );
525
+ else
526
+ bp_core_redirect( $bp->loggedin_user->domain );
527
+ }
528
+ }
529
+ add_action( 'wp', 'bp_core_action_delete_user', 3 );
530
+
531
+
532
+ /********************************************************************************
533
+ * Business Functions
534
+ *
535
+ * Business functions are where all the magic happens in BuddyPress. They will
536
+ * handle the actual saving or manipulation of information. Usually they will
537
+ * hand off to a database class for data access, then return
538
+ * true or false on success or failure.
539
+ */
540
+
541
+ /**
542
+ * bp_core_get_users()
543
+ *
544
+ * Return an array of users IDs based on the parameters passed.
545
+ *
546
+ * @package BuddyPress Core
547
+ */
548
+ function bp_core_get_users( $args = '' ) {
549
+ global $bp;
550
+
551
+ $defaults = array(
552
+ 'type' => 'active', // active, newest, alphabetical, random or popular
553
+ 'user_id' => false, // Pass a user_id to limit to only friend connections for this user
554
+ 'search_terms' => false, // Limit to users that match these search terms
555
+
556
+ 'include' => false, // Pass comma separated list of user_ids to limit to only these users
557
+ 'per_page' => 20, // The number of results to return per page
558
+ 'page' => 1, // The page to return if limiting per page
559
+ 'populate_extras' => true, // Fetch the last active, where the user is a friend, total friend count, latest update
560
+ );
561
+
562
+ $params = wp_parse_args( $args, $defaults );
563
+ extract( $params, EXTR_SKIP );
564
+
565
+ return apply_filters( 'bp_core_get_users', BP_Core_User::get_users( $type, $per_page, $page, $user_id, $include, $search_terms, $populate_extras ), &$params );
566
+ }
567
+
568
+ /**
569
+ * bp_core_get_user_domain()
570
+ *
571
+ * Returns the domain for the passed user:
572
+ * e.g. http://domain.com/members/andy/
573
+ *
574
+ * @package BuddyPress Core
575
+ * @global $current_user WordPress global variable containing current logged in user information
576
+ * @param user_id The ID of the user.
577
+ * @uses get_user_meta() WordPress function to get the usermeta for a user.
578
+ */
579
+ function bp_core_get_user_domain( $user_id, $user_nicename = false, $user_login = false ) {
580
+ global $bp;
581
+
582
+ if ( !$user_id ) return;
583
+
584
+ if ( !$domain = wp_cache_get( 'bp_user_domain_' . $user_id, 'bp' ) ) {
585
+ $username = bp_core_get_username( $user_id, $user_nicename, $user_login );
586
+
587
+ /* If we are using a members slug, include it. */
588
+ if ( !defined( 'BP_ENABLE_ROOT_PROFILES' ) )
589
+ $domain = $bp->root_domain . '/' . BP_MEMBERS_SLUG . '/' . $username . '/';
590
+ else
591
+ $domain = $bp->root_domain . '/' . $username . '/';
592
+
593
+ /* Cache the link */
594
+ if ( !empty( $domain ) )
595
+ wp_cache_set( 'bp_user_domain_' . $user_id, $domain, 'bp' );
596
+ }
597
+
598
+ return apply_filters( 'bp_core_get_user_domain', $domain );
599
+ }
600
+
601
+ /**
602
+ * bp_core_get_core_userdata()
603
+ *
604
+ * Fetch everything in the wp_users table for a user, without any usermeta.
605
+ *
606
+ * @package BuddyPress Core
607
+ * @param user_id The ID of the user.
608
+ * @uses BP_Core_User::get_core_userdata() Performs the query.
609
+ */
610
+ function bp_core_get_core_userdata( $user_id ) {
611
+ if ( empty( $user_id ) )
612
+ return false;
613
+
614
+ if ( !$userdata = wp_cache_get( 'bp_core_userdata_' . $user_id, 'bp' ) ) {
615
+ $userdata = BP_Core_User::get_core_userdata( $user_id );
616
+ wp_cache_set( 'bp_core_userdata_' . $user_id, $userdata, 'bp' );
617
+ }
618
+ return apply_filters( 'bp_core_get_core_userdata', $userdata );
619
+ }
620
+
621
+ /**
622
+ * bp_core_get_root_domain()
623
+ *
624
+ * Returns the domain for the root blog.
625
+ * eg: http://domain.com/ OR https://domain.com
626
+ *
627
+ * @package BuddyPress Core
628
+ * @uses get_blog_option() WordPress function to fetch blog meta.
629
+ * @return $domain The domain URL for the blog.
630
+ */
631
+ function bp_core_get_root_domain() {
632
+ global $current_blog;
633
+
634
+ if ( defined( 'BP_ENABLE_MULTIBLOG' ) )
635
+ $domain = get_blog_option( $current_blog->blog_id, 'home' );
636
+ else
637
+ $domain = get_blog_option( BP_ROOT_BLOG, 'home' );
638
+
639
+ return apply_filters( 'bp_core_get_root_domain', $domain );
640
+ }
641
+
642
+ /**
643
+ * bp_core_get_displayed_userid()
644
+ *
645
+ * Returns the user id for the user that is currently being displayed.
646
+ * eg: http://andy.domain.com/ or http://domain.com/andy/
647
+ *
648
+ * @package BuddyPress Core
649
+ * @global $current_blog WordPress global containing information and settings for the current blog being viewed.
650
+ * @uses bp_core_get_userid_from_user_login() Returns the user id for the username passed
651
+ * @return The user id for the user that is currently being displayed, return zero if this is not a user home and just a normal blog.
652
+ */
653
+ function bp_core_get_displayed_userid( $user_login ) {
654
+ return apply_filters( 'bp_core_get_displayed_userid', bp_core_get_userid( $user_login ) );
655
+ }
656
+
657
+ /**
658
+ * bp_core_new_nav_item()
659
+ *
660
+ * Adds a navigation item to the main navigation array used in BuddyPress themes.
661
+ *
662
+ * @package BuddyPress Core
663
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
664
+ */
665
+ function bp_core_new_nav_item( $args = '' ) {
666
+ global $bp;
667
+
668
+ $defaults = array(
669
+ 'name' => false, // Display name for the nav item
670
+ 'slug' => false, // URL slug for the nav item
671
+ 'item_css_id' => false, // The CSS ID to apply to the HTML of the nav item
672
+ 'show_for_displayed_user' => true, // When viewing another user does this nav item show up?
673
+ 'site_admin_only' => false, // Can only site admins see this nav item?
674
+ 'position' => 99, // Index of where this nav item should be positioned
675
+ 'screen_function' => false, // The name of the function to run when clicked
676
+ 'default_subnav_slug' => false // The slug of the default subnav item to select when clicked
677
+ );
678
+
679
+ $r = wp_parse_args( $args, $defaults );
680
+ extract( $r, EXTR_SKIP );
681
+
682
+ /* If we don't have the required info we need, don't create this subnav item */
683
+ if ( empty($name) || empty($slug) )
684
+ return false;
685
+
686
+ /* If this is for site admins only and the user is not one, don't create the subnav item */
687
+ if ( $site_admin_only && !is_super_admin() )
688
+ return false;
689
+
690
+ if ( empty( $item_css_id ) )
691
+ $item_css_id = $slug;
692
+
693
+ $bp->bp_nav[$slug] = array(
694
+ 'name' => $name,
695
+ 'slug' => $slug,
696
+ 'link' => $bp->loggedin_user->domain . $slug . '/',
697
+ 'css_id' => $item_css_id,
698
+ 'show_for_displayed_user' => $show_for_displayed_user,
699
+ 'position' => $position
700
+ );
701
+
702
+ /***
703
+ * If this nav item is hidden for the displayed user, and
704
+ * the logged in user is not the displayed user
705
+ * looking at their own profile, don't create the nav item.
706
+ */
707
+ if ( !$show_for_displayed_user && !bp_user_has_access() )
708
+ return false;
709
+
710
+ /***
711
+ * If we are not viewing a user, and this is a root component, don't attach the
712
+ * default subnav function so we can display a directory or something else.
713
+ */
714
+ if ( bp_core_is_root_component( $slug ) && !$bp->displayed_user->id )
715
+ return;
716
+
717
+ if ( $bp->current_component == $slug && !$bp->current_action ) {
718
+ if ( !is_object( $screen_function[0] ) )
719
+ add_action( 'wp', $screen_function, 3 );
720
+ else
721
+ add_action( 'wp', array( &$screen_function[0], $screen_function[1] ), 3 );
722
+
723
+ if ( $default_subnav_slug )
724
+ $bp->current_action = $default_subnav_slug;
725
+ }
726
+ }
727
+
728
+ /**
729
+ * bp_core_new_nav_default()
730
+ *
731
+ * Modify the default subnav item to load when a top level nav item is clicked.
732
+ *
733
+ * @package BuddyPress Core
734
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
735
+ */
736
+ function bp_core_new_nav_default( $args = '' ) {
737
+ global $bp;
738
+
739
+ $defaults = array(
740
+ 'parent_slug' => false, // Slug of the parent
741
+ 'screen_function' => false, // The name of the function to run when clicked
742
+ 'subnav_slug' => false // The slug of the subnav item to select when clicked
743
+ );
744
+
745
+ $r = wp_parse_args( $args, $defaults );
746
+ extract( $r, EXTR_SKIP );
747
+
748
+ if ( $bp->current_component == $parent_slug && !$bp->current_action ) {
749
+ if ( !is_object( $screen_function[0] ) )
750
+ add_action( 'wp', $screen_function, 3 );
751
+ else
752
+ add_action( 'wp', array( &$screen_function[0], $screen_function[1] ), 3 );
753
+
754
+ if ( $subnav_slug )
755
+ $bp->current_action = $subnav_slug;
756
+ }
757
+ }
758
+
759
+ /**
760
+ * bp_core_sort_nav_items()
761
+ *
762
+ * We can only sort nav items by their position integer at a later point in time, once all
763
+ * plugins have registered their navigation items.
764
+ *
765
+ * @package BuddyPress Core
766
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
767
+ */
768
+ function bp_core_sort_nav_items() {
769
+ global $bp;
770
+
771
+ if ( empty( $bp->bp_nav ) || !is_array( $bp->bp_nav ) )
772
+ return false;
773
+
774
+ foreach ( (array)$bp->bp_nav as $slug => $nav_item ) {
775
+ if ( empty( $temp[$nav_item['position']]) )
776
+ $temp[$nav_item['position']] = $nav_item;
777
+ else {
778
+ // increase numbers here to fit new items in.
779
+ do {
780
+ $nav_item['position']++;
781
+ } while ( !empty( $temp[$nav_item['position']] ) );
782
+
783
+ $temp[$nav_item['position']] = $nav_item;
784
+ }
785
+ }
786
+
787
+ ksort( $temp );
788
+ $bp->bp_nav = &$temp;
789
+ }
790
+ add_action( 'wp_head', 'bp_core_sort_nav_items' );
791
+ add_action( 'admin_head', 'bp_core_sort_nav_items' );
792
+
793
+ /**
794
+ * bp_core_new_subnav_item()
795
+ *
796
+ * Adds a navigation item to the sub navigation array used in BuddyPress themes.
797
+ *
798
+ * @package BuddyPress Core
799
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
800
+ */
801
+ function bp_core_new_subnav_item( $args = '' ) {
802
+ global $bp;
803
+
804
+ $defaults = array(
805
+ 'name' => false, // Display name for the nav item
806
+ 'slug' => false, // URL slug for the nav item
807
+ 'parent_slug' => false, // URL slug of the parent nav item
808
+ 'parent_url' => false, // URL of the parent item
809
+ 'item_css_id' => false, // The CSS ID to apply to the HTML of the nav item
810
+ 'user_has_access' => true, // Can the logged in user see this nav item?
811
+ 'site_admin_only' => false, // Can only site admins see this nav item?
812
+ 'position' => 90, // Index of where this nav item should be positioned
813
+ 'screen_function' => false // The name of the function to run when clicked
814
+ );
815
+
816
+ $r = wp_parse_args( $args, $defaults );
817
+ extract( $r, EXTR_SKIP );
818
+
819
+ /* If we don't have the required info we need, don't create this subnav item */
820
+ if ( empty($name) || empty($slug) || empty($parent_slug) || empty($parent_url) || empty($screen_function) )
821
+ return false;
822
+
823
+ /* If this is for site admins only and the user is not one, don't create the subnav item */
824
+ if ( $site_admin_only && !is_super_admin() )
825
+ return false;
826
+
827
+ if ( empty( $item_css_id ) )
828
+ $item_css_id = $slug;
829
+
830
+ $bp->bp_options_nav[$parent_slug][$slug] = array(
831
+ 'name' => $name,
832
+ 'link' => $parent_url . $slug . '/',
833
+ 'slug' => $slug,
834
+ 'css_id' => $item_css_id,
835
+ 'position' => $position,
836
+ 'user_has_access' => $user_has_access,
837
+ 'screen_function' => $screen_function
838
+ );
839
+
840
+ if ( ( $bp->current_action == $slug && $bp->current_component == $parent_slug ) && $user_has_access ) {
841
+ if ( !is_object( $screen_function[0] ) )
842
+ add_action( 'wp', $screen_function, 3 );
843
+ else
844
+ add_action( 'wp', array( &$screen_function[0], $screen_function[1] ), 3 );
845
+ }
846
+ }
847
+
848
+ function bp_core_sort_subnav_items() {
849
+ global $bp;
850
+
851
+ if ( empty( $bp->bp_options_nav ) || !is_array( $bp->bp_options_nav ) )
852
+ return false;
853
+
854
+ foreach ( (array)$bp->bp_options_nav as $parent_slug => $subnav_items ) {
855
+ if ( !is_array( $subnav_items ) )
856
+ continue;
857
+
858
+ foreach ( (array)$subnav_items as $subnav_item ) {
859
+ if ( empty( $temp[$subnav_item['position']]) )
860
+ $temp[$subnav_item['position']] = $subnav_item;
861
+ else {
862
+ // increase numbers here to fit new items in.
863
+ do {
864
+ $subnav_item['position']++;
865
+ } while ( !empty( $temp[$subnav_item['position']] ) );
866
+
867
+ $temp[$subnav_item['position']] = $subnav_item;
868
+ }
869
+ }
870
+ ksort( $temp );
871
+ $bp->bp_options_nav[$parent_slug] = &$temp;
872
+ unset($temp);
873
+ }
874
+ }
875
+ add_action( 'wp_head', 'bp_core_sort_subnav_items' );
876
+ add_action( 'admin_head', 'bp_core_sort_subnav_items' );
877
+
878
+ /**
879
+ * bp_core_remove_nav_item()
880
+ *
881
+ * Removes a navigation item from the sub navigation array used in BuddyPress themes.
882
+ *
883
+ * @package BuddyPress Core
884
+ * @param $parent_id The id of the parent navigation item.
885
+ * @param $slug The slug of the sub navigation item.
886
+ */
887
+ function bp_core_remove_nav_item( $parent_id ) {
888
+ global $bp;
889
+
890
+ /* Unset subnav items for this nav item */
891
+ if ( is_array( $bp->bp_options_nav[$parent_id] ) ) {
892
+ foreach( (array)$bp->bp_options_nav[$parent_id] as $subnav_item ) {
893
+ bp_core_remove_subnav_item( $parent_id, $subnav_item['slug'] );
894
+ }
895
+ }
896
+
897
+ unset( $bp->bp_nav[$parent_id] );
898
+ }
899
+
900
+ /**
901
+ * bp_core_remove_subnav_item()
902
+ *
903
+ * Removes a navigation item from the sub navigation array used in BuddyPress themes.
904
+ *
905
+ * @package BuddyPress Core
906
+ * @param $parent_id The id of the parent navigation item.
907
+ * @param $slug The slug of the sub navigation item.
908
+ */
909
+ function bp_core_remove_subnav_item( $parent_id, $slug ) {
910
+ global $bp;
911
+
912
+ $screen_function = $bp->bp_options_nav[$parent_id][$slug]['screen_function'];
913
+
914
+ if ( $screen_function ) {
915
+ if ( !is_object( $screen_function[0] ) )
916
+ remove_action( 'wp', $screen_function, 3 );
917
+ else
918
+ remove_action( 'wp', array( &$screen_function[0], $screen_function[1] ), 3 );
919
+ }
920
+
921
+ unset( $bp->bp_options_nav[$parent_id][$slug] );
922
+
923
+ if ( !count( $bp->bp_options_nav[$parent_id] ) )
924
+ unset($bp->bp_options_nav[$parent_id]);
925
+ }
926
+
927
+ /**
928
+ * bp_core_reset_subnav_items()
929
+ *
930
+ * Clear the subnav items for a specific nav item.
931
+ *
932
+ * @package BuddyPress Core
933
+ * @param $parent_id The id of the parent navigation item.
934
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
935
+ */
936
+ function bp_core_reset_subnav_items($parent_slug) {
937
+ global $bp;
938
+
939
+ unset($bp->bp_options_nav[$parent_slug]);
940
+ }
941
+
942
+ /**
943
+ * bp_core_load_template()
944
+ *
945
+ * Uses the bp_catch_uri function to load a specific template file with fallback support.
946
+ *
947
+ * Example:
948
+ * bp_core_load_template( 'profile/edit-profile' );
949
+ * Loads:
950
+ * wp-content/themes/[activated_theme]/profile/edit-profile.php
951
+ *
952
+ * @package BuddyPress Core
953
+ * @param $username str Username to check.
954
+ * @return false on no match
955
+ * @return int the user ID of the matched user.
956
+ */
957
+ function bp_core_load_template( $template, $skip_blog_check = false ) {
958
+ return bp_catch_uri( $template, $skip_blog_check );
959
+ }
960
+
961
+ /**
962
+ * bp_core_add_root_component()
963
+ *
964
+ * Adds a component to the $bp->root_components global.
965
+ * Any component that runs in the "root" of an install should be added.
966
+ * The "root" as in, it can or always runs outside of the /members/username/ path.
967
+ *
968
+ * Example of a root component:
969
+ * Groups: http://domain.com/groups/group-name
970
+ * http://community.domain.com/groups/group-name
971
+ * http://domain.com/wpmu/groups/group-name
972
+ *
973
+ * Example of a component that is NOT a root component:
974
+ * F