PluginProbe
bbPress / 2.6.6
bbPress v2.6.6
2.6.17 trunk 2.0 2.0-beta-1 2.0-beta-2b 2.0-beta-3 2.0-beta-3b 2.0-rc-2 2.0-rc-3 2.0-rc-4 2.0-rc-5 2.0.1 2.0.2 2.0.3 2.1 2.1-beta-1 2.1-rc1 2.1-rc2 2.1-rc3 2.1-rc4 2.1.1 2.1.2 2.1.3 2.2 2.2.1 All 72 releases
← All changes | includes/users/functions.php +628 -801 2.2.12.6.6 View file →
@@ -7,38 +7,35 @@
7 7 * @subpackage Functions
8 8 */
9 9
10 10 // Exit if accessed directly
11 -if ( !defined( 'ABSPATH' ) ) exit;
11 +defined( 'ABSPATH' ) || exit;
12 12
13 13 /**
14 14 * Redirect back to $url when attempting to use the login page
15 15 *
16 - * @since bbPress (r2815)
16 + * @since 2.0.0 bbPress (r2815)
17 17 *
18 18 * @param string $url The url
19 19 * @param string $raw_url Raw url
20 20 * @param object $user User object
21 - * @uses is_wp_error() To check if the user param is a {@link WP_Error}
22 - * @uses admin_url() To get the admin url
23 - * @uses home_url() To get the home url
24 - * @uses esc_url() To escape the url
25 - * @uses wp_safe_redirect() To redirect
26 21 */
27 22 function bbp_redirect_login( $url = '', $raw_url = '', $user = '' ) {
28 23
29 24 // Raw redirect_to was passed, so use it
30 - if ( !empty( $raw_url ) )
25 + if ( ! empty( $raw_url ) ) {
31 26 $url = $raw_url;
32 27
33 28 // $url was manually set in wp-login.php to redirect to admin
34 - elseif ( admin_url() == $url )
29 + } elseif ( admin_url() === $url ) {
35 30 $url = home_url();
36 31
37 32 // $url is empty
38 - elseif ( empty( $url ) )
33 + } elseif ( empty( $url ) ) {
39 34 $url = home_url();
35 + }
40 36
37 + // Filter & return
41 38 return apply_filters( 'bbp_redirect_login', $url, $raw_url, $user );
42 39 }
43 40
44 41 /**
@@ -43,54 +40,47 @@
43 40
44 41 /**
45 42 * Is an anonymous topic/reply being made?
46 43 *
47 - * @since bbPres (r2688)
44 + * @since 2.0.0 bbPress (r2688)
48 45 *
49 - * @uses is_user_logged_in() Is the user logged in?
50 - * @uses bbp_allow_anonymous() Is anonymous posting allowed?
51 - * @uses apply_filters() Calls 'bbp_is_anonymous' with the return value
52 46 * @return bool True if anonymous is allowed and user is not logged in, false if
53 47 * anonymous is not allowed or user is logged in
54 48 */
55 49 function bbp_is_anonymous() {
56 - if ( !is_user_logged_in() && bbp_allow_anonymous() )
57 - $is_anonymous = true;
58 - else
59 - $is_anonymous = false;
50 + $is_anonymous = ( ! is_user_logged_in() && bbp_allow_anonymous() );
60 51
61 - return apply_filters( 'bbp_is_anonymous', $is_anonymous );
52 + // Filter & return
53 + return (bool) apply_filters( 'bbp_is_anonymous', $is_anonymous );
62 54 }
63 55
64 56 /**
65 57 * Echoes the values for current poster (uses WP comment cookies)
66 58 *
67 - * @since bbPress (r2734)
59 + * @since 2.0.0 bbPress (r2734)
68 60 *
69 61 * @param string $key Which value to echo?
70 - * @uses bbp_get_current_anonymous_user_data() To get the current anonymous user
71 - * data
72 62 */
73 63 function bbp_current_anonymous_user_data( $key = '' ) {
74 - echo bbp_get_current_anonymous_user_data( $key );
64 + echo esc_attr( bbp_get_current_anonymous_user_data( $key ) );
75 65 }
76 66
77 67 /**
78 68 * Get the cookies for current poster (uses WP comment cookies).
79 69 *
80 - * @since bbPress (r2734)
70 + * @since 2.0.0 bbPress (r2734)
81 71 *
82 72 * @param string $key Optional. Which value to get? If not given, then
83 73 * an array is returned.
84 - * @uses sanitize_comment_cookies() To sanitize the current poster data
85 - * @uses wp_get_current_commenter() To get the current poster data *
86 74 * @return string|array Cookie(s) for current poster
87 75 */
88 76 function bbp_get_current_anonymous_user_data( $key = '' ) {
77 +
78 + // Array of allowed cookie names
89 79 $cookie_names = array(
90 - 'name' => 'comment_author',
91 - 'email' => 'comment_author_email',
92 - 'website' => 'comment_author_url',
80 + 'name' => 'comment_author',
81 + 'email' => 'comment_author_email',
82 + 'url' => 'comment_author_url',
93 83
94 84 // Here just for the sake of them, use the above ones
95 85 'comment_author' => 'comment_author',
96 86 'comment_author_email' => 'comment_author_email',
@@ -96,15 +86,20 @@
96 86 'comment_author_email' => 'comment_author_email',
97 87 'comment_author_url' => 'comment_author_url',
98 88 );
99 89
100 - sanitize_comment_cookies();
90 + // Get the current poster's info from the cookies
91 + $bbp_current_poster = wp_get_current_commenter();
101 92
102 - $bbp_current_poster = wp_get_current_commenter();
93 + // Sanitize the cookie key being retrieved
94 + $key = sanitize_key( $key );
103 95
104 - if ( !empty( $key ) && in_array( $key, array_keys( $cookie_names ) ) )
105 - return $bbp_current_poster[$cookie_names[$key]];
96 + // Maybe return a specific key
97 + if ( ! empty( $key ) && in_array( $key, array_keys( $cookie_names ), true ) ) {
98 + return $bbp_current_poster[ $cookie_names[ $key ] ];
99 + }
106 100
101 + // Return all keys
107 102 return $bbp_current_poster;
108 103 }
109 104
110 105 /**
@@ -109,972 +104,734 @@
109 104
110 105 /**
111 106 * Set the cookies for current poster (uses WP comment cookies)
112 107 *
113 - * @since bbPress (r2734)
108 + * @since 2.0.0 bbPress (r2734)
114 109 *
115 - * @param array $anonymous_data With keys 'bbp_anonymous_name',
116 - * 'bbp_anonymous_email', 'bbp_anonymous_website'.
117 - * Should be sanitized (see
118 - * {@link bbp_filter_anonymous_post_data()} for
119 - * sanitization)
120 - * @uses apply_filters() Calls 'comment_cookie_lifetime' for cookie lifetime.
121 - * Defaults to 30000000.
110 + * @param array $anonymous_data Optional - if it's an anonymous post. Do not
111 + * supply if supplying $author_id. Should be
112 + * sanitized (see {@link bbp_filter_anonymous_post_data()}
122 113 */
123 114 function bbp_set_current_anonymous_user_data( $anonymous_data = array() ) {
124 - if ( empty( $anonymous_data ) || !is_array( $anonymous_data ) )
115 +
116 + // Bail if empty or not an array
117 + if ( empty( $anonymous_data ) || ! is_array( $anonymous_data ) ) {
125 118 return;
119 + }
126 120
127 - $comment_cookie_lifetime = apply_filters( 'comment_cookie_lifetime', 30000000 );
121 + // Setup cookie expiration
122 + $lifetime = (int) apply_filters( 'comment_cookie_lifetime', 30000000 );
123 + $expiry = time() + $lifetime;
124 + $secure = ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) );
128 125
129 - setcookie( 'comment_author_' . COOKIEHASH, $anonymous_data['bbp_anonymous_name'], time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN );
130 - setcookie( 'comment_author_email_' . COOKIEHASH, $anonymous_data['bbp_anonymous_email'], time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN );
131 - setcookie( 'comment_author_url_' . COOKIEHASH, $anonymous_data['bbp_anonymous_website'], time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN );
126 + // Set the cookies
127 + setcookie( 'comment_author_' . COOKIEHASH, $anonymous_data['bbp_anonymous_name'], $expiry, COOKIEPATH, COOKIE_DOMAIN, $secure );
128 + setcookie( 'comment_author_email_' . COOKIEHASH, $anonymous_data['bbp_anonymous_email'], $expiry, COOKIEPATH, COOKIE_DOMAIN, $secure );
129 + setcookie( 'comment_author_url_' . COOKIEHASH, $anonymous_data['bbp_anonymous_website'], $expiry, COOKIEPATH, COOKIE_DOMAIN, $secure );
132 130 }
133 131
134 132 /**
135 133 * Get the poster IP address
136 134 *
137 - * @since bbPress (r3120)
135 + * @since 2.0.0 bbPress (r3120)
136 + * @since 2.6.0 bbPress (r5609) Added `empty()` check for unit tests
138 137 *
139 138 * @return string
140 139 */
141 140 function bbp_current_author_ip() {
142 - $retval = preg_replace( '/[^0-9a-fA-F:., ]/', '', $_SERVER['REMOTE_ADDR'] );
143 141
144 - return apply_filters( 'bbp_current_author_ip', $retval );
142 + // Check for remote address
143 + $remote_address = ! empty( $_SERVER['REMOTE_ADDR'] )
144 + ? wp_unslash( $_SERVER['REMOTE_ADDR'] )
145 + : '127.0.0.1';
146 +
147 + // Remove any unsavory bits
148 + $retval = preg_replace( '/[^0-9a-fA-F:., ]/', '', $remote_address );
149 +
150 + // Filter & return
151 + return apply_filters( 'bbp_current_author_ip', $retval, $remote_address );
145 152 }
146 153
147 154 /**
148 155 * Get the poster user agent
149 156 *
150 - * @since bbPress (r3446)
157 + * @since 2.0.0 bbPress (r3446)
151 158 *
152 159 * @return string
153 160 */
154 161 function bbp_current_author_ua() {
155 - $retval = !empty( $_SERVER['HTTP_USER_AGENT'] ) ? substr( $_SERVER['HTTP_USER_AGENT'], 0, 254 ) : '';
162 + $retval = ! empty( $_SERVER['HTTP_USER_AGENT'] )
163 + ? mb_substr( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ), 0, 254 )
164 + : '';
156 165
166 + // Filter & return
157 167 return apply_filters( 'bbp_current_author_ua', $retval );
158 168 }
159 169
160 -/** Post Counts ***************************************************************/
170 +/** Edit **********************************************************************/
161 171
162 172 /**
163 - * Return the raw database count of topics by a user
173 + * Handles the front end user editing from POST requests
164 174 *
165 - * @since bbPress (r3633)
166 - * @global WPDB $wpdb
167 - * @uses bbp_get_user_id()
168 - * @uses get_posts_by_author_sql()
169 - * @uses bbp_get_topic_post_type()
170 - * @uses apply_filters()
171 - * @return int Raw DB count of topics
175 + * @since 2.0.0 bbPress (r2790)
176 + *
177 + * @param string $action The requested action to compare this function to
172 178 */
173 -function bbp_get_user_topic_count_raw( $user_id = 0 ) {
174 - $user_id = bbp_get_user_id( $user_id );
175 - if ( empty( $user_id ) )
176 - return false;
179 +function bbp_edit_user_handler( $action = '' ) {
177 180
178 - global $wpdb;
181 + // Bail if action is not `bbp-update-user`
182 + if ( 'bbp-update-user' !== $action ) {
183 + return;
184 + }
179 185
180 - $where = get_posts_by_author_sql( bbp_get_topic_post_type(), true, $user_id );
181 - $count = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->posts} {$where}" );
186 + // Bail if in wp-admin
187 + if ( is_admin() ) {
188 + return;
189 + }
182 190
183 - return (int) apply_filters( 'bbp_get_user_topic_count_raw', $count, $user_id );
184 -}
191 + // Get the displayed user ID
192 + $user_id = bbp_get_displayed_user_id();
185 193
186 -/**
187 - * Return the raw database count of replies by a user
188 - *
189 - * @since bbPress (r3633)
190 - * @global WPDB $wpdb
191 - * @uses bbp_get_user_id()
192 - * @uses get_posts_by_author_sql()
193 - * @uses bbp_get_reply_post_type()
194 - * @uses apply_filters()
195 - * @return int Raw DB count of replies
196 - */
197 -function bbp_get_user_reply_count_raw( $user_id = 0 ) {
198 - $user_id = bbp_get_user_id( $user_id );
199 - if ( empty( $user_id ) )
200 - return false;
194 + // Nonce check
195 + if ( ! bbp_verify_nonce_request( 'update-user_' . $user_id ) ) {
196 + bbp_add_error( 'bbp_update_user_nonce', __( '<strong>Error</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
197 + return;
198 + }
201 199
202 - global $wpdb;
200 + // Cap check
201 + if ( ! current_user_can( 'edit_user', $user_id ) ) {
202 + bbp_add_error( 'bbp_update_user_capability', __( '<strong>Error</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
203 + return;
204 + }
203 205
204 - $where = get_posts_by_author_sql( bbp_get_reply_post_type(), true, $user_id );
205 - $count = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->posts} {$where}" );
206 + // Empty email check
207 + if ( empty( $_POST['email'] ) ) {
208 + bbp_add_error( 'bbp_user_email_empty', __( '<strong>Error</strong>: That is not a valid email address.', 'bbpress' ), array( 'form-field' => 'email' ) );
209 + return;
210 + }
206 211
207 - return (int) apply_filters( 'bbp_get_user_reply_count_raw', $count, $user_id );
208 -}
212 + // Get the users current email address to use for comparisons
213 + $user_email = bbp_get_displayed_user_field( 'user_email', 'raw' );
209 214
210 -/** Favorites *****************************************************************/
215 + // Bail if no email change
216 + if ( $user_email !== $_POST['email'] ) {
211 217
212 -/**
213 - * Get the users who have made the topic favorite
214 - *
215 - * @since bbPress (r2658)
216 - *
217 - * @param int $topic_id Optional. Topic id
218 - * @uses wpdb::get_col() To execute our query and get the column back
219 - * @uses apply_filters() Calls 'bbp_get_topic_favoriters' with the users and
220 - * topic id
221 - * @return array|bool Results if the topic has any favoriters, otherwise false
222 - */
223 -function bbp_get_topic_favoriters( $topic_id = 0 ) {
224 - if ( empty( $topic_id ) )
225 - return;
218 + // Check that new email address is valid
219 + if ( ! is_email( $_POST['email'] ) ) {
220 + bbp_add_error( 'bbp_user_email_invalid', __( '<strong>Error</strong>: That is not a valid email address.', 'bbpress' ), array( 'form-field' => 'email' ) );
221 + return;
222 + }
226 223
227 - global $wpdb;
224 + // Check if email address is already in use
225 + if ( email_exists( $_POST['email'] ) ) {
226 + bbp_add_error( 'bbp_user_email_taken', __( '<strong>Error</strong>: That email address is already in use.', 'bbpress' ), array( 'form-field' => 'email' ) );
227 + return;
228 + }
228 229
229 - // Get the users who have favorited the topic
230 - $key = $wpdb->prefix . '_bbp_favorites';
231 - $users = $wpdb->get_col( "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = '{$key}' and FIND_IN_SET('{$topic_id}', meta_value) > 0" );
232 - $users = apply_filters( 'bbp_get_topic_favoriters', $users, $topic_id );
230 + // Update the option
231 + $option = array(
232 + 'hash' => md5( $_POST['email'] . time() . wp_rand() ),
233 + 'newemail' => $_POST['email'],
234 + );
235 + update_user_meta( $user_id, '_new_email', $option );
233 236
234 - if ( !empty( $users ) )
235 - return $users;
237 + // Attempt to notify the user of email address change
238 + bbp_edit_user_email_send_notification( $user_id, $option );
236 239
237 - return false;
238 -}
240 + // Set the POST email variable back to the user's email address
241 + // so `edit_user()` does not attempt to update it. This is not ideal,
242 + // but it's also what send_confirmation_on_profile_email() does.
243 + $_POST['email'] = $user_email;
244 + }
239 245
240 -/**
241 - * Get a user's favorite topics
242 - *
243 - * @since bbPress (r2652)
244 - *
245 - * @param int $user_id Optional. User id
246 - * @uses bbp_get_user_favorites_topic_ids() To get the user's favorites
247 - * @uses bbp_has_topics() To get the topics
248 - * @uses apply_filters() Calls 'bbp_get_user_favorites' with the topic query and
249 - * user id
250 - * @return array|bool Results if user has favorites, otherwise false
251 - */
252 -function bbp_get_user_favorites( $user_id = 0 ) {
253 - $user_id = bbp_get_user_id( $user_id );
254 - if ( empty( $user_id ) )
255 - return false;
246 + // Do action based on who's profile you're editing
247 + $edit_action = bbp_is_user_home_edit()
248 + ? 'personal_options_update'
249 + : 'edit_user_profile_update';
256 250
257 - // If user has favorites, load them
258 - $favorites = bbp_get_user_favorites_topic_ids( $user_id );
259 - if ( !empty( $favorites ) ) {
251 + do_action( $edit_action, $user_id );
260 252
261 - // Setup the topics query
262 - $topics_query = bbp_has_topics( array( 'post__in' => $favorites ) );
253 + // Prevent edit_user() from wiping out the user's Toolbar on front setting
254 + if ( ! isset( $_POST['admin_bar_front'] ) && _get_admin_bar_pref( 'front', $user_id ) ) {
255 + $_POST['admin_bar_front'] = 1;
256 + }
263 257
264 - return apply_filters( 'bbp_get_user_favorites', $topics_query, $user_id );
258 + // Bail if errors already exist
259 + if ( bbp_has_errors() ) {
260 + return;
265 261 }
266 262
267 - return false;
268 -}
263 + // Handle user edit
264 + $edit_user = edit_user( $user_id );
269 265
270 -/**
271 - * Get a user's favorite topics' ids
272 - *
273 - * @since bbPress (r2652)
274 - *
275 - * @param int $user_id Optional. User id
276 - * @uses bbp_get_user_id() To get the user id
277 - * @uses get_user_option() To get the user favorites
278 - * @uses apply_filters() Calls 'bbp_get_user_favorites_topic_ids' with
279 - * the favorites and user id
280 - * @return array|bool Results if user has favorites, otherwise false
281 - */
282 -function bbp_get_user_favorites_topic_ids( $user_id = 0 ) {
283 - $user_id = bbp_get_user_id( $user_id );
284 - if ( empty( $user_id ) )
285 - return false;
266 + // Error(s) editng the user, so copy them into the global
267 + if ( is_wp_error( $edit_user ) ) {
268 + bbpress()->errors = $edit_user;
286 269
287 - $favorites = (string) get_user_option( '_bbp_favorites', $user_id );
288 - $favorites = (array) explode( ',', $favorites );
289 - $favorites = array_filter( $favorites );
270 + // Successful edit to redirect
271 + } elseif ( is_integer( $edit_user ) ) {
290 272
291 - return apply_filters( 'bbp_get_user_favorites_topic_ids', $favorites, $user_id );
273 + // Maybe update super admin ability
274 + if ( is_multisite() && ! bbp_is_user_home_edit() && current_user_can( 'manage_network_options' ) && is_super_admin() ) {
275 + empty( $_POST['super_admin'] )
276 + ? revoke_super_admin( $edit_user )
277 + : grant_super_admin( $edit_user );
278 + }
279 +
280 + // Redirect
281 + $args = array( 'updated' => 'true' );
282 + $user_url = bbp_get_user_profile_edit_url( $edit_user );
283 + $redirect = add_query_arg( $args, $user_url );
284 +
285 + bbp_redirect( $redirect );
286 + }
292 287 }
293 288
294 289 /**
295 - * Check if a topic is in user's favorites or not
290 + * Handles user email address updating from GET requests
296 291 *
297 - * @since bbPress (r2652)
292 + * @since 2.6.0 bbPress (r5660)
298 293 *
299 - * @param int $user_id Optional. User id
300 - * @param int $topic_id Optional. Topic id
301 - * @uses bbp_get_user_id() To get the user id
302 - * @uses bbp_get_user_favorites_topic_ids() To get the user favorites
303 - * @uses bbp_get_topic() To get the topic
304 - * @uses bbp_get_topic_id() To get the topic id
305 - * @uses apply_filters() Calls 'bbp_is_user_favorite' with the bool, user id,
306 - * topic id and favorites
307 - * @return bool True if the topic is in user's favorites, otherwise false
294 + * @param string $action
308 295 */
309 -function bbp_is_user_favorite( $user_id = 0, $topic_id = 0 ) {
296 +function bbp_user_email_change_handler( $action = '' ) {
310 297
311 - $user_id = bbp_get_user_id( $user_id, true, true );
312 - if ( empty( $user_id ) )
313 - return false;
298 + // Bail if action is not `bbp-update-user-email`
299 + if ( 'bbp-update-user-email' !== $action ) {
300 + return;
301 + }
314 302
315 - $retval = false;
316 - $favorites = bbp_get_user_favorites_topic_ids( $user_id );
303 + // Bail if not on users own profile
304 + if ( ! bbp_is_user_home_edit() ) {
305 + return;
306 + }
317 307
318 - if ( !empty( $favorites ) ) {
319 -
320 - // Checking a specific topic id
321 - if ( !empty( $topic_id ) ) {
322 - $topic = bbp_get_topic( $topic_id );
323 - $topic_id = !empty( $topic ) ? $topic->ID : 0;
308 + // Bail if not attempting to modify user email address
309 + if ( empty( $_GET['newuseremail'] ) && empty( $_GET['dismiss'] ) ) {
310 + return;
311 + }
324 312
325 - // Using the global topic id
326 - } elseif ( bbp_get_topic_id() ) {
327 - $topic_id = bbp_get_topic_id();
313 + // Get the displayed user ID & option key
314 + $user_id = bbp_get_displayed_user_id();
315 + $key = '_new_email';
316 + $redirect_to = bbp_get_user_profile_edit_url( $user_id );
328 317
329 - // Use the current post id
330 - } elseif ( !bbp_get_topic_id() ) {
331 - $topic_id = get_the_ID();
318 + // Execute confirmed email change.
319 + if ( ! empty( $_GET['newuseremail'] ) ) {
320 +
321 + // Check for email address change option
322 + $new_email = get_user_meta( $user_id, $key, true );
323 +
324 + // Redirect if *no* email address change exists
325 + if ( false === $new_email ) {
326 + bbp_redirect( $redirect_to );
332 327 }
333 328
334 - // Is topic_id in the user's favorites
335 - if ( !empty( $topic_id ) ) {
336 - $retval = in_array( $topic_id, $favorites );
329 + // Cleanup & redirect if *invalid* email address change exists
330 + if ( empty( $new_email['hash'] ) || empty( $new_email['newemail'] ) ) {
331 + delete_user_meta( $user_id, $key );
332 +
333 + bbp_redirect( $redirect_to );
337 334 }
338 - }
339 335
340 - return (bool) apply_filters( 'bbp_is_user_favorite', (bool) $retval, $user_id, $topic_id, $favorites );
341 -}
336 + // Compare hashes, and update user if hashes match
337 + if ( hash_equals( $new_email['hash'], $_GET['newuseremail'] ) ) {
342 338
343 -/**
344 - * Add a topic to user's favorites
345 - *
346 - * @since bbPress (r2652)
347 - *
348 - * @param int $user_id Optional. User id
349 - * @param int $topic_id Optional. Topic id
350 - * @uses bbp_get_user_favorites_topic_ids() To get the user favorites
351 - * @uses update_user_option() To update the user favorites
352 - * @uses do_action() Calls 'bbp_add_user_favorite' with the user id and topic id
353 - * @return bool Always true
354 - */
355 -function bbp_add_user_favorite( $user_id = 0, $topic_id = 0 ) {
356 - if ( empty( $user_id ) || empty( $topic_id ) )
357 - return false;
339 + // Does another user have this email address already?
340 + if ( email_exists( $new_email['newemail'] ) ) {
341 + delete_user_meta( $user_id, $key );
358 342
359 - $favorites = (array) bbp_get_user_favorites_topic_ids( $user_id );
360 - $topic = bbp_get_topic( $topic_id );
361 - if ( empty( $topic ) )
362 - return false;
343 + bbp_add_error( 'bbp_user_email_taken', __( '<strong>Error</strong>: That email address is already in use.', 'bbpress' ), array( 'form-field' => 'email' ) );
363 344
364 - if ( !in_array( $topic_id, $favorites ) ) {
365 - $favorites[] = $topic_id;
366 - $favorites = array_filter( $favorites );
367 - $favorites = (string) implode( ',', $favorites );
368 - update_user_option( $user_id, '_bbp_favorites', $favorites );
369 - }
345 + // Email address is good to change to
346 + } else {
370 347
371 - do_action( 'bbp_add_user_favorite', $user_id, $topic_id );
348 + // Create a stdClass (for easy call to wp_update_user())
349 + $user = new stdClass();
350 + $user->ID = $user_id;
351 + $user->user_email = esc_html( trim( $new_email['newemail'] ) );
372 352
373 - return true;
374 -}
353 + // Attempt to update user email
354 + $update_user = wp_update_user( $user );
375 355
376 -/**
377 - * Remove a topic from user's favorites
378 - *
379 - * @since bbPress (r2652)
380 - *
381 - * @param int $user_id Optional. User id
382 - * @param int $topic_id Optional. Topic id
383 - * @uses bbp_get_user_favorites_topic_ids() To get the user favorites
384 - * @uses update_user_option() To update the user favorites
385 - * @uses delete_user_option() To delete the user favorites meta
386 - * @uses do_action() Calls 'bbp_remove_user_favorite' with the user & topic id
387 - * @return bool True if the topic was removed from user's favorites, otherwise
388 - * false
389 - */
390 -function bbp_remove_user_favorite( $user_id, $topic_id ) {
391 - if ( empty( $user_id ) || empty( $topic_id ) )
392 - return false;
356 + // Error(s) editing the user, so copy them into the global
357 + if ( is_wp_error( $update_user ) ) {
358 + bbpress()->errors = $update_user;
393 359
394 - $favorites = (array) bbp_get_user_favorites_topic_ids( $user_id );
395 - if ( empty( $favorites ) )
396 - return false;
360 + // All done, so redirect and show the updated message
361 + } else {
397 362
398 - $pos = array_search( $topic_id, $favorites );
399 - if ( is_numeric( $pos ) ) {
400 - array_splice( $favorites, $pos, 1 );
401 - $favorites = array_filter( $favorites );
363 + // Update signups table, if signups table & entry exists
364 + // For Multisite & BuddyPress compatibility
365 + $bbp_db = bbp_db();
366 + if ( ! empty( $bbp_db->signups ) && $bbp_db->get_var( $bbp_db->prepare( "SELECT user_login FROM {$bbp_db->signups} WHERE user_login = %s", bbp_get_displayed_user_field( 'user_login', 'raw' ) ) ) ) {
367 + $bbp_db->query( $bbp_db->prepare( "UPDATE {$bbp_db->signups} SET user_email = %s WHERE user_login = %s", $user->user_email, bbp_get_displayed_user_field( 'user_login', 'raw' ) ) );
368 + }
402 369
403 - if ( !empty( $favorites ) ) {
404 - $favorites = implode( ',', $favorites );
405 - update_user_option( $user_id, '_bbp_favorites', $favorites );
406 - } else {
407 - delete_user_option( $user_id, '_bbp_favorites' );
370 + delete_user_meta( $user_id, $key );
371 +
372 + bbp_redirect( add_query_arg( array( 'updated' => 'true' ), $redirect_to ) );
373 + }
374 + }
408 375 }
409 - }
410 376
411 - do_action( 'bbp_remove_user_favorite', $user_id, $topic_id );
377 + // Delete new email address from user options
378 + } elseif ( ! empty( $_GET['dismiss'] ) && ( "{$user_id}{$key}" === $_GET['dismiss'] ) ) {
379 + if ( ! bbp_verify_nonce_request( "dismiss-{$user_id}{$key}" ) ) {
380 + bbp_add_error( 'bbp_dismiss_new_email_nonce', __( '<strong>Error</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
381 + return;
382 + }
412 383
413 - return true;
384 + delete_user_meta( $user_id, $key );
385 + bbp_redirect( $redirect_to );
386 + }
414 387 }
415 388
416 389 /**
417 - * Handles the front end adding and removing of favorite topics
390 + * Sends an email when an email address change occurs on POST requests
418 391 *
419 - * @uses bbp_get_user_id() To get the user id
420 - * @uses bbp_verify_nonce_request() To verify the nonce and check the request
421 - * @uses current_user_can() To check if the current user can edit the user
422 - * @uses bbPress:errors:add() To log the error messages
423 - * @uses bbp_is_user_favorite() To check if the topic is in user's favorites
424 - * @uses bbp_remove_user_favorite() To remove the user favorite
425 - * @uses bbp_add_user_favorite() To add the user favorite
426 - * @uses do_action() Calls 'bbp_favorites_handler' with success, user id, topic
427 - * id and action
428 - * @uses bbp_is_favorites() To check if it's the favorites page
429 - * @uses bbp_get_favorites_link() To get the favorites page link
430 - * @uses bbp_get_topic_permalink() To get the topic permalink
431 - * @uses wp_safe_redirect() To redirect to the url
392 + * @since 2.6.0 bbPress (r5660)
393 + *
394 + * @see send_confirmation_on_profile_email()
432 395 */
433 -function bbp_favorites_handler() {
396 +function bbp_edit_user_email_send_notification( $user_id = 0, $args = array() ) {
434 397
435 - if ( !bbp_is_favorites_active() )
436 - return false;
398 + // Parse args
399 + $r = bbp_parse_args( $args, array(
400 + 'hash' => '',
401 + 'newemail' => '',
402 + ) );
437 403
438 - // Bail if not a GET action
439 - if ( 'GET' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
404 + // Bail if any relevant parameters are empty
405 + if ( empty( $user_id ) || empty( $r['hash'] ) || empty( $r['newemail'] ) ) {
406 + bbp_add_error( 'bbp_user_email_invalid_hash', __( '<strong>Error</strong>: An error occurred while updating your email address.', 'bbpress' ), array( 'form-field' => 'email' ) );
440 407 return;
408 + }
441 409
442 - // Bail if required GET actions aren't passed
443 - if ( empty( $_GET['topic_id'] ) || empty( $_GET['action'] ) )
444 - return;
410 + // Build the nonced URL to dismiss the pending change
411 + $user_login = bbp_get_displayed_user_field( 'user_login', 'raw' );
412 + $user_url = bbp_get_user_profile_edit_url( $user_id );
413 + $confirm_url = add_query_arg( array(
414 + 'action' => 'bbp-update-user-email',
415 + 'newuseremail' => $r['hash']
416 + ), $user_url );
445 417
446 - // Setup possible get actions
447 - $possible_actions = array(
448 - 'bbp_favorite_add',
449 - 'bbp_favorite_remove',
450 - );
418 + $email_text = __( '%1$s
451 419
452 - // Bail if actions aren't meant for this function
453 - if ( !in_array( $_GET['action'], $possible_actions ) )
454 - return;
420 +Someone requested a change to the email address on your account.
455 421
456 - // What action is taking place?
457 - $action = $_GET['action'];
458 - $topic_id = intval( $_GET['topic_id'] );
459 - $user_id = bbp_get_user_id( 0, true, true );
422 +Please click the following link to confirm this change:
423 +%2$s
460 424
461 - // Check for empty topic
462 - if ( empty( $topic_id ) ) {
463 - bbp_add_error( 'bbp_favorite_topic_id', __( '<strong>ERROR</strong>: No topic was found! Which topic are you marking/unmarking as favorite?', 'bbpress' ) );
425 +If you did not request this, you can safely ignore and delete this notification.
464 426
465 - // Check nonce
466 - } elseif ( ! bbp_verify_nonce_request( 'toggle-favorite_' . $topic_id ) ) {
467 - bbp_add_error( 'bbp_favorite_nonce', __( '<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
427 +This email was sent to: %3$s
468 428
469 - // Check current user's ability to edit the user
470 - } elseif ( !current_user_can( 'edit_user', $user_id ) ) {
471 - bbp_add_error( 'bbp_favorite_permissions', __( '<strong>ERROR</strong>: You don\'t have the permission to edit favorites of that user!', 'bbpress' ) );
472 - }
429 +Regards,
430 +The %4$s Team
431 +%5$s', 'bbpress' );
473 432
474 - // Bail if errors
475 - if ( bbp_has_errors() )
476 - return;
433 + /**
434 + * Filter the email text sent when a user changes emails.
435 + *
436 + * The following strings have a special meaning and will get replaced dynamically:
437 + *
438 + * %1$s - The current user's username
439 + * %2$s - The link to click on to confirm the email change
440 + * %3$s - The new email
441 + * %4$s - The name of the site
442 + * %5$s - The URL to the site
443 + *
444 + * @param string $email_text Text in the email.
445 + * @param string $r New user email that the current user has changed to.
446 + */
447 + $content = apply_filters( 'bbp_user_email_update_content', $email_text, $r );
477 448
478 - /** No errors *************************************************************/
449 + // Build the email message
450 + $message = sprintf( $content, $user_login, $confirm_url, $r['newemail'], get_site_option( 'site_name' ), network_home_url() );
479 451
480 - $is_favorite = bbp_is_user_favorite( $user_id, $topic_id );
481 - $success = false;
452 + // Build the email subject
453 + $subject = sprintf( __( '[%s] New Email Address', 'bbpress' ), wp_specialchars_decode( get_option( 'blogname' ) ) );
482 454
483 - if ( true == $is_favorite && 'bbp_favorite_remove' == $action )
484 - $success = bbp_remove_user_favorite( $user_id, $topic_id );
485 - elseif ( false == $is_favorite && 'bbp_favorite_add' == $action )
486 - $success = bbp_add_user_favorite( $user_id, $topic_id );
455 + // Send the email
456 + wp_mail( $r['newemail'], $subject, $message );
457 +}
487 458
488 - // Do additional favorites actions
489 - do_action( 'bbp_favorites_handler', $success, $user_id, $topic_id, $action );
459 +/**
460 + * Conditionally hook the core WordPress output actions to the end of the
461 + * default user's edit profile template
462 + *
463 + * This allows clever plugin authors to conditionally unhook the WordPress core
464 + * output actions if they don't want any unexpected junk to appear there, and
465 + * also avoids needing to pollute the templates with additional logic and actions.
466 + *
467 + * @since 2.2.0 bbPress (r4273)
468 + */
469 +function bbp_user_edit_after() {
470 + $action = bbp_is_user_home_edit() ? 'show_user_profile' : 'edit_user_profile';
490 471
491 - // Success!
492 - if ( true == $success ) {
493 -
494 - // Redirect back from whence we came
495 - if ( bbp_is_favorites() ) {
496 - $redirect = bbp_get_favorites_permalink( $user_id );
497 - } elseif ( bbp_is_single_user() ) {
498 - $redirect = bbp_get_user_profile_url();
499 - } elseif ( is_singular( bbp_get_topic_post_type() ) ) {
500 - $redirect = bbp_get_topic_permalink( $topic_id );
501 - } elseif ( is_single() || is_page() ) {
502 - $redirect = get_permalink();
503 - }
504 -
505 - wp_safe_redirect( $redirect );
506 -
507 - // For good measure
508 - exit();
509 -
510 - // Fail! Handle errors
511 - } elseif ( true == $is_favorite && 'bbp_favorite_remove' == $action ) {
512 - bbp_add_error( 'bbp_favorite_remove', __( '<strong>ERROR</strong>: There was a problem removing that topic from favorites!', 'bbpress' ) );
513 - } elseif ( false == $is_favorite && 'bbp_favorite_add' == $action ) {
514 - bbp_add_error( 'bbp_favorite_add', __( '<strong>ERROR</strong>: There was a problem favoriting that topic!', 'bbpress' ) );
515 - }
472 + do_action( $action, get_userdata( bbp_get_displayed_user_id() ) );
516 473 }
517 474
518 -/** Subscriptions *************************************************************/
475 +/** User Queries **************************************************************/
519 476
520 477 /**
521 - * Get the users who have subscribed to the topic
478 + * Get the topics that a user created
522 479 *
523 - * @since bbPress (r2668)
480 + * @since 2.0.0 bbPress (r2660)
481 + * @since 2.6.0 bbPress (r6618) Signature changed to accept an array of arguments
524 482 *
525 - * @param int $topic_id Optional. Topic id
526 - * @uses wpdb::get_col() To execute our query and get the column back
527 - * @uses apply_filters() Calls 'bbp_get_topic_subscribers' with the subscribers
528 - * @return array|bool Results if the topic has any subscribers, otherwise false
483 + * @param array $args Optional. Arguments to pass into bbp_has_topics()
484 + *
485 + * @return bool True if user has started topics, otherwise false
529 486 */
530 -function bbp_get_topic_subscribers( $topic_id = 0 ) {
531 - if ( empty( $topic_id ) ) return;
487 +function bbp_get_user_topics_started( $args = array() ) {
532 488
533 - global $wpdb;
489 + // Backwards compat for pre-2.6.0
490 + if ( is_numeric( $args ) ) {
491 + $args = array(
492 + 'author' => bbp_get_user_id( $args, false, false )
493 + );
494 + }
534 495
535 - $key = $wpdb->prefix . '_bbp_subscriptions';
536 - $users = wp_cache_get( 'bbp_get_topic_subscribers_' . $topic_id, 'bbpress' );
537 - if ( empty( $users ) ) {
538 - $users = $wpdb->get_col( "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = '{$key}' and FIND_IN_SET('{$topic_id}', meta_value) > 0" );
539 - wp_cache_set( 'bbp_get_topic_subscribers_' . $topic_id, $users, 'bbpress' );
540 - }
496 + // Default arguments
497 + $defaults = array(
498 + 'author' => bbp_get_displayed_user_id()
499 + );
541 500
542 - if ( !empty( $users ) ) {
543 - $users = apply_filters( 'bbp_get_topic_subscribers', $users );
544 - return $users;
545 - }
501 + // Parse arguments
502 + $r = bbp_parse_args( $args, $defaults, 'get_user_topics_started' );
546 503
547 - return false;
504 + // Get the topics
505 + $query = bbp_has_topics( $r );
506 + $user_id = $r['author'];
507 +
508 + // Filter & return
509 + return apply_filters( 'bbp_get_user_topics_started', $query, $user_id, $r, $args );
548 510 }
549 511
550 512 /**
551 - * Get a user's subscribed topics
513 + * Get the replies that a user created
552 514 *
553 - * @since bbPress (r2668)
515 + * @since 2.2.0 bbPress (r4225)
516 + * @since 2.6.0 bbPress (r6618) Signature changed to accept an array of arguments
554 517 *
555 - * @param int $user_id Optional. User id
556 - * @uses bbp_get_user_subscribed_topic_ids() To get the user's subscriptions
557 - * @uses bbp_has_topics() To get the topics
558 - * @uses apply_filters() Calls 'bbp_get_user_subscriptions' with the topic query
559 - * and user id
560 - * @return array|bool Results if user has subscriptions, otherwise false
518 + * @param array $args Optional. Arguments to pass into bbp_has_replies()
519 + *
520 + * @return bool True if user has created replies, otherwise false
561 521 */
562 -function bbp_get_user_subscriptions( $user_id = 0 ) {
522 +function bbp_get_user_replies_created( $args = array() ) {
563 523
564 - // Default to the displayed user
565 - $user_id = bbp_get_user_id( $user_id );
566 - if ( empty( $user_id ) )
567 - return false;
568 -
569 - // If user has subscriptions, load them
570 - $subscriptions = bbp_get_user_subscribed_topic_ids( $user_id );
571 - if ( !empty( $subscriptions ) ) {
572 - $query = bbp_has_topics( array( 'post__in' => $subscriptions ) );
573 - return apply_filters( 'bbp_get_user_subscriptions', $query, $user_id );
524 + // Backwards compat for pre-2.6.0
525 + if ( is_numeric( $args ) ) {
526 + $args = array(
527 + 'author' => bbp_get_user_id( $args, false, false ),
528 + 'post_type' => bbp_get_reply_post_type(),
529 + 'order' => 'DESC'
530 + );
574 531 }
575 532
576 - return false;
577 -}
533 + // Default arguments
534 + $defaults = array(
535 + 'author' => bbp_get_displayed_user_id(),
536 + 'post_type' => bbp_get_reply_post_type(),
537 + 'order' => 'DESC'
538 + );
578 539
579 -/**
580 - * Get a user's subscribed topics' ids
581 - *
582 - * @since bbPress (r2668)
583 - *
584 - * @param int $user_id Optional. User id
585 - * @uses bbp_get_user_id() To get the user id
586 - * @uses get_user_option() To get the user's subscriptions
587 - * @uses apply_filters() Calls 'bbp_get_user_subscribed_topic_ids' with
588 - * the subscriptions and user id
589 - * @return array|bool Results if user has subscriptions, otherwise false
590 - */
591 -function bbp_get_user_subscribed_topic_ids( $user_id = 0 ) {
592 - $user_id = bbp_get_user_id( $user_id );
593 - if ( empty( $user_id ) )
594 - return false;
540 + // Parse arguments
541 + $r = bbp_parse_args( $args, $defaults, 'get_user_replies_created' );
595 542
596 - $subscriptions = (string) get_user_option( '_bbp_subscriptions', $user_id );
597 - $subscriptions = (array) explode( ',', $subscriptions );
598 - $subscriptions = array_filter( $subscriptions );
543 + // Get the replies
544 + $query = bbp_has_replies( $r );
545 + $user_id = $r['author'];
599 546
600 - return apply_filters( 'bbp_get_user_subscribed_topic_ids', $subscriptions, $user_id );
547 + // Filter & return
548 + return apply_filters( 'bbp_get_user_replies_created', $query, $user_id, $r, $args );
601 549 }
602 550
603 551 /**
604 - * Check if a topic is in user's subscription list or not
552 + * Get user IDs from nicenames
605 553 *
606 - * @since bbPress (r2668)
554 + * This function is primarily used when saving object moderators
607 555 *
608 - * @param int $user_id Optional. User id
609 - * @param int $topic_id Optional. Topic id
610 - * @uses bbp_get_user_id() To get the user id
611 - * @uses bbp_get_user_subscribed_topic_ids() To get the user's subscriptions
612 - * @uses bbp_get_topic() To get the topic
613 - * @uses bbp_get_topic_id() To get the topic id
614 - * @uses apply_filters() Calls 'bbp_is_user_subscribed' with the bool, user id,
615 - * topic id and subsriptions
616 - * @return bool True if the topic is in user's subscriptions, otherwise false
556 + * @since 2.6.0 bbPress
557 + *
558 + * @param mixed $user_nicenames
559 + * @return array
617 560 */
618 -function bbp_is_user_subscribed( $user_id = 0, $topic_id = 0 ) {
561 +function bbp_get_user_ids_from_nicenames( $user_nicenames = array() ) {
619 562
620 - // Validate user
621 - $user_id = bbp_get_user_id( $user_id, true, true );
622 - if ( empty( $user_id ) )
623 - return false;
563 + // Default value
564 + $retval = array();
624 565
625 - $retval = false;
626 - $subscriptions = bbp_get_user_subscribed_topic_ids( $user_id );
566 + // Only query if nicenames
567 + if ( ! empty( $user_nicenames ) ) {
627 568
628 - if ( !empty( $subscriptions ) ) {
569 + // Maybe explode by comma
570 + $user_nicenames = ( is_string( $user_nicenames ) && strstr( $user_nicenames, ',' ) )
571 + ? explode( ',', $user_nicenames )
572 + : (array) $user_nicenames;
629 573
630 - // Checking a specific topic id
631 - if ( !empty( $topic_id ) ) {
632 - $topic = bbp_get_topic( $topic_id );
633 - $topic_id = !empty( $topic ) ? $topic->ID : 0;
574 + // Sanitize each nicename in the array
575 + $user_nicenames = array_map( 'sanitize_title', $user_nicenames );
634 576
635 - // Using the global topic id
636 - } elseif ( bbp_get_topic_id() ) {
637 - $topic_id = bbp_get_topic_id();
577 + // Get users
578 + $users = get_users( array(
579 + 'nicename__in' => $user_nicenames
580 + ) );
638 581
639 - // Use the current post id
640 - } elseif ( !bbp_get_topic_id() ) {
641 - $topic_id = get_the_ID();
582 + // Pluck or empty
583 + if ( ! empty( $users ) ) {
584 + $retval = wp_list_pluck( $users, 'ID' );
642 585 }
643 -
644 - // Is topic_id in the user's favorites
645 - if ( !empty( $topic_id ) ) {
646 - $retval = in_array( $topic_id, $subscriptions );
647 - }
648 586 }
649 587
650 - return (bool) apply_filters( 'bbp_is_user_subscribed', (bool) $retval, $user_id, $topic_id, $subscriptions );
588 + // Filter & return
589 + return (array) apply_filters( 'bbp_get_user_ids_from_nicenames', $retval, $user_nicenames );
651 590 }
652 591
653 592 /**
654 - * Add a topic to user's subscriptions
593 + * Get user nicenames from IDs
655 594 *
656 - * @since bbPress (r2668)
595 + * This function is primarily used when saving object moderators
657 596 *
658 - * @param int $user_id Optional. User id
659 - * @param int $topic_id Optional. Topic id
660 - * @uses bbp_get_user_subscribed_topic_ids() To get the user's subscriptions
661 - * @uses bbp_get_topic() To get the topic
662 - * @uses update_user_option() To update the user's subscriptions
663 - * @uses do_action() Calls 'bbp_add_user_subscription' with the user & topic id
664 - * @return bool Always true
597 + * @since 2.6.0 bbPress
598 + *
599 + * @param mixed $user_ids
600 + * @return array
665 601 */
666 -function bbp_add_user_subscription( $user_id = 0, $topic_id = 0 ) {
667 - if ( empty( $user_id ) || empty( $topic_id ) )
668 - return false;
602 +function bbp_get_user_nicenames_from_ids( $user_ids = array() ) {
669 603
670 - $subscriptions = (array) bbp_get_user_subscribed_topic_ids( $user_id );
604 + // Default value
605 + $retval = array();
671 606
672 - $topic = bbp_get_topic( $topic_id );
673 - if ( empty( $topic ) )
674 - return false;
607 + // Only query if nicenames
608 + if ( ! empty( $user_ids ) ) {
675 609
676 - if ( !in_array( $topic_id, $subscriptions ) ) {
677 - $subscriptions[] = $topic_id;
678 - $subscriptions = array_filter( $subscriptions );
679 - $subscriptions = (string) implode( ',', $subscriptions );
680 - update_user_option( $user_id, '_bbp_subscriptions', $subscriptions );
610 + // Get users
611 + $users = get_users( array(
612 + 'include' => $user_ids
613 + ) );
681 614
682 - wp_cache_delete( 'bbp_get_topic_subscribers_' . $topic_id, 'bbpress' );
615 + // Pluck or empty
616 + if ( ! empty( $users ) ) {
617 + $retval = wp_list_pluck( $users, 'user_nicename' );
618 + }
683 619 }
684 620
685 - do_action( 'bbp_add_user_subscription', $user_id, $topic_id );
621 + // Filter & return
622 + return (array) apply_filters( 'bbp_get_user_nicenames_from_ids', $retval, $user_ids );
623 +}
686 624
687 - return true;
688 -}
625 +/** Post Counts ***************************************************************/
689 626
690 627 /**
691 - * Remove a topic from user's subscriptions
628 + * Return the raw database count of topics by a user
692 629 *
693 - * @since bbPress (r2668)
630 + * @since 2.1.0 bbPress (r3633)
694 631 *
695 - * @param int $user_id Optional. User id
696 - * @param int $topic_id Optional. Topic id
697 - * @uses bbp_get_user_subscribed_topic_ids() To get the user's subscriptions
698 - * @uses update_user_option() To update the user's subscriptions
699 - * @uses delete_user_option() To delete the user's subscriptions meta
700 - * @uses do_action() Calls 'bbp_remove_user_subscription' with the user id and
701 - * topic id
702 - * @return bool True if the topic was removed from user's subscriptions,
703 - * otherwise false
632 + * @param int $user_id User ID to get count for
633 + *
634 + * @return int Raw DB count of topics
704 635 */
705 -function bbp_remove_user_subscription( $user_id, $topic_id ) {
706 - if ( empty( $user_id ) || empty( $topic_id ) )
707 - return false;
636 +function bbp_get_user_topic_count_raw( $user_id = 0 ) {
637 + $user_id = bbp_get_user_id( $user_id );
638 + $bbp_db = bbp_db();
639 + $statii = "'" . implode( "', '", bbp_get_public_topic_statuses() ) . "'";
640 + $sql = "SELECT COUNT(*)
641 + FROM {$bbp_db->posts}
642 + WHERE post_author = %d
643 + AND post_type = %s
644 + AND post_status IN ({$statii})";
708 645
709 - $subscriptions = (array) bbp_get_user_subscribed_topic_ids( $user_id );
646 + $query = $bbp_db->prepare( $sql, $user_id, bbp_get_topic_post_type() );
647 + $count = (int) $bbp_db->get_var( $query );
710 648
711 - if ( empty( $subscriptions ) )
712 - return false;
649 + // Filter & return
650 + return (int) apply_filters( 'bbp_get_user_topic_count_raw', $count, $user_id );
651 +}
713 652
714 - $pos = array_search( $topic_id, $subscriptions );
715 - if ( is_numeric( $pos ) ) {
716 - array_splice( $subscriptions, $pos, 1 );
717 - $subscriptions = array_filter( $subscriptions );
653 +/**
654 + * Return the raw database count of replies by a user
655 + *
656 + * @since 2.1.0 bbPress (r3633)
657 + *
658 + * @param int $user_id User ID to get count for
659 + *
660 + * @return int Raw DB count of replies
661 + */
662 +function bbp_get_user_reply_count_raw( $user_id = 0 ) {
663 + $user_id = bbp_get_user_id( $user_id );
664 + $bbp_db = bbp_db();
665 + $statii = "'" . implode( "', '", bbp_get_public_reply_statuses() ) . "'";
666 + $sql = "SELECT COUNT(*)
667 + FROM {$bbp_db->posts}
668 + WHERE post_author = %d
669 + AND post_type = %s
670 + AND post_status IN ({$statii})";
718 671
719 - if ( !empty( $subscriptions ) ) {
720 - $subscriptions = implode( ',', $subscriptions );
721 - update_user_option( $user_id, '_bbp_subscriptions', $subscriptions );
722 - } else {
723 - delete_user_option( $user_id, '_bbp_subscriptions' );
724 - }
672 + $query = $bbp_db->prepare( $sql, $user_id, bbp_get_reply_post_type() );
673 + $count = (int) $bbp_db->get_var( $query );
725 674
726 - wp_cache_delete( 'bbp_get_topic_subscribers_' . $topic_id, 'bbpress' );
727 - }
728 -
729 - do_action( 'bbp_remove_user_subscription', $user_id, $topic_id );
730 -
731 - return true;
675 + // Filter & return
676 + return (int) apply_filters( 'bbp_get_user_reply_count_raw', $count, $user_id );
732 677 }
733 678
734 679 /**
735 - * Handles the front end subscribing and unsubscribing topics
680 + * Bump the topic count for a user by a certain amount.
736 681 *
737 - * @uses bbp_is_subscriptions_active() To check if the subscriptions are active
738 - * @uses bbp_get_user_id() To get the user id
739 - * @uses bbp_verify_nonce_request() To verify the nonce and check the request
740 - * @uses current_user_can() To check if the current user can edit the user
741 - * @uses bbPress:errors:add() To log the error messages
742 - * @uses bbp_is_user_subscribed() To check if the topic is in user's
743 - * subscriptions
744 - * @uses bbp_remove_user_subscription() To remove the user subscription
745 - * @uses bbp_add_user_subscription() To add the user subscription
746 - * @uses do_action() Calls 'bbp_subscriptions_handler' with success, user id,
747 - * topic id and action
748 - * @uses bbp_is_subscription() To check if it's the subscription page
749 - * @uses bbp_get_subscription_link() To get the subscription page link
750 - * @uses bbp_get_topic_permalink() To get the topic permalink
751 - * @uses wp_safe_redirect() To redirect to the url
682 + * @since 2.6.0 bbPress (r5309)
683 + *
684 + * @param int $user_id
685 + * @param int $difference
752 686 */
753 -function bbp_subscriptions_handler() {
687 +function bbp_bump_user_topic_count( $user_id = 0, $difference = 1 ) {
754 688
755 - if ( !bbp_is_subscriptions_active() )
689 + // Bail if no bump
690 + if ( empty( $difference ) ) {
756 691 return false;
692 + }
757 693
758 - // Bail if not a GET action
759 - if ( 'GET' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
760 - return;
694 + // Validate user ID
695 + $user_id = bbp_get_user_id( $user_id );
696 + if ( empty( $user_id ) ) {
697 + return false;
698 + }
761 699
762 - // Bail if required GET actions aren't passed
763 - if ( empty( $_GET['topic_id'] ) || empty( $_GET['action'] ) )
764 - return;
765 -
766 - // Setup possible get actions
767 - $possible_actions = array(
768 - 'bbp_subscribe',
769 - 'bbp_unsubscribe',
770 - );
771 -
772 - // Bail if actions aren't meant for this function
773 - if ( !in_array( $_GET['action'], $possible_actions ) )
774 - return;
775 -
776 - // Get required data
777 - $action = $_GET['action'];
778 - $user_id = bbp_get_user_id( 0, true, true );
779 - $topic_id = intval( $_GET['topic_id'] );
780 -
781 - // Check for empty topic
782 - if ( empty( $topic_id ) ) {
783 - bbp_add_error( 'bbp_subscription_topic_id', __( '<strong>ERROR</strong>: No topic was found! Which topic are you subscribing/unsubscribing to?', 'bbpress' ) );
784 -
785 - // Check nonce
786 - } elseif ( ! bbp_verify_nonce_request( 'toggle-subscription_' . $topic_id ) ) {
787 - bbp_add_error( 'bbp_subscription_topic_id', __( '<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
788 -
789 - // Check current user's ability to edit the user
790 - } elseif ( !current_user_can( 'edit_user', $user_id ) ) {
791 - bbp_add_error( 'bbp_subscription_permissions', __( '<strong>ERROR</strong>: You don\'t have the permission to edit favorites of that user!', 'bbpress' ) );
700 + // Check meta for count, or query directly if not found
701 + $count = bbp_get_user_topic_count( $user_id, true );
702 + if ( empty( $count ) ) {
703 + $count = bbp_get_user_topic_count_raw( $user_id );
792 704 }
793 705
794 - // Bail if we have errors
795 - if ( bbp_has_errors() )
796 - return;
706 + $difference = (int) $difference;
707 + $user_topic_count = (int) ( $count + $difference );
797 708
798 - /** No errors *************************************************************/
709 + // Add them up and filter them
710 + $new_count = (int) apply_filters( 'bbp_bump_user_topic_count', $user_topic_count, $user_id, $difference, $count );
799 711
800 - $is_subscription = bbp_is_user_subscribed( $user_id, $topic_id );
801 - $success = false;
802 -
803 - if ( true == $is_subscription && 'bbp_unsubscribe' == $action )
804 - $success = bbp_remove_user_subscription( $user_id, $topic_id );
805 - elseif ( false == $is_subscription && 'bbp_subscribe' == $action )
806 - $success = bbp_add_user_subscription( $user_id, $topic_id );
807 -
808 - // Do additional subscriptions actions
809 - do_action( 'bbp_subscriptions_handler', $success, $user_id, $topic_id, $action );
810 -
811 - // Success!
812 - if ( true == $success ) {
813 -
814 - // Redirect back from whence we came
815 - if ( bbp_is_subscriptions() ) {
816 - $redirect = bbp_get_subscriptions_permalink( $user_id );
817 - } elseif ( bbp_is_single_user() ) {
818 - $redirect = bbp_get_user_profile_url();
819 - } elseif ( is_singular( bbp_get_topic_post_type() ) ) {
820 - $redirect = bbp_get_topic_permalink( $topic_id );
821 - } elseif ( is_single() || is_page() ) {
822 - $redirect = get_permalink();
823 - }
824 -
825 - wp_safe_redirect( $redirect );
826 -
827 - // For good measure
828 - exit();
829 -
830 - // Fail! Handle errors
831 - } elseif ( true == $is_subscription && 'bbp_unsubscribe' == $action ) {
832 - bbp_add_error( 'bbp_unsubscribe', __( '<strong>ERROR</strong>: There was a problem unsubscribing from that topic!', 'bbpress' ) );
833 - } elseif ( false == $is_subscription && 'bbp_subscribe' == $action ) {
834 - bbp_add_error( 'bbp_subscribe', __( '<strong>ERROR</strong>: There was a problem subscribing to that topic!', 'bbpress' ) );
835 - }
712 + return bbp_update_user_topic_count( $user_id, $new_count );
836 713 }
837 714
838 -/** Edit **********************************************************************/
839 -
840 715 /**
841 - * Handles the front end user editing
716 + * Bump the reply count for a user by a certain amount.
842 717 *
843 - * @uses is_multisite() To check if it's a multisite
844 - * @uses bbp_is_user_home() To check if the user is at home (the display page
845 - * is the one of the logged in user)
846 - * @uses get_option() To get the displayed user's new email id option
847 - * @uses wpdb::prepare() To sanitize our sql query
848 - * @uses wpdb::get_var() To execute our query and get back the variable
849 - * @uses wpdb::query() To execute our query
850 - * @uses wp_update_user() To update the user
851 - * @uses delete_option() To delete the displayed user's email id option
852 - * @uses bbp_get_user_profile_edit_url() To get the edit profile url
853 - * @uses wp_safe_redirect() To redirect to the url
854 - * @uses bbp_verify_nonce_request() To verify the nonce and check the request
855 - * @uses current_user_can() To check if the current user can edit the user
856 - * @uses do_action() Calls 'personal_options_update' or
857 - * 'edit_user_options_update' (based on if it's the user home)
858 - * with the displayed user id
859 - * @uses edit_user() To edit the user based on the post data
860 - * @uses get_userdata() To get the user data
861 - * @uses is_email() To check if the string is an email id or not
862 - * @uses wpdb::get_blog_prefix() To get the blog prefix
863 - * @uses is_network_admin() To check if the user is the network admin
864 - * @uses is_super_admin() To check if the user is super admin
865 - * @uses revoke_super_admin() To revoke super admin priviledges
866 - * @uses grant_super_admin() To grant super admin priviledges
867 - * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error}
718 + * @since 2.6.0 bbPress (r5309)
719 + *
720 + * @param int $user_id
721 + * @param int $difference
868 722 */
869 -function bbp_edit_user_handler() {
723 +function bbp_bump_user_reply_count( $user_id = 0, $difference = 1 ) {
870 724
871 - // Bail if not a POST action
872 - if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
873 - return;
874 -
875 - // Bail if action is not 'bbp-update-user'
876 - if ( empty( $_POST['action'] ) || ( 'bbp-update-user' !== $_POST['action'] ) )
877 - return;
878 -
879 - // Get the displayed user ID
880 - $user_id = bbp_get_displayed_user_id();
881 -
882 - // Execute confirmed email change. See send_confirmation_on_profile_email().
883 - if ( is_multisite() && bbp_is_user_home_edit() && isset( $_GET['newuseremail'] ) ) {
884 -
885 - $new_email = get_option( $user_id . '_new_email' );
886 -
887 - if ( $new_email['hash'] == $_GET['newuseremail'] ) {
888 - $user = new stdClass();
889 - $user->ID = $user_id;
890 - $user->user_email = esc_html( trim( $new_email['newemail'] ) );
891 -
892 - global $wpdb;
893 -
894 - if ( $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM {$wpdb->signups} WHERE user_login = %s", bbp_get_displayed_user_field( 'user_login' ) ) ) ) {
895 - $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->signups} SET user_email = %s WHERE user_login = %s", $user->user_email, bbp_get_displayed_user_field( 'user_login' ) ) );
896 - }
897 -
898 - wp_update_user( get_object_vars( $user ) );
899 - delete_option( $user_id . '_new_email' );
900 -
901 - wp_safe_redirect( add_query_arg( array( 'updated' => 'true' ), bbp_get_user_profile_edit_url( $user_id ) ) );
902 - exit();
903 - }
904 -
905 - // Delete new email address from user options
906 - } elseif ( is_multisite() && bbp_is_user_home_edit() && !empty( $_GET['dismiss'] ) && ( $user_id . '_new_email' == $_GET['dismiss'] ) ) {
907 - delete_option( $user_id . '_new_email' );
908 - wp_safe_redirect( add_query_arg( array( 'updated' => 'true' ), bbp_get_user_profile_edit_url( $user_id ) ) );
909 - exit();
725 + // Bail if no bump
726 + if ( empty( $difference ) ) {
727 + return false;
910 728 }
911 729
912 - // Nonce check
913 - if ( ! bbp_verify_nonce_request( 'update-user_' . $user_id ) ) {
914 - bbp_add_error( 'bbp_update_user_nonce', __( '<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
915 - return;
730 + // Validate user ID
731 + $user_id = bbp_get_user_id( $user_id );
732 + if ( empty( $user_id ) ) {
733 + return false;
916 734 }
917 735
918 - // Cap check
919 - if ( ! current_user_can( 'edit_user', $user_id ) ) {
920 - bbp_add_error( 'bbp_update_user_capability', __( '<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
921 - return;
736 + // Check meta for count, or query directly if not found
737 + $count = bbp_get_user_reply_count( $user_id, true );
738 + if ( empty( $count ) ) {
739 + $count = bbp_get_user_reply_count_raw( $user_id );
922 740 }
923 741
924 - // Do action based on who's profile you're editing
925 - $edit_action = bbp_is_user_home_edit() ? 'personal_options_update' : 'edit_user_profile_update';
926 - do_action( $edit_action, $user_id );
742 + $difference = (int) $difference;
743 + $user_reply_count = (int) ( $count + $difference );
927 744
928 - // Handle user edit
929 - $edit_user = edit_user( $user_id );
745 + // Add them up and filter them
746 + $new_count = (int) apply_filters( 'bbp_bump_user_reply_count', $user_reply_count, $user_id, $difference, $count );
930 747
931 - // Error(s) editng the user, so copy them into the global
932 - if ( is_wp_error( $edit_user ) ) {
933 - bbpress()->errors = $edit_user;
934 -
935 - // Successful edit to redirect
936 - } elseif ( is_integer( $edit_user ) ) {
937 -
938 - // Maybe update super admin ability
939 - if ( is_multisite() && ! bbp_is_user_home_edit() ) {
940 - empty( $_POST['super_admin'] ) ? revoke_super_admin( $edit_user ) : grant_super_admin( $edit_user );
941 - }
942 -
943 - $redirect = add_query_arg( array( 'updated' => 'true' ), bbp_get_user_profile_edit_url( $edit_user ) );
944 -
945 - wp_safe_redirect( $redirect );
946 - exit;
947 - }
748 + return bbp_update_user_reply_count( $user_id, $new_count );
948 749 }
949 750
950 751 /**
951 - * Conditionally hook the core WordPress output actions to the end of the
952 - * default user's edit profile template.
752 + * Helper function used to increase (by one) the count of topics for a user when
753 + * a topic is published.
953 754 *
954 - * This allows clever plugin authors to conditionally unhook the WordPress core
955 - * output actions if they don't want any unexpected junk to appear there, and
956 - * also avoids needing to pollute the templates with additional logic and actions.
755 + * @since 2.6.0 bbPress (r5309)
957 756 *
958 - * @since bbPress (r4273)
959 - *
960 - * @uses bbp_is_user_home_edit() To switch the action fired
961 - * @uses get_userdata() To get the current user's data
962 - * @uses bbp_get_displayed_user_id() To get the currently displayed user ID
757 + * @access
758 + * @param $topic_id
759 + * @param $forum_id
760 + * @param $anonymous_data
761 + * @param $topic_author
963 762 */
964 -function bbp_user_edit_after() {
965 - $action = bbp_is_user_home_edit() ? 'show_user_profile' : 'edit_user_profile';
966 -
967 - do_action( $action, get_userdata( bbp_get_displayed_user_id() ) );
763 +function bbp_increase_user_topic_count( $topic_id = 0 ) {
764 + $user_id = bbp_get_topic_author_id( $topic_id );
765 + return bbp_bump_user_topic_count( $user_id, 1 );
968 766 }
969 767
970 -/** User Queries **************************************************************/
971 -
972 768 /**
973 - * Get the topics that a user created
769 + * Helper function used to increase (by one) the count of replies for a user when
770 + * a reply is published.
974 771 *
975 - * @since bbPress (r2660)
772 + * This is a helper function, hooked to `bbp_new_reply`
976 773 *
977 - * @param int $user_id Optional. User id
978 - * @uses bbp_get_user_id() To get the topic id
979 - * @uses bbp_has_topics() To get the topics created by the user
980 - * @return array|bool Results if the user has created topics, otherwise false
774 + * @since 2.6.0 bbPress (r5309)
775 + *
776 + * @param $topic_id
777 + * @param $forum_id
778 + * @param $anonymous_data
779 + * @param $topic_author
981 780 */
982 -function bbp_get_user_topics_started( $user_id = 0 ) {
983 -
984 - // Validate user
985 - $user_id = bbp_get_user_id( $user_id );
986 - if ( empty( $user_id ) )
987 - return false;
988 -
989 - // Query defaults
990 - $default_query = array(
991 - 'author' => $user_id,
992 - 'show_stickies' => false,
993 - 'order' => 'DESC',
994 - );
995 -
996 - // Try to get the topics
997 - $query = bbp_has_topics( $default_query );
998 - if ( empty( $query ) )
999 - return false;
1000 -
1001 - return apply_filters( 'bbp_get_user_topics_started', $query, $user_id );
781 +function bbp_increase_user_reply_count( $reply_id = 0 ) {
782 + $user_id = bbp_get_reply_author_id( $reply_id );
783 + return bbp_bump_user_reply_count( $user_id, 1 );
1002 784 }
1003 785
1004 786 /**
1005 - * Get the replies that a user created
787 + * Helper function used to decrease (by one) the count of topics for a user when
788 + * a topic is unpublished.
1006 789 *
1007 - * @since bbPress (r4225)
790 + * @since 2.6.0 bbPress (r5309)
1008 791 *
1009 - * @param int $user_id Optional. User id
1010 - * @uses bbp_get_user_id() To get the topic id
1011 - * @uses bbp_has_replies() To get the topics created by the user
1012 - * @return array|bool Results if the user has created topics, otherwise false
792 + * @param $topic_id
1013 793 */
1014 -function bbp_get_user_replies_created( $user_id = 0 ) {
1015 -
1016 - // Validate user
1017 - $user_id = bbp_get_user_id( $user_id );
1018 - if ( empty( $user_id ) )
1019 - return false;
1020 -
1021 - // Try to get the topics
1022 - $query = bbp_has_replies( array(
1023 - 'post_type' => array( bbp_get_topic_post_type(), bbp_get_reply_post_type() ),
1024 - 'post_parent' => 'any',
1025 - 'posts_per_page' => bbp_get_replies_per_page(),
1026 - 'paged' => bbp_get_paged(),
1027 - 'orderby' => 'date',
1028 - 'order' => 'DESC',
1029 - 'author' => $user_id,
1030 - 'show_stickies' => false,
1031 - ) );
1032 -
1033 - return apply_filters( 'bbp_get_user_replies_created', $query, $user_id );
794 +function bbp_decrease_user_topic_count( $topic_id = 0 ) {
795 + $user_id = bbp_get_topic_author_id( $topic_id );
796 + return bbp_bump_user_topic_count( $user_id, -1 );
1034 797 }
1035 798
1036 799 /**
1037 - * Get the total number of users on the forums
800 + * Helper function used to increase (by one) the count of replies for a user when
801 + * a topic is unpublished.
1038 802 *
1039 - * @since bbPress (r2769)
1040 - * @uses wp_cache_get() Check if query is in cache
1041 - * @uses get_users() To execute our query and get the var back
1042 - * @uses wp_cache_set() Set the query in the cache
1043 - * @uses apply_filters() Calls 'bbp_get_total_users' with number of users
1044 - * @return int Total number of users
803 + * @since 2.6.0 bbPress (r5309)
804 + *
805 + * @param $reply_id
1045 806 */
1046 -function bbp_get_total_users() {
1047 - $user_count = count_users();
1048 - return apply_filters( 'bbp_get_total_users', (int) $user_count['total_users'] );
807 +function bbp_decrease_user_reply_count( $reply_id = 0 ) {
808 + $user_id = bbp_get_reply_author_id( $reply_id );
809 + return bbp_bump_user_reply_count( $user_id, -1 );
1049 810 }
1050 811
1051 -/** Premissions ***************************************************************/
812 +/** Permissions ***************************************************************/
1052 813
1053 814 /**
1054 - * Redirect if unathorized user is attempting to edit another user
815 + * Redirect if unauthorized user is attempting to edit another user
1055 816 *
1056 817 * This is hooked to 'bbp_template_redirect' and controls the conditions under
1057 818 * which a user can edit another user (or themselves.) If these conditions are
1058 - * met. We assume a user cannot perform this task, and look for ways they can
819 + * met, we assume a user cannot perform this task, and look for ways they can
1059 820 * earn the ability to access this template.
1060 - *
1061 - * @since bbPress (r3605)
1062 821 *
1063 - * @uses bbp_is_topic_edit()
1064 - * @uses current_user_can()
1065 - * @uses bbp_get_topic_id()
1066 - * @uses wp_safe_redirect()
1067 - * @uses bbp_get_topic_permalink()
822 + * @since 2.1.0 bbPress (r3605)
1068 823 */
1069 824 function bbp_check_user_edit() {
1070 825
1071 - // Bail if not editing a topic
1072 - if ( ! bbp_is_single_user_edit() )
826 + // Bail if not editing a user
827 + if ( ! bbp_is_single_user_edit() ) {
1073 828 return;
829 + }
1074 830
1075 831 // Default to false
1076 832 $redirect = true;
833 + $user_id = bbp_get_displayed_user_id();
1077 834
1078 835 // Allow user to edit their own profile
1079 836 if ( bbp_is_user_home_edit() ) {
1080 837 $redirect = false;
@@ -1079,9 +836,9 @@
1079 836 if ( bbp_is_user_home_edit() ) {
1080 837 $redirect = false;
1081 838
1082 839 // Allow if current user can edit the displayed user
1083 - } elseif ( current_user_can( 'edit_user', bbp_get_displayed_user_id() ) ) {
840 + } elseif ( current_user_can( 'edit_user', $user_id ) ) {
1084 841 $redirect = false;
1085 842
1086 843 // Allow if user can manage network users, or edit-any is enabled
1087 844 } elseif ( current_user_can( 'manage_network_users' ) || apply_filters( 'enable_edit_any_user_configuration', false ) ) {
@@ -1087,30 +844,33 @@
1087 844 } elseif ( current_user_can( 'manage_network_users' ) || apply_filters( 'enable_edit_any_user_configuration', false ) ) {
1088 845 $redirect = false;
1089 846 }
1090 847
1091 - // Maybe redirect back to profile page
1092 - if ( true === $redirect ) {
1093 - wp_safe_redirect( bbp_get_user_profile_url( bbp_get_displayed_user_id() ) );
1094 - exit();
848 + // Allow conclusion to be overridden
849 + $redirect = (bool) apply_filters( 'bbp_check_user_edit', $redirect, $user_id );
850 +
851 + // Bail if not redirecting
852 + if ( false === $redirect ) {
853 + return;
1095 854 }
855 +
856 + // Filter redirect URL
857 + $profile_url = bbp_get_user_profile_url( $user_id );
858 + $redirect_to = apply_filters( 'bbp_check_user_edit_redirect_to', $profile_url, $user_id );
859 +
860 + // Redirect
861 + bbp_redirect( $redirect_to );
1096 862 }
1097 863
1098 864 /**
1099 865 * Check if a user is blocked, or cannot spectate the forums.
1100 866 *
1101 - * @since bbPress (r2996)
1102 - *
1103 - * @uses is_user_logged_in() To check if user is logged in
1104 - * @uses is_super_admin() To check if user is a super admin
1105 - * @uses current_user_can() To check if the current user can spectate
1106 - * @uses is_bbpress() To check if in a bbPress section of the site
1107 - * @uses bbp_set_404() To set a 404 status
867 + * @since 2.0.0 bbPress (r2996)
1108 868 */
1109 869 function bbp_forum_enforce_blocked() {
1110 870
1111 - // Bail if not logged in or super admin
1112 - if ( ! is_user_logged_in() || is_super_admin() ) {
871 + // Bail if not logged in or keymaster
872 + if ( ! is_user_logged_in() || bbp_is_user_keymaster() ) {
1113 873 return;
1114 874 }
1115 875
1116 876 // Set 404 if in bbPress and user cannot spectate
@@ -1118,44 +878,111 @@
1118 878 bbp_set_404();
1119 879 }
1120 880 }
1121 881
882 +/** Sanitization **************************************************************/
883 +
884 +/**
885 + * Sanitize displayed user data, when viewing and editing any user.
886 + *
887 + * This somewhat monolithic function handles the escaping and sanitization of
888 + * user data for a bbPress profile. There are two reasons this all happens here:
889 + *
890 + * 1. bbPress took a similar approach to WordPress, and funnels all user profile
891 + * data through a central helper. This eventually calls sanitize_user_field()
892 + * which applies a few context based filters, which some third party plugins
893 + * might be relying on bbPress to play nicely with.
894 + *
895 + * 2. Early versions of bbPress 2.x templates did not escape this data meaning
896 + * a backwards compatible approach like this one was necessary to protect
897 + * existing installations that may have custom template parts.
898 + *
899 + * @since 2.6.0 bbPress (r5368)
900 + *
901 + * @param string $value
902 + * @param string $field
903 + * @param string $context
904 + * @return string
905 + */
906 +function bbp_sanitize_displayed_user_field( $value = '', $field = '', $context = 'display' ) {
907 +
908 + // Bail if not editing or displaying (maybe we'll do more here later)
909 + if ( ! in_array( $context, array( 'edit', 'display' ), true ) ) {
910 + return $value;
911 + }
912 +
913 + // By default, no filter set (consider making this an array later)
914 + $filter = false;
915 +
916 + // Big switch statement to decide which user field we're sanitizing and how
917 + switch ( $field ) {
918 +
919 + // Description is a paragraph
920 + case 'description' :
921 + $filter = ( 'edit' === $context ) ? '' : 'wp_kses_data';
922 + break;
923 +
924 + // Email addresses are sanitized with a specific function
925 + case 'user_email' :
926 + $filter = 'sanitize_email';
927 + break;
928 +
929 + // Name & login fields
930 + case 'user_login' :
931 + case 'display_name' :
932 + case 'first_name' :
933 + case 'last_name' :
934 + case 'nick_name' :
935 + $filter = ( 'edit' === $context ) ? 'esc_attr' : 'esc_html';
936 + break;
937 +
938 + // wp-includes/default-filters.php escapes this for us via esc_url()
939 + case 'user_url' :
940 + break;
941 + }
942 +
943 + // Run any applicable filters on the value
944 + if ( ! empty( $filter ) ) {
945 + $value = call_user_func( $filter, $value );
946 + }
947 +
948 + return $value;
949 +}
950 +
1122 951 /** Converter *****************************************************************/
1123 952
1124 953 /**
1125 - * Convert passwords from previous platfrom encryption to WordPress encryption.
954 + * Convert passwords from previous platform encryption to WordPress encryption.
1126 955 *
1127 - * @since bbPress (r3813)
1128 - * @global WPDB $wpdb
956 + * @since 2.1.0 bbPress (r3813)
1129 957 */
1130 958 function bbp_user_maybe_convert_pass() {
1131 959
960 + // Sanitize username
961 + $username = ! empty( $_POST['log'] )
962 + ? sanitize_user( $_POST['log'] )
963 + : '';
964 +
1132 965 // Bail if no username
1133 - $username = !empty( $_POST['log'] ) ? $_POST['log'] : '';
1134 - if ( empty( $username ) )
966 + if ( empty( $username ) ) {
1135 967 return;
968 + }
1136 969
1137 - global $wpdb;
1138 -
1139 970 // Bail if no user password to convert
1140 - $row = $wpdb->get_row( "SELECT * FROM {$wpdb->users} INNER JOIN {$wpdb->usermeta} ON user_id = ID WHERE meta_key = '_bbp_class' AND user_login = '{$username}' LIMIT 1" );
1141 - if ( empty( $row ) || is_wp_error( $row ) )
971 + $bbp_db = bbp_db();
972 + $query = $bbp_db->prepare( "SELECT * FROM {$bbp_db->users} INNER JOIN {$bbp_db->usermeta} ON user_id = ID WHERE meta_key = %s AND user_login = %s LIMIT 1", '_bbp_class', $username );
973 + $row = $bbp_db->get_row( $query );
974 + if ( empty( $row ) || is_wp_error( $row ) ) {
1142 975 return;
976 + }
1143 977
1144 - // Setup admin (to include converter)
1145 - require_once( bbpress()->includes_dir . 'admin/admin.php' );
978 + // Setup the converter
979 + bbp_setup_converter();
1146 980
1147 - // Create the admin object
1148 - bbp_admin();
1149 -
1150 - // Convert password
1151 - require_once( bbpress()->admin->admin_dir . 'converter.php' );
1152 - require_once( bbpress()->admin->admin_dir . 'converters/' . $row->meta_value . '.php' );
1153 -
1154 - // Create the converter
981 + // Try to convert the old password for this user
1155 982 $converter = bbp_new_converter( $row->meta_value );
1156 983
1157 984 // Try to call the conversion method
1158 - if ( is_a( $converter, 'BBP_Converter_Base' ) && method_exists( $converter, 'callback_pass' ) ) {
985 + if ( ( $converter instanceof BBP_Converter_Base ) && method_exists( $converter, 'callback_pass' ) ) {
1159 986 $converter->callback_pass( $username, $_POST['pwd'] );
1160 987 }
1161 988 }