bbPress - Version 2.5.4

Version Description

  • Fix reply editing causing polluted hierarchy
  • Add tool for repairing reply positions within topics
  • Improved custom slug and displayed user field sanitization
  • Improved SSL support when relying on theme compatibility
Download this release

Release Info

Developer johnjamesjacoby
Plugin Icon 128x128 bbPress
Version 2.5.4
Comparing to
See all releases

Code changes from version 2.5.3 to 2.5.4

bbpress.php CHANGED
@@ -5,7 +5,7 @@
5
  *
6
  * bbPress is forum software with a twist from the creators of WordPress.
7
  *
8
- * $Id: bbpress.php 5249 2014-01-11 18:20:32Z johnjamesjacoby $
9
  *
10
  * @package bbPress
11
  * @subpackage Main
@@ -17,7 +17,7 @@
17
  * Description: bbPress is forum software with a twist from the creators of WordPress.
18
  * Author: The bbPress Community
19
  * Author URI: http://bbpress.org
20
- * Version: 2.5.3
21
  * Text Domain: bbpress
22
  * Domain Path: /languages/
23
  */
@@ -190,7 +190,7 @@ final class bbPress {
190
 
191
  /** Versions **********************************************************/
192
 
193
- $this->version = '2.5.3-5249';
194
  $this->db_version = '250';
195
 
196
  /** Paths *************************************************************/
5
  *
6
  * bbPress is forum software with a twist from the creators of WordPress.
7
  *
8
+ * $Id: bbpress.php 5381 2014-06-06 19:58:00Z johnjamesjacoby $
9
  *
10
  * @package bbPress
11
  * @subpackage Main
17
  * Description: bbPress is forum software with a twist from the creators of WordPress.
18
  * Author: The bbPress Community
19
  * Author URI: http://bbpress.org
20
+ * Version: 2.5.4
21
  * Text Domain: bbpress
22
  * Domain Path: /languages/
23
  */
190
 
191
  /** Versions **********************************************************/
192
 
193
+ $this->version = '2.5.4-5380';
194
  $this->db_version = '250';
195
 
196
  /** Paths *************************************************************/
includes/admin/converters/Drupal7.php CHANGED
@@ -3,7 +3,7 @@
3
  /**
4
  * Implementation of Drupal v7.x Forum converter.
5
  *
6
- * @since bbPress (r5057)
7
  * @link Codex Docs http://codex.bbpress.org/import-forums/drupal
8
  */
9
  class Drupal7 extends BBP_Converter_Base {
3
  /**
4
  * Implementation of Drupal v7.x Forum converter.
5
  *
6
+ * @since bbPress (r5138)
7
  * @link Codex Docs http://codex.bbpress.org/import-forums/drupal
8
  */
9
  class Drupal7 extends BBP_Converter_Base {
includes/admin/functions.php CHANGED
@@ -137,6 +137,36 @@ function bbp_filter_sample_permalink( $post_link, $_post, $leavename = false, $s
137
  return $post_link;
138
  }
139
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  /**
141
  * Uninstall all bbPress options and capabilities from a specific site.
142
  *
137
  return $post_link;
138
  }
139
 
140
+ /**
141
+ * Sanitize permalink slugs when saving the settings page.
142
+ *
143
+ * @since bbPress (r5364)
144
+ *
145
+ * @param string $slug
146
+ * @return string
147
+ */
148
+ function bbp_sanitize_slug( $slug = '' ) {
149
+
150
+ // Don't allow multiple slashes in a row
151
+ $value = preg_replace( '#/+#', '/', str_replace( '#', '', $slug ) );
152
+
153
+ // Strip out unsafe or unusable chars
154
+ $value = esc_url_raw( $value );
155
+
156
+ // esc_url_raw() adds a scheme via esc_url(), so let's remove it
157
+ $value = str_replace( 'http://', '', $value );
158
+
159
+ // Trim off first and last slashes.
160
+ //
161
+ // We already prevent double slashing elsewhere, but let's prevent
162
+ // accidental poisoning of options values where we can.
163
+ $value = ltrim( $value, '/' );
164
+ $value = rtrim( $value, '/' );
165
+
166
+ // Filter the result and return
167
+ return apply_filters( 'bbp_sanitize_slug', $value, $slug );
168
+ }
169
+
170
  /**
171
  * Uninstall all bbPress options and capabilities from a specific site.
172
  *
includes/admin/settings.php CHANGED
@@ -263,7 +263,7 @@ function bbp_admin_get_settings_fields() {
263
  '_bbp_root_slug' => array(
264
  'title' => __( 'Forum Root', 'bbpress' ),
265
  'callback' => 'bbp_admin_setting_callback_root_slug',
266
- 'sanitize_callback' => 'esc_sql',
267
  'args' => array()
268
  ),
269
 
@@ -292,7 +292,7 @@ function bbp_admin_get_settings_fields() {
292
  '_bbp_forum_slug' => array(
293
  'title' => __( 'Forum', 'bbpress' ),
294
  'callback' => 'bbp_admin_setting_callback_forum_slug',
295
- 'sanitize_callback' => 'sanitize_title',
296
  'args' => array()
297
  ),
298
 
@@ -300,7 +300,7 @@ function bbp_admin_get_settings_fields() {
300
  '_bbp_topic_slug' => array(
301
  'title' => __( 'Topic', 'bbpress' ),
302
  'callback' => 'bbp_admin_setting_callback_topic_slug',
303
- 'sanitize_callback' => 'sanitize_title',
304
  'args' => array()
305
  ),
306
 
@@ -308,7 +308,7 @@ function bbp_admin_get_settings_fields() {
308
  '_bbp_topic_tag_slug' => array(
309
  'title' => __( 'Topic Tag', 'bbpress' ),
310
  'callback' => 'bbp_admin_setting_callback_topic_tag_slug',
311
- 'sanitize_callback' => 'sanitize_title',
312
  'args' => array()
313
  ),
314
 
@@ -316,7 +316,7 @@ function bbp_admin_get_settings_fields() {
316
  '_bbp_view_slug' => array(
317
  'title' => __( 'Topic View', 'bbpress' ),
318
  'callback' => 'bbp_admin_setting_callback_view_slug',
319
- 'sanitize_callback' => 'sanitize_title',
320
  'args' => array()
321
  ),
322
 
@@ -324,7 +324,7 @@ function bbp_admin_get_settings_fields() {
324
  '_bbp_reply_slug' => array(
325
  'title' => __( 'Reply', 'bbpress' ),
326
  'callback' => 'bbp_admin_setting_callback_reply_slug',
327
- 'sanitize_callback' => 'sanitize_title',
328
  'args' => array()
329
  ),
330
 
@@ -332,7 +332,7 @@ function bbp_admin_get_settings_fields() {
332
  '_bbp_search_slug' => array(
333
  'title' => __( 'Search', 'bbpress' ),
334
  'callback' => 'bbp_admin_setting_callback_search_slug',
335
- 'sanitize_callback' => 'sanitize_title',
336
  'args' => array()
337
  )
338
  ),
@@ -345,7 +345,7 @@ function bbp_admin_get_settings_fields() {
345
  '_bbp_user_slug' => array(
346
  'title' => __( 'User Base', 'bbpress' ),
347
  'callback' => 'bbp_admin_setting_callback_user_slug',
348
- 'sanitize_callback' => 'sanitize_title',
349
  'args' => array()
350
  ),
351
 
@@ -353,7 +353,7 @@ function bbp_admin_get_settings_fields() {
353
  '_bbp_topic_archive_slug' => array(
354
  'title' => __( 'Topics Started', 'bbpress' ),
355
  'callback' => 'bbp_admin_setting_callback_topic_archive_slug',
356
- 'sanitize_callback' => 'esc_sql',
357
  'args' => array()
358
  ),
359
 
@@ -361,7 +361,7 @@ function bbp_admin_get_settings_fields() {
361
  '_bbp_reply_archive_slug' => array(
362
  'title' => __( 'Replies Created', 'bbpress' ),
363
  'callback' => 'bbp_admin_setting_callback_reply_archive_slug',
364
- 'sanitize_callback' => 'esc_sql',
365
  'args' => array()
366
  ),
367
 
@@ -369,7 +369,7 @@ function bbp_admin_get_settings_fields() {
369
  '_bbp_user_favs_slug' => array(
370
  'title' => __( 'Favorite Topics', 'bbpress' ),
371
  'callback' => 'bbp_admin_setting_callback_user_favs_slug',
372
- 'sanitize_callback' => 'esc_sql',
373
  'args' => array()
374
  ),
375
 
@@ -377,7 +377,7 @@ function bbp_admin_get_settings_fields() {
377
  '_bbp_user_subs_slug' => array(
378
  'title' => __( 'Topic Subscriptions', 'bbpress' ),
379
  'callback' => 'bbp_admin_setting_callback_user_subs_slug',
380
- 'sanitize_callback' => 'esc_sql',
381
  'args' => array()
382
  )
383
  ),
263
  '_bbp_root_slug' => array(
264
  'title' => __( 'Forum Root', 'bbpress' ),
265
  'callback' => 'bbp_admin_setting_callback_root_slug',
266
+ 'sanitize_callback' => 'bbp_sanitize_slug',
267
  'args' => array()
268
  ),
269
 
292
  '_bbp_forum_slug' => array(
293
  'title' => __( 'Forum', 'bbpress' ),
294
  'callback' => 'bbp_admin_setting_callback_forum_slug',
295
+ 'sanitize_callback' => 'bbp_sanitize_slug',
296
  'args' => array()
297
  ),
298
 
300
  '_bbp_topic_slug' => array(
301
  'title' => __( 'Topic', 'bbpress' ),
302
  'callback' => 'bbp_admin_setting_callback_topic_slug',
303
+ 'sanitize_callback' => 'bbp_sanitize_slug',
304
  'args' => array()
305
  ),
306
 
308
  '_bbp_topic_tag_slug' => array(
309
  'title' => __( 'Topic Tag', 'bbpress' ),
310
  'callback' => 'bbp_admin_setting_callback_topic_tag_slug',
311
+ 'sanitize_callback' => 'bbp_sanitize_slug',
312
  'args' => array()
313
  ),
314
 
316
  '_bbp_view_slug' => array(
317
  'title' => __( 'Topic View', 'bbpress' ),
318
  'callback' => 'bbp_admin_setting_callback_view_slug',
319
+ 'sanitize_callback' => 'bbp_sanitize_slug',
320
  'args' => array()
321
  ),
322
 
324
  '_bbp_reply_slug' => array(
325
  'title' => __( 'Reply', 'bbpress' ),
326
  'callback' => 'bbp_admin_setting_callback_reply_slug',
327
+ 'sanitize_callback' => 'bbp_sanitize_slug',
328
  'args' => array()
329
  ),
330
 
332
  '_bbp_search_slug' => array(
333
  'title' => __( 'Search', 'bbpress' ),
334
  'callback' => 'bbp_admin_setting_callback_search_slug',
335
+ 'sanitize_callback' => 'bbp_sanitize_slug',
336
  'args' => array()
337
  )
338
  ),
345
  '_bbp_user_slug' => array(
346
  'title' => __( 'User Base', 'bbpress' ),
347
  'callback' => 'bbp_admin_setting_callback_user_slug',
348
+ 'sanitize_callback' => 'bbp_sanitize_slug',
349
  'args' => array()
350
  ),
351
 
353
  '_bbp_topic_archive_slug' => array(
354
  'title' => __( 'Topics Started', 'bbpress' ),
355
  'callback' => 'bbp_admin_setting_callback_topic_archive_slug',
356
+ 'sanitize_callback' => 'bbp_sanitize_slug',
357
  'args' => array()
358
  ),
359
 
361
  '_bbp_reply_archive_slug' => array(
362
  'title' => __( 'Replies Created', 'bbpress' ),
363
  'callback' => 'bbp_admin_setting_callback_reply_archive_slug',
364
+ 'sanitize_callback' => 'bbp_sanitize_slug',
365
  'args' => array()
366
  ),
367
 
369
  '_bbp_user_favs_slug' => array(
370
  'title' => __( 'Favorite Topics', 'bbpress' ),
371
  'callback' => 'bbp_admin_setting_callback_user_favs_slug',
372
+ 'sanitize_callback' => 'bbp_sanitize_slug',
373
  'args' => array()
374
  ),
375
 
377
  '_bbp_user_subs_slug' => array(
378
  'title' => __( 'Topic Subscriptions', 'bbpress' ),
379
  'callback' => 'bbp_admin_setting_callback_user_subs_slug',
380
+ 'sanitize_callback' => 'bbp_sanitize_slug',
381
  'args' => array()
382
  )
383
  ),
includes/admin/tools.php CHANGED
@@ -163,18 +163,19 @@ function bbp_admin_repair_list() {
163
  10 => array( 'bbp-sync-forum-visibility', __( 'Recalculate private and hidden forums', 'bbpress' ), 'bbp_admin_repair_forum_visibility' ),
164
  15 => array( 'bbp-sync-all-topics-forums', __( 'Recalculate last activity in each topic and forum', 'bbpress' ), 'bbp_admin_repair_freshness' ),
165
  20 => array( 'bbp-sync-all-topics-sticky', __( 'Recalculate the sticky relationship of each topic', 'bbpress' ), 'bbp_admin_repair_sticky' ),
166
- 25 => array( 'bbp-group-forums', __( 'Repair BuddyPress Group Forum relationships', 'bbpress' ), 'bbp_admin_repair_group_forum_relationship' ),
167
- 30 => array( 'bbp-forum-topics', __( 'Count topics in each forum', 'bbpress' ), 'bbp_admin_repair_forum_topic_count' ),
168
- 35 => array( 'bbp-forum-replies', __( 'Count replies in each forum', 'bbpress' ), 'bbp_admin_repair_forum_reply_count' ),
169
- 40 => array( 'bbp-topic-replies', __( 'Count replies in each topic', 'bbpress' ), 'bbp_admin_repair_topic_reply_count' ),
170
- 45 => array( 'bbp-topic-voices', __( 'Count voices in each topic', 'bbpress' ), 'bbp_admin_repair_topic_voice_count' ),
171
- 50 => array( 'bbp-topic-hidden-replies', __( 'Count spammed & trashed replies in each topic', 'bbpress' ), 'bbp_admin_repair_topic_hidden_reply_count' ),
172
- 55 => array( 'bbp-user-topics', __( 'Count topics for each user', 'bbpress' ), 'bbp_admin_repair_user_topic_count' ),
173
- 60 => array( 'bbp-user-replies', __( 'Count replies for each user', 'bbpress' ), 'bbp_admin_repair_user_reply_count' ),
174
- 65 => array( 'bbp-user-favorites', __( 'Remove trashed topics from user favorites', 'bbpress' ), 'bbp_admin_repair_user_favorites' ),
175
- 70 => array( 'bbp-user-topic-subscriptions', __( 'Remove trashed topics from user subscriptions', 'bbpress' ), 'bbp_admin_repair_user_topic_subscriptions' ),
176
- 75 => array( 'bbp-user-forum-subscriptions', __( 'Remove trashed forums from user subscriptions', 'bbpress' ), 'bbp_admin_repair_user_forum_subscriptions' ),
177
- 80 => array( 'bbp-user-role-map', __( 'Remap existing users to default forum roles', 'bbpress' ), 'bbp_admin_repair_user_roles' )
 
178
  );
179
  ksort( $repair_list );
180
 
@@ -197,16 +198,23 @@ function bbp_admin_repair_topic_reply_count() {
197
  $statement = __( 'Counting the number of replies in each topic… %s', 'bbpress' );
198
  $result = __( 'Failed!', 'bbpress' );
199
 
200
- $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` = '_bbp_reply_count';";
201
- if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
202
- return array( 1, sprintf( $statement, $result ) );
203
-
204
  // Post types and status
205
  $tpt = bbp_get_topic_post_type();
206
  $rpt = bbp_get_reply_post_type();
207
  $pps = bbp_get_public_status_id();
208
  $cps = bbp_get_closed_status_id();
209
 
 
 
 
 
 
 
 
 
 
 
 
210
  $sql = "INSERT INTO `{$wpdb->postmeta}` (`post_id`, `meta_key`, `meta_value`) (
211
  SELECT `topics`.`ID` AS `post_id`, '_bbp_reply_count' AS `meta_key`, COUNT(`replies`.`ID`) As `meta_value`
212
  FROM `{$wpdb->posts}` AS `topics`
@@ -218,8 +226,9 @@ function bbp_admin_repair_topic_reply_count() {
218
  AND `topics`.`post_status` IN ( '{$pps}', '{$cps}' )
219
  GROUP BY `topics`.`ID`);";
220
 
221
- if ( is_wp_error( $wpdb->query( $sql ) ) )
222
  return array( 2, sprintf( $statement, $result ) );
 
223
 
224
  return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
225
  }
@@ -478,10 +487,21 @@ function bbp_admin_repair_forum_reply_count() {
478
  $statement = __( 'Counting the number of replies in each forum… %s', 'bbpress' );
479
  $result = __( 'Failed!', 'bbpress' );
480
 
481
- $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` IN ( '_bbp_reply_count', '_bbp_total_reply_count' );";
482
- if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
483
- return array( 1, sprintf( $statement, $result ) );
484
 
 
 
 
 
 
 
 
 
 
 
 
 
485
  $forums = get_posts( array( 'post_type' => bbp_get_forum_post_type(), 'numberposts' => -1 ) );
486
  if ( !empty( $forums ) ) {
487
  foreach ( $forums as $forum ) {
@@ -1110,6 +1130,62 @@ function bbp_admin_repair_topic_meta() {
1110
  return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
1111
  }
1112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1113
  /** Reset ********************************************************************/
1114
 
1115
  /**
163
  10 => array( 'bbp-sync-forum-visibility', __( 'Recalculate private and hidden forums', 'bbpress' ), 'bbp_admin_repair_forum_visibility' ),
164
  15 => array( 'bbp-sync-all-topics-forums', __( 'Recalculate last activity in each topic and forum', 'bbpress' ), 'bbp_admin_repair_freshness' ),
165
  20 => array( 'bbp-sync-all-topics-sticky', __( 'Recalculate the sticky relationship of each topic', 'bbpress' ), 'bbp_admin_repair_sticky' ),
166
+ 25 => array( 'bbp-sync-all-reply-positions', __( 'Recalculate the position of each reply', 'bbpress' ), 'bbp_admin_repair_reply_menu_order' ),
167
+ 30 => array( 'bbp-group-forums', __( 'Repair BuddyPress Group Forum relationships', 'bbpress' ), 'bbp_admin_repair_group_forum_relationship' ),
168
+ 35 => array( 'bbp-forum-topics', __( 'Count topics in each forum', 'bbpress' ), 'bbp_admin_repair_forum_topic_count' ),
169
+ 40 => array( 'bbp-forum-replies', __( 'Count replies in each forum', 'bbpress' ), 'bbp_admin_repair_forum_reply_count' ),
170
+ 45 => array( 'bbp-topic-replies', __( 'Count replies in each topic', 'bbpress' ), 'bbp_admin_repair_topic_reply_count' ),
171
+ 50 => array( 'bbp-topic-voices', __( 'Count voices in each topic', 'bbpress' ), 'bbp_admin_repair_topic_voice_count' ),
172
+ 55 => array( 'bbp-topic-hidden-replies', __( 'Count spammed & trashed replies in each topic', 'bbpress' ), 'bbp_admin_repair_topic_hidden_reply_count' ),
173
+ 60 => array( 'bbp-user-topics', __( 'Count topics for each user', 'bbpress' ), 'bbp_admin_repair_user_topic_count' ),
174
+ 65 => array( 'bbp-user-replies', __( 'Count replies for each user', 'bbpress' ), 'bbp_admin_repair_user_reply_count' ),
175
+ 70 => array( 'bbp-user-favorites', __( 'Remove trashed topics from user favorites', 'bbpress' ), 'bbp_admin_repair_user_favorites' ),
176
+ 75 => array( 'bbp-user-topic-subscriptions', __( 'Remove trashed topics from user subscriptions', 'bbpress' ), 'bbp_admin_repair_user_topic_subscriptions' ),
177
+ 80 => array( 'bbp-user-forum-subscriptions', __( 'Remove trashed forums from user subscriptions', 'bbpress' ), 'bbp_admin_repair_user_forum_subscriptions' ),
178
+ 85 => array( 'bbp-user-role-map', __( 'Remap existing users to default forum roles', 'bbpress' ), 'bbp_admin_repair_user_roles' )
179
  );
180
  ksort( $repair_list );
181
 
198
  $statement = __( 'Counting the number of replies in each topic… %s', 'bbpress' );
199
  $result = __( 'Failed!', 'bbpress' );
200
 
 
 
 
 
201
  // Post types and status
202
  $tpt = bbp_get_topic_post_type();
203
  $rpt = bbp_get_reply_post_type();
204
  $pps = bbp_get_public_status_id();
205
  $cps = bbp_get_closed_status_id();
206
 
207
+ // Delete the meta key _bbp_reply_count for each topic
208
+ $sql_delete = "DELETE `postmeta` FROM `{$wpdb->postmeta}` AS `postmeta`
209
+ LEFT JOIN `{$wpdb->posts}` AS `posts` ON `posts`.`ID` = `postmeta`.`post_id`
210
+ WHERE `posts`.`post_type` = '{$tpt}'
211
+ AND `postmeta`.`meta_key` = '_bbp_reply_count'";
212
+
213
+ if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) {
214
+ return array( 1, sprintf( $statement, $result ) );
215
+ }
216
+
217
+ // Recalculate the meta key _bbp_reply_count for each topic
218
  $sql = "INSERT INTO `{$wpdb->postmeta}` (`post_id`, `meta_key`, `meta_value`) (
219
  SELECT `topics`.`ID` AS `post_id`, '_bbp_reply_count' AS `meta_key`, COUNT(`replies`.`ID`) As `meta_value`
220
  FROM `{$wpdb->posts}` AS `topics`
226
  AND `topics`.`post_status` IN ( '{$pps}', '{$cps}' )
227
  GROUP BY `topics`.`ID`);";
228
 
229
+ if ( is_wp_error( $wpdb->query( $sql ) ) ) {
230
  return array( 2, sprintf( $statement, $result ) );
231
+ }
232
 
233
  return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
234
  }
487
  $statement = __( 'Counting the number of replies in each forum… %s', 'bbpress' );
488
  $result = __( 'Failed!', 'bbpress' );
489
 
490
+ // Post type
491
+ $fpt = bbp_get_forum_post_type();
 
492
 
493
+ // Delete the meta keys _bbp_reply_count and _bbp_total_reply_count for each forum
494
+ $sql_delete = "DELETE `postmeta` FROM `{$wpdb->postmeta}` AS `postmeta`
495
+ LEFT JOIN `{$wpdb->posts}` AS `posts` ON `posts`.`ID` = `postmeta`.`post_id`
496
+ WHERE `posts`.`post_type` = '{$fpt}'
497
+ AND `postmeta`.`meta_key` = '_bbp_reply_count'
498
+ OR `postmeta`.`meta_key` = '_bbp_total_reply_count'";
499
+
500
+ if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) {
501
+ return array( 1, sprintf( $statement, $result ) );
502
+ }
503
+
504
+ // Recalculate the metas key _bbp_reply_count and _bbp_total_reply_count for each forum
505
  $forums = get_posts( array( 'post_type' => bbp_get_forum_post_type(), 'numberposts' => -1 ) );
506
  if ( !empty( $forums ) ) {
507
  foreach ( $forums as $forum ) {
1130
  return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
1131
  }
1132
 
1133
+ /**
1134
+ * Recalculate reply menu order
1135
+ *
1136
+ * @since bbPress (r5367)
1137
+ *
1138
+ * @uses wpdb::query() To run our recount sql queries
1139
+ * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
1140
+ * @uses bbp_get_reply_post_type() To get the reply post type
1141
+ * @uses bbp_update_reply_position() To update the reply position
1142
+ * @return array An array of the status code and the message
1143
+ */
1144
+ function bbp_admin_repair_reply_menu_order() {
1145
+ global $wpdb;
1146
+
1147
+ $statement = __( 'Recalculating reply menu order … %s', 'bbpress' );
1148
+ $result = __( 'No reply positions to recalculate!', 'bbpress' );
1149
+
1150
+ // Delete cases where `_bbp_reply_to` was accidentally set to itself
1151
+ if ( is_wp_error( $wpdb->query( "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` = '_bbp_reply_to' AND `post_id` = `meta_value`;" ) ) ) {
1152
+ return array( 1, sprintf( $statement, $result ) );
1153
+ }
1154
+
1155
+ // Post type
1156
+ $rpt = bbp_get_reply_post_type();
1157
+
1158
+ // Get an array of reply id's to update the menu oder for each reply
1159
+ $replies = $wpdb->get_results( "SELECT `a`.`ID` FROM `{$wpdb->posts}` AS `a`
1160
+ INNER JOIN (
1161
+ SELECT `menu_order`, `post_parent`
1162
+ FROM `{$wpdb->posts}`
1163
+ GROUP BY `menu_order`, `post_parent`
1164
+ HAVING COUNT( * ) >1
1165
+ )`b`
1166
+ ON `a`.`menu_order` = `b`.`menu_order`
1167
+ AND `a`.`post_parent` = `b`.`post_parent`
1168
+ WHERE `post_type` = '{$rpt}';", OBJECT_K );
1169
+
1170
+ // Bail if no replies returned
1171
+ if ( empty( $replies ) ) {
1172
+ return array( 1, sprintf( $statement, $result ) );
1173
+ }
1174
+
1175
+ // Recalculate the menu order position for each reply
1176
+ foreach ( $replies as $reply ) {
1177
+ bbp_update_reply_position( $reply->ID );
1178
+ }
1179
+
1180
+ // Cleanup
1181
+ unset( $replies, $reply );
1182
+
1183
+ // Flush the cache; things are about to get ugly.
1184
+ wp_cache_flush();
1185
+
1186
+ return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
1187
+ }
1188
+
1189
  /** Reset ********************************************************************/
1190
 
1191
  /**
includes/common/functions.php CHANGED
@@ -987,6 +987,12 @@ function bbp_check_for_blacklist( $anonymous_data = false, $author_id = 0, $titl
987
  * Gets new post's ID and check if there are subscribed users to that topic, and
988
  * if there are, send notifications
989
  *
 
 
 
 
 
 
990
  * @since bbPress (r2668)
991
  *
992
  * @param int $reply_id ID of the newly made reply
@@ -1017,8 +1023,9 @@ function bbp_check_for_blacklist( $anonymous_data = false, $author_id = 0, $titl
1017
  function bbp_notify_subscribers( $reply_id = 0, $topic_id = 0, $forum_id = 0, $anonymous_data = false, $reply_author = 0 ) {
1018
 
1019
  // Bail if subscriptions are turned off
1020
- if ( !bbp_is_subscriptions_active() )
1021
  return false;
 
1022
 
1023
  /** Validation ************************************************************/
1024
 
@@ -1026,52 +1033,39 @@ function bbp_notify_subscribers( $reply_id = 0, $topic_id = 0, $forum_id = 0, $a
1026
  $topic_id = bbp_get_topic_id( $topic_id );
1027
  $forum_id = bbp_get_forum_id( $forum_id );
1028
 
1029
- /** Reply *****************************************************************/
1030
-
1031
- // Bail if reply is not published
1032
- if ( !bbp_is_reply_published( $reply_id ) )
1033
- return false;
1034
-
1035
  /** Topic *****************************************************************/
1036
 
1037
  // Bail if topic is not published
1038
- if ( !bbp_is_topic_published( $topic_id ) )
1039
  return false;
 
1040
 
1041
- /** User ******************************************************************/
1042
 
1043
- // Get topic subscribers and bail if empty
1044
- $user_ids = bbp_get_topic_subscribers( $topic_id, true );
1045
- if ( empty( $user_ids ) )
1046
  return false;
 
1047
 
1048
  // Poster name
1049
  $reply_author_name = bbp_get_reply_author_display_name( $reply_id );
1050
 
1051
  /** Mail ******************************************************************/
1052
 
1053
- do_action( 'bbp_pre_notify_subscribers', $reply_id, $topic_id, $user_ids );
1054
-
1055
  // Remove filters from reply content and topic title to prevent content
1056
  // from being encoded with HTML entities, wrapped in paragraph tags, etc...
1057
  remove_all_filters( 'bbp_get_reply_content' );
1058
  remove_all_filters( 'bbp_get_topic_title' );
1059
 
1060
- // Strip tags from text
1061
  $topic_title = strip_tags( bbp_get_topic_title( $topic_id ) );
1062
  $reply_content = strip_tags( bbp_get_reply_content( $reply_id ) );
1063
  $reply_url = bbp_get_reply_url( $reply_id );
1064
  $blog_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
 
1065
 
1066
- // Loop through users
1067
- foreach ( (array) $user_ids as $user_id ) {
1068
-
1069
- // Don't send notifications to the person who made the post
1070
- if ( !empty( $reply_author ) && (int) $user_id === (int) $reply_author )
1071
- continue;
1072
-
1073
- // For plugins to filter messages per reply/topic/user
1074
- $message = sprintf( __( '%1$s wrote:
1075
 
1076
  %2$s
1077
 
@@ -1083,30 +1077,58 @@ You are receiving this email because you subscribed to a forum topic.
1083
 
1084
  Login and visit the topic to unsubscribe from these emails.', 'bbpress' ),
1085
 
1086
- $reply_author_name,
1087
- $reply_content,
1088
- $reply_url
1089
- );
1090
 
1091
- $message = apply_filters( 'bbp_subscription_mail_message', $message, $reply_id, $topic_id, $user_id );
1092
- if ( empty( $message ) )
1093
- continue;
 
1094
 
1095
- // For plugins to filter titles per reply/topic/user
1096
- $subject = apply_filters( 'bbp_subscription_mail_title', '[' . $blog_name . '] ' . $topic_title, $reply_id, $topic_id, $user_id );
1097
- if ( empty( $subject ) )
1098
- continue;
 
1099
 
1100
- // Custom headers
1101
- $headers = apply_filters( 'bbp_subscription_mail_headers', array() );
1102
 
1103
- // Get user data of this user
1104
- $user = get_userdata( $user_id );
1105
 
1106
- // Send notification email
1107
- wp_mail( $user->user_email, $subject, $message, $headers );
 
 
 
 
 
1108
  }
1109
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1110
  do_action( 'bbp_post_notify_subscribers', $reply_id, $topic_id, $user_ids );
1111
 
1112
  return true;
@@ -1115,9 +1137,15 @@ Login and visit the topic to unsubscribe from these emails.', 'bbpress' ),
1115
  /**
1116
  * Sends notification emails for new topics to subscribed forums
1117
  *
1118
- * Gets new post's ID and check if there are subscribed users to that topic, and
1119
  * if there are, send notifications
1120
  *
 
 
 
 
 
 
1121
  * @since bbPress (r5156)
1122
  *
1123
  * @param int $topic_id ID of the newly made reply
@@ -1143,8 +1171,9 @@ Login and visit the topic to unsubscribe from these emails.', 'bbpress' ),
1143
  function bbp_notify_forum_subscribers( $topic_id = 0, $forum_id = 0, $anonymous_data = false, $topic_author = 0 ) {
1144
 
1145
  // Bail if subscriptions are turned off
1146
- if ( !bbp_is_subscriptions_active() )
1147
  return false;
 
1148
 
1149
  /** Validation ************************************************************/
1150
 
@@ -1154,43 +1183,29 @@ function bbp_notify_forum_subscribers( $topic_id = 0, $forum_id = 0, $anonymous_
1154
  /** Topic *****************************************************************/
1155
 
1156
  // Bail if topic is not published
1157
- if ( ! bbp_is_topic_published( $topic_id ) )
1158
- return false;
1159
-
1160
- /** User ******************************************************************/
1161
-
1162
- // Get forum subscribers and bail if empty
1163
- $user_ids = bbp_get_forum_subscribers( $forum_id, true );
1164
- if ( empty( $user_ids ) )
1165
  return false;
 
1166
 
1167
  // Poster name
1168
  $topic_author_name = bbp_get_topic_author_display_name( $topic_id );
1169
 
1170
  /** Mail ******************************************************************/
1171
 
1172
- do_action( 'bbp_pre_notify_forum_subscribers', $topic_id, $forum_id, $user_ids );
1173
-
1174
  // Remove filters from reply content and topic title to prevent content
1175
  // from being encoded with HTML entities, wrapped in paragraph tags, etc...
1176
  remove_all_filters( 'bbp_get_topic_content' );
1177
  remove_all_filters( 'bbp_get_topic_title' );
1178
 
1179
- // Strip tags from text
1180
  $topic_title = strip_tags( bbp_get_topic_title( $topic_id ) );
1181
  $topic_content = strip_tags( bbp_get_topic_content( $topic_id ) );
1182
  $topic_url = get_permalink( $topic_id );
1183
  $blog_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
 
1184
 
1185
- // Loop through users
1186
- foreach ( (array) $user_ids as $user_id ) {
1187
-
1188
- // Don't send notifications to the person who made the post
1189
- if ( !empty( $topic_author ) && (int) $user_id === (int) $topic_author )
1190
- continue;
1191
-
1192
- // For plugins to filter messages per reply/topic/user
1193
- $message = sprintf( __( '%1$s wrote:
1194
 
1195
  %2$s
1196
 
@@ -1202,29 +1217,58 @@ You are receiving this email because you subscribed to a forum.
1202
 
1203
  Login and visit the topic to unsubscribe from these emails.', 'bbpress' ),
1204
 
1205
- $topic_author_name,
1206
- $topic_content,
1207
- $topic_url
1208
- );
1209
- $message = apply_filters( 'bbp_forum_subscription_mail_message', $message, $topic_id, $forum_id, $user_id );
1210
- if ( empty( $message ) )
1211
- continue;
1212
 
1213
- // For plugins to filter titles per reply/topic/user
1214
- $subject = apply_filters( 'bbp_forum_subscription_mail_title', '[' . $blog_name . '] ' . $topic_title, $topic_id, $forum_id, $user_id );
1215
- if ( empty( $subject ) )
1216
- continue;
1217
 
1218
- // Custom headers
1219
- $headers = apply_filters( 'bbp_forum_subscription_mail_headers', array() );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1220
 
1221
- // Get user data of this user
1222
- $user = get_userdata( $user_id );
 
 
1223
 
1224
- // Send notification email
1225
- wp_mail( $user->user_email, $subject, $message, $headers );
1226
  }
1227
 
 
 
 
 
 
 
 
 
 
 
1228
  do_action( 'bbp_post_notify_forum_subscribers', $topic_id, $forum_id, $user_ids );
1229
 
1230
  return true;
987
  * Gets new post's ID and check if there are subscribed users to that topic, and
988
  * if there are, send notifications
989
  *
990
+ * Note: in bbPress 2.6, we've moved away from 1 email per subscriber to 1 email
991
+ * with everyone BCC'd. This may have negative repercussions for email services
992
+ * that limit the number of addresses in a BCC field (often to around 500.) In
993
+ * those cases, we recommend unhooking this function and creating your own
994
+ * custom emailer script.
995
+ *
996
  * @since bbPress (r2668)
997
  *
998
  * @param int $reply_id ID of the newly made reply
1023
  function bbp_notify_subscribers( $reply_id = 0, $topic_id = 0, $forum_id = 0, $anonymous_data = false, $reply_author = 0 ) {
1024
 
1025
  // Bail if subscriptions are turned off
1026
+ if ( !bbp_is_subscriptions_active() ) {
1027
  return false;
1028
+ }
1029
 
1030
  /** Validation ************************************************************/
1031
 
1033
  $topic_id = bbp_get_topic_id( $topic_id );
1034
  $forum_id = bbp_get_forum_id( $forum_id );
1035
 
 
 
 
 
 
 
1036
  /** Topic *****************************************************************/
1037
 
1038
  // Bail if topic is not published
1039
+ if ( !bbp_is_topic_published( $topic_id ) ) {
1040
  return false;
1041
+ }
1042
 
1043
+ /** Reply *****************************************************************/
1044
 
1045
+ // Bail if reply is not published
1046
+ if ( !bbp_is_reply_published( $reply_id ) ) {
 
1047
  return false;
1048
+ }
1049
 
1050
  // Poster name
1051
  $reply_author_name = bbp_get_reply_author_display_name( $reply_id );
1052
 
1053
  /** Mail ******************************************************************/
1054
 
 
 
1055
  // Remove filters from reply content and topic title to prevent content
1056
  // from being encoded with HTML entities, wrapped in paragraph tags, etc...
1057
  remove_all_filters( 'bbp_get_reply_content' );
1058
  remove_all_filters( 'bbp_get_topic_title' );
1059
 
1060
+ // Strip tags from text and setup mail data
1061
  $topic_title = strip_tags( bbp_get_topic_title( $topic_id ) );
1062
  $reply_content = strip_tags( bbp_get_reply_content( $reply_id ) );
1063
  $reply_url = bbp_get_reply_url( $reply_id );
1064
  $blog_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
1065
+ $do_not_reply = '<noreply@' . ltrim( get_home_url(), '^(http|https)://' ) . '>';
1066
 
1067
+ // For plugins to filter messages per reply/topic/user
1068
+ $message = sprintf( __( '%1$s wrote:
 
 
 
 
 
 
 
1069
 
1070
  %2$s
1071
 
1077
 
1078
  Login and visit the topic to unsubscribe from these emails.', 'bbpress' ),
1079
 
1080
+ $reply_author_name,
1081
+ $reply_content,
1082
+ $reply_url
1083
+ );
1084
 
1085
+ $message = apply_filters( 'bbp_subscription_mail_message', $message, $reply_id, $topic_id );
1086
+ if ( empty( $message ) ) {
1087
+ return;
1088
+ }
1089
 
1090
+ // For plugins to filter titles per reply/topic/user
1091
+ $subject = apply_filters( 'bbp_subscription_mail_title', '[' . $blog_name . '] ' . $topic_title, $reply_id, $topic_id );
1092
+ if ( empty( $subject ) ) {
1093
+ return;
1094
+ }
1095
 
1096
+ /** Users *****************************************************************/
 
1097
 
1098
+ // Array to hold BCC's
1099
+ $headers = array();
1100
 
1101
+ // Setup the From header
1102
+ $headers[] = 'From: ' . get_bloginfo( 'name' ) . ' ' . $do_not_reply;
1103
+
1104
+ // Get topic subscribers and bail if empty
1105
+ $user_ids = bbp_get_topic_subscribers( $topic_id, true );
1106
+ if ( empty( $user_ids ) ) {
1107
+ return false;
1108
  }
1109
 
1110
+ // Loop through users
1111
+ foreach ( (array) $user_ids as $user_id ) {
1112
+
1113
+ // Don't send notifications to the person who made the post
1114
+ if ( !empty( $reply_author ) && (int) $user_id === (int) $reply_author ) {
1115
+ continue;
1116
+ }
1117
+
1118
+ // Get email address of subscribed user
1119
+ $headers[] = 'Bcc: ' . get_userdata( $user_id )->user_email;
1120
+ }
1121
+
1122
+ /** Send it ***************************************************************/
1123
+
1124
+ // Custom headers
1125
+ $headers = apply_filters( 'bbp_subscription_mail_headers', $headers );
1126
+
1127
+ do_action( 'bbp_pre_notify_subscribers', $reply_id, $topic_id, $user_ids );
1128
+
1129
+ // Send notification email
1130
+ wp_mail( $do_not_reply, $subject, $message, $headers );
1131
+
1132
  do_action( 'bbp_post_notify_subscribers', $reply_id, $topic_id, $user_ids );
1133
 
1134
  return true;
1137
  /**
1138
  * Sends notification emails for new topics to subscribed forums
1139
  *
1140
+ * Gets new post's ID and check if there are subscribed users to that forum, and
1141
  * if there are, send notifications
1142
  *
1143
+ * Note: in bbPress 2.6, we've moved away from 1 email per subscriber to 1 email
1144
+ * with everyone BCC'd. This may have negative repercussions for email services
1145
+ * that limit the number of addresses in a BCC field (often to around 500.) In
1146
+ * those cases, we recommend unhooking this function and creating your own
1147
+ * custom emailer script.
1148
+ *
1149
  * @since bbPress (r5156)
1150
  *
1151
  * @param int $topic_id ID of the newly made reply
1171
  function bbp_notify_forum_subscribers( $topic_id = 0, $forum_id = 0, $anonymous_data = false, $topic_author = 0 ) {
1172
 
1173
  // Bail if subscriptions are turned off
1174
+ if ( !bbp_is_subscriptions_active() ) {
1175
  return false;
1176
+ }
1177
 
1178
  /** Validation ************************************************************/
1179
 
1183
  /** Topic *****************************************************************/
1184
 
1185
  // Bail if topic is not published
1186
+ if ( ! bbp_is_topic_published( $topic_id ) ) {
 
 
 
 
 
 
 
1187
  return false;
1188
+ }
1189
 
1190
  // Poster name
1191
  $topic_author_name = bbp_get_topic_author_display_name( $topic_id );
1192
 
1193
  /** Mail ******************************************************************/
1194
 
 
 
1195
  // Remove filters from reply content and topic title to prevent content
1196
  // from being encoded with HTML entities, wrapped in paragraph tags, etc...
1197
  remove_all_filters( 'bbp_get_topic_content' );
1198
  remove_all_filters( 'bbp_get_topic_title' );
1199
 
1200
+ // Strip tags from text and setup mail data
1201
  $topic_title = strip_tags( bbp_get_topic_title( $topic_id ) );
1202
  $topic_content = strip_tags( bbp_get_topic_content( $topic_id ) );
1203
  $topic_url = get_permalink( $topic_id );
1204
  $blog_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
1205
+ $do_not_reply = '<noreply@' . ltrim( get_home_url(), '^(http|https)://' ) . '>';
1206
 
1207
+ // For plugins to filter messages per reply/topic/user
1208
+ $message = sprintf( __( '%1$s wrote:
 
 
 
 
 
 
 
1209
 
1210
  %2$s
1211
 
1217
 
1218
  Login and visit the topic to unsubscribe from these emails.', 'bbpress' ),
1219
 
1220
+ $topic_author_name,
1221
+ $topic_content,
1222
+ $topic_url
1223
+ );
 
 
 
1224
 
1225
+ $message = apply_filters( 'bbp_forum_subscription_mail_message', $message, $topic_id, $forum_id, $user_id );
1226
+ if ( empty( $message ) ) {
1227
+ return;
1228
+ }
1229
 
1230
+ // For plugins to filter titles per reply/topic/user
1231
+ $subject = apply_filters( 'bbp_forum_subscription_mail_title', '[' . $blog_name . '] ' . $topic_title, $topic_id, $forum_id, $user_id );
1232
+ if ( empty( $subject ) ) {
1233
+ return;
1234
+ }
1235
+
1236
+ /** User ******************************************************************/
1237
+
1238
+ // Array to hold BCC's
1239
+ $headers = array();
1240
+
1241
+ // Setup the From header
1242
+ $headers[] = 'From: ' . get_bloginfo( 'name' ) . ' ' . $do_not_reply;
1243
+
1244
+ // Get topic subscribers and bail if empty
1245
+ $user_ids = bbp_get_forum_subscribers( $forum_id, true );
1246
+ if ( empty( $user_ids ) ) {
1247
+ return false;
1248
+ }
1249
+
1250
+ // Loop through users
1251
+ foreach ( (array) $user_ids as $user_id ) {
1252
 
1253
+ // Don't send notifications to the person who made the post
1254
+ if ( !empty( $topic_author ) && (int) $user_id === (int) $topic_author ) {
1255
+ continue;
1256
+ }
1257
 
1258
+ // Get email address of subscribed user
1259
+ $headers[] = 'Bcc: ' . get_userdata( $user_id )->user_email;
1260
  }
1261
 
1262
+ /** Send it ***************************************************************/
1263
+
1264
+ // Custom headers
1265
+ $headers = apply_filters( 'bbp_subscription_mail_headers', $headers );
1266
+
1267
+ do_action( 'bbp_pre_notify_forum_subscribers', $topic_id, $forum_id, $user_ids );
1268
+
1269
+ // Send notification email
1270
+ wp_mail( $do_not_reply, $subject, $message, $headers );
1271
+
1272
  do_action( 'bbp_post_notify_forum_subscribers', $topic_id, $forum_id, $user_ids );
1273
 
1274
  return true;
includes/core/filters.php CHANGED
@@ -182,6 +182,9 @@ add_filter( 'bbp_get_topic_voice_count', 'bbp_number_format', 10 );
182
  add_filter( 'bbp_get_topic_reply_count', 'bbp_number_format', 10 );
183
  add_filter( 'bbp_get_topic_post_count', 'bbp_number_format', 10 );
184
 
 
 
 
185
  // Run wp_kses_data on topic/reply content in admin section
186
  if ( is_admin() ) {
187
  add_filter( 'bbp_get_reply_content', 'bbp_kses_data' );
182
  add_filter( 'bbp_get_topic_reply_count', 'bbp_number_format', 10 );
183
  add_filter( 'bbp_get_topic_post_count', 'bbp_number_format', 10 );
184
 
185
+ // Sanitize displayed user data
186
+ add_filter( 'bbp_get_displayed_user_field', 'bbp_sanitize_displayed_user_field', 10, 3 );
187
+
188
  // Run wp_kses_data on topic/reply content in admin section
189
  if ( is_admin() ) {
190
  add_filter( 'bbp_get_reply_content', 'bbp_kses_data' );
includes/core/template-functions.php CHANGED
@@ -168,7 +168,7 @@ function bbp_enqueue_style( $handle = '', $file = '', $dependencies = array(), $
168
  }
169
 
170
  // Make path to file relative to site URL
171
- $located = str_replace( $content_dir, WP_CONTENT_URL, $located );
172
 
173
  // Enqueue the style
174
  wp_enqueue_style( $handle, $located, $dependencies, $version, $media );
@@ -236,7 +236,7 @@ function bbp_enqueue_script( $handle = '', $file = '', $dependencies = array(),
236
  }
237
 
238
  // Make path to file relative to site URL
239
- $located = str_replace( $content_dir, WP_CONTENT_URL, $located );
240
 
241
  // Enqueue the style
242
  wp_enqueue_script( $handle, $located, $dependencies, $version, $in_footer );
168
  }
169
 
170
  // Make path to file relative to site URL
171
+ $located = str_replace( $content_dir, content_url(), $located );
172
 
173
  // Enqueue the style
174
  wp_enqueue_style( $handle, $located, $dependencies, $version, $media );
236
  }
237
 
238
  // Make path to file relative to site URL
239
+ $located = str_replace( $content_dir, content_url(), $located );
240
 
241
  // Enqueue the style
242
  wp_enqueue_script( $handle, $located, $dependencies, $version, $in_footer );
includes/replies/functions.php CHANGED
@@ -249,15 +249,6 @@ function bbp_new_reply_handler( $action = '' ) {
249
  }
250
  }
251
 
252
- /** Reply To **************************************************************/
253
-
254
- // Handle Reply To of the reply; $_REQUEST for non-JS submissions
255
- if ( isset( $_REQUEST['bbp_reply_to'] ) ) {
256
- $reply_to = (int) $_REQUEST['bbp_reply_to'];
257
- }
258
-
259
- $reply_to = bbp_get_reply_id( $reply_to );
260
-
261
  /** Unfiltered HTML *******************************************************/
262
 
263
  // Remove kses filters from title and content for capable users and if the nonce is verified
@@ -313,6 +304,13 @@ function bbp_new_reply_handler( $action = '' ) {
313
  $reply_status = bbp_get_public_status_id();
314
  }
315
 
 
 
 
 
 
 
 
316
  /** Topic Closed **********************************************************/
317
 
318
  // If topic is closed, moderators can still reply
@@ -562,10 +560,6 @@ function bbp_edit_reply_handler( $action = '' ) {
562
 
563
  $forum_id = bbp_get_topic_forum_id( $topic_id );
564
 
565
- /** Reply To **************************************************************/
566
-
567
- $reply_to = bbp_get_reply_to( $reply_id );
568
-
569
  // Forum exists
570
  if ( !empty( $forum_id ) && ( $forum_id !== bbp_get_reply_forum_id( $reply_id ) ) ) {
571
 
@@ -636,6 +630,13 @@ function bbp_edit_reply_handler( $action = '' ) {
636
  $reply_status = $reply->post_status;
637
  }
638
 
 
 
 
 
 
 
 
639
  /** Topic Tags ************************************************************/
640
 
641
  // Either replace terms
@@ -793,7 +794,7 @@ function bbp_update_reply( $reply_id = 0, $topic_id = 0, $forum_id = 0, $anonymo
793
  $reply_id = bbp_get_reply_id( $reply_id );
794
  $topic_id = bbp_get_topic_id( $topic_id );
795
  $forum_id = bbp_get_forum_id( $forum_id );
796
- $reply_to = bbp_get_reply_id( $reply_to );
797
 
798
  // Bail if there is no reply
799
  if ( empty( $reply_id ) )
@@ -1112,19 +1113,19 @@ function bbp_update_reply_to( $reply_id = 0, $reply_to = 0 ) {
1112
 
1113
  // Validation
1114
  $reply_id = bbp_get_reply_id( $reply_id );
1115
- $reply_to = bbp_get_reply_id( $reply_to );
1116
 
1117
- // Return if no reply
1118
- if ( empty( $reply_id ) )
1119
- return;
1120
 
1121
- // Set the reply to
1122
- if ( !empty( $reply_to ) ) {
1123
- update_post_meta( $reply_id, '_bbp_reply_to', $reply_to );
1124
 
1125
- // Delete the reply to
1126
- } else {
1127
- delete_post_meta( $reply_id, '_bbp_reply_to' );
 
1128
  }
1129
 
1130
  return (int) apply_filters( 'bbp_update_reply_to', (int) $reply_to, $reply_id );
@@ -2218,3 +2219,32 @@ function bbp_list_replies( $args = array() ) {
2218
  bbpress()->max_num_pages = $walker->max_pages;
2219
  bbpress()->reply_query->in_the_loop = false;
2220
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  }
250
  }
251
 
 
 
 
 
 
 
 
 
 
252
  /** Unfiltered HTML *******************************************************/
253
 
254
  // Remove kses filters from title and content for capable users and if the nonce is verified
304
  $reply_status = bbp_get_public_status_id();
305
  }
306
 
307
+ /** Reply To **************************************************************/
308
+
309
+ // Handle Reply To of the reply; $_REQUEST for non-JS submissions
310
+ if ( isset( $_REQUEST['bbp_reply_to'] ) ) {
311
+ $reply_to = bbp_validate_reply_to( $_REQUEST['bbp_reply_to'] );
312
+ }
313
+
314
  /** Topic Closed **********************************************************/
315
 
316
  // If topic is closed, moderators can still reply
560
 
561
  $forum_id = bbp_get_topic_forum_id( $topic_id );
562
 
 
 
 
 
563
  // Forum exists
564
  if ( !empty( $forum_id ) && ( $forum_id !== bbp_get_reply_forum_id( $reply_id ) ) ) {
565
 
630
  $reply_status = $reply->post_status;
631
  }
632
 
633
+ /** Reply To **************************************************************/
634
+
635
+ // Handle Reply To of the reply; $_REQUEST for non-JS submissions
636
+ if ( isset( $_REQUEST['bbp_reply_to'] ) ) {
637
+ $reply_to = bbp_validate_reply_to( $_REQUEST['bbp_reply_to'] );
638
+ }
639
+
640
  /** Topic Tags ************************************************************/
641
 
642
  // Either replace terms
794
  $reply_id = bbp_get_reply_id( $reply_id );
795
  $topic_id = bbp_get_topic_id( $topic_id );
796
  $forum_id = bbp_get_forum_id( $forum_id );
797
+ $reply_to = bbp_validate_reply_to( $reply_to );
798
 
799
  // Bail if there is no reply
800
  if ( empty( $reply_id ) )
1113
 
1114
  // Validation
1115
  $reply_id = bbp_get_reply_id( $reply_id );
1116
+ $reply_to = bbp_validate_reply_to( $reply_to );
1117
 
1118
+ // Update or delete the `reply_to` postmeta
1119
+ if ( ! empty( $reply_id ) ) {
 
1120
 
1121
+ // Update the reply to
1122
+ if ( !empty( $reply_to ) ) {
1123
+ update_post_meta( $reply_id, '_bbp_reply_to', $reply_to );
1124
 
1125
+ // Delete the reply to
1126
+ } else {
1127
+ delete_post_meta( $reply_id, '_bbp_reply_to' );
1128
+ }
1129
  }
1130
 
1131
  return (int) apply_filters( 'bbp_update_reply_to', (int) $reply_to, $reply_id );
2219
  bbpress()->max_num_pages = $walker->max_pages;
2220
  bbpress()->reply_query->in_the_loop = false;
2221
  }
2222
+
2223
+ /**
2224
+ * Validate a `reply_to` field for hierarchical replies
2225
+ *
2226
+ * Checks for 2 scenarios:
2227
+ * -- The reply to ID is actually a reply
2228
+ * -- The reply to ID does not match the current reply
2229
+ *
2230
+ * @since bbPress (r5377)
2231
+ *
2232
+ * @param int $reply_to
2233
+ * @param int $reply_id
2234
+ *
2235
+ * @return int $reply_to
2236
+ */
2237
+ function bbp_validate_reply_to( $reply_to = 0, $reply_id = 0 ) {
2238
+
2239
+ // The parent reply must actually be a reply
2240
+ if ( ! bbp_is_reply( $reply_to ) ) {
2241
+ $reply_to = 0;
2242
+ }
2243
+
2244
+ // The parent reply cannot be itself
2245
+ if ( $reply_id === $reply_to ) {
2246
+ $reply_to = 0;
2247
+ }
2248
+
2249
+ return (int) $reply_to;
2250
+ }
includes/replies/template.php CHANGED
@@ -1576,10 +1576,12 @@ function bbp_reply_to( $reply_id = 0 ) {
1576
  $reply_to = 0;
1577
 
1578
  // Check that reply_id is valid
1579
- if ( $reply_id = bbp_get_reply_id( $reply_id ) )
1580
 
1581
- // Get reply_to value
 
1582
  $reply_to = (int) get_post_meta( $reply_id, '_bbp_reply_to', true );
 
1583
 
1584
  return (int) apply_filters( 'bbp_get_reply_to', $reply_to, $reply_id );
1585
  }
@@ -2463,7 +2465,7 @@ function bbp_form_reply_to() {
2463
 
2464
  // Get $_REQUEST data
2465
  if ( isset( $_REQUEST['bbp_reply_to'] ) ) {
2466
- $reply_to = (int) $_REQUEST['bbp_reply_to'];
2467
  }
2468
 
2469
  // If empty, get from meta
@@ -2471,9 +2473,6 @@ function bbp_form_reply_to() {
2471
  $reply_to = bbp_get_reply_to();
2472
  }
2473
 
2474
- // Validate
2475
- $reply_to = bbp_get_reply_id( $reply_to );
2476
-
2477
  return (int) apply_filters( 'bbp_get_form_reply_to', $reply_to );
2478
  }
2479
 
1576
  $reply_to = 0;
1577
 
1578
  // Check that reply_id is valid
1579
+ $reply_id = bbp_get_reply_id( $reply_id );
1580
 
1581
+ // Get reply_to value
1582
+ if ( !empty( $reply_id ) ) {
1583
  $reply_to = (int) get_post_meta( $reply_id, '_bbp_reply_to', true );
1584
+ }
1585
 
1586
  return (int) apply_filters( 'bbp_get_reply_to', $reply_to, $reply_id );
1587
  }
2465
 
2466
  // Get $_REQUEST data
2467
  if ( isset( $_REQUEST['bbp_reply_to'] ) ) {
2468
+ $reply_to = bbp_validate_reply_to( $_REQUEST['bbp_reply_to'] );
2469
  }
2470
 
2471
  // If empty, get from meta
2473
  $reply_to = bbp_get_reply_to();
2474
  }
2475
 
 
 
 
2476
  return (int) apply_filters( 'bbp_get_form_reply_to', $reply_to );
2477
  }
2478
 
includes/topics/functions.php CHANGED
@@ -1672,7 +1672,7 @@ function bbp_split_topic_handler( $action = '' ) {
1672
  }
1673
 
1674
  // New topic from reply can't be a reply to
1675
- if ( ( $from_reply->ID === $destination_topic->ID && $from_reply->ID === $reply_to ) ) {
1676
  bbp_update_reply_to( $reply->ID, 0 );
1677
  }
1678
 
1672
  }
1673
 
1674
  // New topic from reply can't be a reply to
1675
+ if ( ( $from_reply->ID === $destination_topic->ID ) && ( $from_reply->ID === $reply_to ) ) {
1676
  bbp_update_reply_to( $reply->ID, 0 );
1677
  }
1678
 
includes/users/functions.php CHANGED
@@ -1603,6 +1603,75 @@ function bbp_forum_enforce_blocked() {
1603
  }
1604
  }
1605
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1606
  /** Converter *****************************************************************/
1607
 
1608
  /**
1603
  }
1604
  }
1605
 
1606
+ /** Sanitization **************************************************************/
1607
+
1608
+ /**
1609
+ * Sanitize displayed user data, when viewing and editing any user.
1610
+ *
1611
+ * This somewhat monolithic function handles the escaping and sanitization of
1612
+ * user data for a bbPress profile. There are two reasons this all happers here:
1613
+ *
1614
+ * 1. bbPress took a similar approach to WordPress, and funnels all user profile
1615
+ * data through a central helper. This eventually calls sanitize_user_field()
1616
+ * which applies a few context based filters, which some third party plugins
1617
+ * might be relying on bbPress to play nicely with.
1618
+ *
1619
+ * 2. Early versions of bbPress 2.x templates did not escape this data meaning
1620
+ * a backwards compatible approach like this one was necessary to protect
1621
+ * existing installations that may have custom template parts.
1622
+ *
1623
+ * @since bbPress (r5368)
1624
+ *
1625
+ * @param string $value
1626
+ * @param string $field
1627
+ * @param string $context
1628
+ * @return string
1629
+ */
1630
+ function bbp_sanitize_displayed_user_field( $value = '', $field = '', $context = 'display' ) {
1631
+
1632
+ // Bail if not editing or displaying (maybe we'll do more here later)
1633
+ if ( ! in_array( $context, array( 'edit', 'display' ) ) ) {
1634
+ return $value;
1635
+ }
1636
+
1637
+ // By default, no filter set (consider making this an array later)
1638
+ $filter = false;
1639
+
1640
+ // Big switch statement to decide which user field we're sanitizing and how
1641
+ switch ( $field ) {
1642
+
1643
+ // Description is a paragraph
1644
+ case 'description' :
1645
+ $filter = ( 'edit' === $context ) ? '' : 'wp_kses_data';
1646
+ break;
1647
+
1648
+ // Email addresses are sanitized with a specific function
1649
+ case 'user_email' :
1650
+ $filter = 'sanitize_email';
1651
+ break;
1652
+
1653
+ // Name & login fields
1654
+ case 'user_login' :
1655
+ case 'display_name' :
1656
+ case 'first_name' :
1657
+ case 'last_name' :
1658
+ case 'nick_name' :
1659
+ $filter = ( 'edit' === $context ) ? 'esc_attr' : 'esc_html';
1660
+ break;
1661
+
1662
+ // wp-includes/default-filters.php escapes this for us via esc_url()
1663
+ case 'user_url' :
1664
+ break;
1665
+ }
1666
+
1667
+ // Run any applicable filters on the value
1668
+ if ( ! empty( $filter ) ) {
1669
+ $value = call_user_func( $filter, $value );
1670
+ }
1671
+
1672
+ return $value;
1673
+ }
1674
+
1675
  /** Converter *****************************************************************/
1676
 
1677
  /**
includes/users/template.php CHANGED
@@ -156,7 +156,7 @@ function bbp_displayed_user_field( $field = '', $filter = 'display' ) {
156
  $user->filter = $old_filter;
157
 
158
  // Return empty
159
- return apply_filters( 'bbp_get_displayed_user_field', $value, $field );
160
  }
161
 
162
  /**
156
  $user->filter = $old_filter;
157
 
158
  // Return empty
159
+ return apply_filters( 'bbp_get_displayed_user_field', $value, $field, $filter );
160
  }
161
 
162
  /**
languages/bbpress.pot CHANGED
@@ -2,7 +2,7 @@
2
  # This file is distributed under the same license as the bbPress package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: bbPress 2.5.3\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/bbpress\n"
7
  "POT-Creation-Date: 2014-01-11 18:30:39+00:00\n"
8
  "MIME-Version: 1.0\n"
@@ -4927,9 +4927,9 @@ msgstr ""
4927
  msgid "bbPress"
4928
  msgstr ""
4929
 
4930
- #. #-#-#-#-# plugin.pot (bbPress 2.5.3) #-#-#-#-#
4931
  #. Plugin URI of the plugin/theme
4932
- #. #-#-#-#-# plugin.pot (bbPress 2.5.3) #-#-#-#-#
4933
  #. Author URI of the plugin/theme
4934
  msgid "http://bbpress.org"
4935
  msgstr ""
2
  # This file is distributed under the same license as the bbPress package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: bbPress 2.5.4\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/bbpress\n"
7
  "POT-Creation-Date: 2014-01-11 18:30:39+00:00\n"
8
  "MIME-Version: 1.0\n"
4927
  msgid "bbPress"
4928
  msgstr ""
4929
 
4930
+ #. #-#-#-#-# plugin.pot (bbPress 2.5.4) #-#-#-#-#
4931
  #. Plugin URI of the plugin/theme
4932
+ #. #-#-#-#-# plugin.pot (bbPress 2.5.4) #-#-#-#-#
4933
  #. Author URI of the plugin/theme
4934
  msgid "http://bbpress.org"
4935
  msgstr ""
readme.txt CHANGED
@@ -2,12 +2,12 @@
2
  Contributors: matt, johnjamesjacoby, jmdodd, netweb
3
  Tags: forums, discussion, support, theme, akismet, multisite
4
  Requires at least: 3.6
5
- Tested up to: 3.9
6
- Stable tag: 2.5.3
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
10
- bbPress is forum software, made the WordPress way
11
 
12
  == Description ==
13
 
@@ -42,6 +42,12 @@ We're keeping things as small and light as possible while still allowing for gre
42
 
43
  == Changelog ==
44
 
 
 
 
 
 
 
45
  = 2.5.3 =
46
  * WordPress 3.8 support (dashicons, new color schemes)
47
  * Fix dropdown selects in settings pages
2
  Contributors: matt, johnjamesjacoby, jmdodd, netweb
3
  Tags: forums, discussion, support, theme, akismet, multisite
4
  Requires at least: 3.6
5
+ Tested up to: 4.1
6
+ Stable tag: 2.5.4
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
10
+ bbPress is forum software, made the WordPress way.
11
 
12
  == Description ==
13
 
42
 
43
  == Changelog ==
44
 
45
+ = 2.5.4 =
46
+ * Fix reply editing causing polluted hierarchy
47
+ * Add tool for repairing reply positions within topics
48
+ * Improved custom slug and displayed user field sanitization
49
+ * Improved SSL support when relying on theme compatibility
50
+
51
  = 2.5.3 =
52
  * WordPress 3.8 support (dashicons, new color schemes)
53
  * Fix dropdown selects in settings pages