BuddyPress - Version 1.1

Version Description

Download this release

Release Info

Developer apeatling
Plugin Icon 128x128 BuddyPress
Version 1.1
Comparing to
See all releases

Code changes from version 1.0.3 to 1.1

Files changed (151) hide show
  1. bp-activity.php +250 -153
  2. bp-activity/bp-activity-classes.php +196 -190
  3. bp-activity/bp-activity-cssjs.php +0 -10
  4. bp-activity/bp-activity-filters.php +19 -6
  5. bp-activity/bp-activity-templatetags.php +162 -59
  6. bp-activity/bp-activity-widgets.php +45 -27
  7. bp-activity/css/widget-activity.css +0 -14
  8. bp-activity/deprecated/bp-activity-deprecated.php +95 -0
  9. bp-activity/{css → deprecated/css}/structure.css +0 -0
  10. bp-activity/{images → deprecated/images}/rss.png +0 -0
  11. bp-activity/feeds/bp-activity-friends-feed.php +2 -2
  12. bp-activity/feeds/bp-activity-personal-feed.php +2 -2
  13. bp-activity/feeds/bp-activity-sitewide-feed.php +2 -2
  14. bp-blogs.php +215 -242
  15. bp-blogs/admin-tabs/bp-blogs-comments-tab.php +1 -1
  16. bp-blogs/admin-tabs/bp-blogs-posts-tab.php +1 -1
  17. bp-blogs/admin-tabs/bp-blogs-tab.php +1 -1
  18. bp-blogs/bp-blogs-ajax.php +0 -12
  19. bp-blogs/bp-blogs-cssjs.php +0 -10
  20. bp-blogs/bp-blogs-templatetags.php +26 -17
  21. bp-blogs/bp-blogs-widgets.php +6 -3
  22. bp-blogs/css/widget-blogs.css +0 -29
  23. bp-blogs/deprecated/bp-blogs-deprecated.php +105 -0
  24. bp-blogs/{css → deprecated/css}/structure.css +0 -0
  25. bp-blogs/{js → deprecated/js}/directory-blogs.js +0 -0
  26. bp-core.php +593 -369
  27. bp-core/bp-core-activation.php +85 -107
  28. bp-core/bp-core-admin.php +30 -2
  29. bp-core/bp-core-adminbar.php +16 -13
  30. bp-core/bp-core-ajax.php +0 -81
  31. bp-core/bp-core-avatars.php +283 -422
  32. bp-core/bp-core-catchuri.php +71 -106
  33. bp-core/bp-core-classes.php +12 -15
  34. bp-core/bp-core-cssjs.php +134 -134
  35. bp-core/bp-core-notifications.php +2 -5
  36. bp-core/bp-core-settings.php +37 -19
  37. bp-core/bp-core-signup.php +183 -382
  38. bp-core/bp-core-templatetags.php +809 -191
  39. bp-core/bp-core-widgets.php +75 -7
  40. bp-core/deprecated/bp-core-deprecated.php +980 -0
  41. bp-core/{css → deprecated/css}/admin-bar.css +6 -1
  42. bp-core/{css → deprecated/css}/structure.css +10 -9
  43. bp-core/{images → deprecated/images}/accept_button_side.gif +0 -0
  44. bp-core/{images → deprecated/images}/add_button_side.gif +0 -0
  45. bp-core/{images → deprecated/images}/add_friend_button.gif +0 -0
  46. bp-core/{images → deprecated/images}/admin-menu-arrow.gif +0 -0
  47. bp-core/{images → deprecated/images}/admin_bar_back.gif +0 -0
  48. bp-core/{images → deprecated/images}/admin_bar_logo.gif +0 -0
  49. bp-core/{images → deprecated/images}/ajax-loader.gif +0 -0
  50. bp-core/{images → deprecated/images}/blog.png +0 -0
  51. bp-core/{images → deprecated/images}/button_back.gif +0 -0
  52. bp-core/{images → deprecated/images}/check_button_side.gif +0 -0
  53. bp-core/{images → deprecated/images}/loading_button_side.gif +0 -0
  54. bp-core/{images → deprecated/images}/logout_bullet.gif +0 -0
  55. bp-core/{images → deprecated/images}/member.png +0 -0
  56. bp-core/{images → deprecated/images}/nav_bullet.gif +0 -0
  57. bp-core/{images → deprecated/images}/reject_button_side.gif +0 -0
  58. bp-core/{images → deprecated/images}/remove_button_side.gif +0 -0
  59. bp-core/{images → deprecated/images}/remove_friend_button.gif +0 -0
  60. bp-core/{images → deprecated/images}/requested_friend_button.gif +0 -0
  61. bp-core/{images → deprecated/images}/view_button_side.gif +0 -0
  62. bp-core/{js → deprecated/js}/directory-members.js +0 -0
  63. bp-core/{js → deprecated/js}/general.js +0 -12
  64. bp-core/{js → deprecated/js}/jquery/jquery.livequery.pack.js +0 -0
  65. bp-core/{js → deprecated/js}/jquery/jquery.tablednd.js +0 -0
  66. bp-core/images/Jcrop.gif +0 -0
  67. bp-core/images/admin_menu_icon.png +0 -0
  68. bp-core/js/admin-bar.js +9 -0
  69. bp-core/js/widget-members.js +1 -2
  70. bp-forums.php +318 -119
  71. bp-forums/bb-config.php +11 -0
  72. bp-forums/bbpress-plugins/buddypress-enable.php +0 -55
  73. bp-forums/bbpress/bb-admin/admin-action.php +5 -0
  74. bp-forums/bbpress/bb-admin/admin-ajax.php +243 -0
  75. bp-forums/bbpress/bb-admin/admin-base.php +19 -0
  76. bp-forums/bbpress/bb-admin/admin-footer.php +33 -0
  77. bp-forums/bbpress/bb-admin/admin-header.php +51 -0
  78. bp-forums/bbpress/bb-admin/admin.php +37 -0
  79. bp-forums/bbpress/bb-admin/bb-forum.php +61 -0
  80. bp-forums/bbpress/bb-admin/delete-post.php +78 -0
  81. bp-forums/bbpress/bb-admin/delete-topic.php +53 -0
  82. bp-forums/bbpress/bb-admin/export.php +306 -0
  83. bp-forums/bbpress/bb-admin/forums.php +106 -0
  84. bp-forums/bbpress/bb-admin/images/admin-header-logo.gif +0 -0
  85. bp-forums/bbpress/bb-admin/images/bbpress-logo.png +0 -0
  86. bp-forums/bbpress/bb-admin/images/blank.gif +0 -0
  87. bp-forums/bbpress/bb-admin/images/button-grad.png +0 -0
  88. bp-forums/bbpress/bb-admin/images/drag.gif +0 -0
  89. bp-forums/bbpress/bb-admin/images/gray-grad.png +0 -0
  90. bp-forums/bbpress/bb-admin/images/icons32.png +0 -0
  91. bp-forums/bbpress/bb-admin/images/input-lock.png +0 -0
  92. bp-forums/bbpress/bb-admin/images/menu-arrows.gif +0 -0
  93. bp-forums/bbpress/bb-admin/images/menu-bits-rtl.gif +0 -0
  94. bp-forums/bbpress/bb-admin/images/menu-bits.gif +0 -0
  95. bp-forums/bbpress/bb-admin/images/menu-dark-rtl.gif +0 -0
  96. bp-forums/bbpress/bb-admin/images/menu-dark.gif +0 -0
  97. bp-forums/bbpress/bb-admin/images/menu.png +0 -0
  98. bp-forums/bbpress/bb-admin/images/visit-site-button-grad.gif +0 -0
  99. bp-forums/bbpress/bb-admin/images/white-grad-active.png +0 -0
  100. bp-forums/bbpress/bb-admin/images/white-grad.png +0 -0
  101. bp-forums/bbpress/bb-admin/includes/class.bb-install.php +2763 -0
  102. bp-forums/bbpress/bb-admin/includes/defaults.bb-htaccess.php +46 -0
  103. bp-forums/bbpress/bb-admin/includes/defaults.bb-schema.php +219 -0
  104. bp-forums/bbpress/bb-admin/includes/functions.bb-admin.php +1432 -0
  105. bp-forums/bbpress/bb-admin/includes/functions.bb-plugin.php +441 -0
  106. bp-forums/bbpress/bb-admin/includes/functions.bb-upgrade.php +503 -0
  107. bp-forums/bbpress/bb-admin/index.php +123 -0
  108. bp-forums/bbpress/bb-admin/install-rtl.css +100 -0
  109. bp-forums/bbpress/bb-admin/install.css +433 -0
  110. bp-forums/bbpress/bb-admin/install.php +401 -0
  111. bp-forums/bbpress/bb-admin/js/admin-forums.js +140 -0
  112. bp-forums/bbpress/bb-admin/js/common.js +87 -0
  113. bp-forums/bbpress/bb-admin/js/utils.js +166 -0
  114. bp-forums/bbpress/bb-admin/options-discussion.php +131 -0
  115. bp-forums/bbpress/bb-admin/options-general.php +244 -0
  116. bp-forums/bbpress/bb-admin/options-permalinks.php +188 -0
  117. bp-forums/bbpress/bb-admin/options-reading.php +69 -0
  118. bp-forums/bbpress/bb-admin/options-wordpress.php +311 -0
  119. bp-forums/bbpress/bb-admin/options-writing.php +86 -0
  120. bp-forums/bbpress/bb-admin/plugins.php +268 -0
  121. bp-forums/bbpress/bb-admin/posts.php +119 -0
  122. bp-forums/bbpress/bb-admin/rewrite-rules.php +4 -0
  123. bp-forums/bbpress/bb-admin/sticky.php +29 -0
  124. bp-forums/bbpress/bb-admin/style-rtl.css +456 -0
  125. bp-forums/bbpress/bb-admin/style.css +1854 -0
  126. bp-forums/bbpress/bb-admin/tag-destroy.php +22 -0
  127. bp-forums/bbpress/bb-admin/tag-merge.php +26 -0
  128. bp-forums/bbpress/bb-admin/tag-rename.php +22 -0
  129. bp-forums/bbpress/bb-admin/themes.php +159 -0
  130. bp-forums/bbpress/bb-admin/tools-recount.php +211 -0
  131. bp-forums/bbpress/bb-admin/topic-move.php +30 -0
  132. bp-forums/bbpress/bb-admin/topic-toggle.php +33 -0
  133. bp-forums/bbpress/bb-admin/topics.php +180 -0
  134. bp-forums/bbpress/bb-admin/upgrade.php +210 -0
  135. bp-forums/bbpress/bb-admin/users.php +22 -0
  136. bp-forums/bbpress/bb-config-sample.php +64 -0
  137. bp-forums/bbpress/bb-cron.php +57 -0
  138. bp-forums/bbpress/bb-edit.php +46 -0
  139. bp-forums/bbpress/bb-includes/backpress/class.bp-log.php +550 -0
  140. bp-forums/bbpress/bb-includes/backpress/class.bp-roles.php +86 -0
  141. bp-forums/bbpress/bb-includes/backpress/class.bp-sql-schema-parser.php +615 -0
  142. bp-forums/bbpress/bb-includes/backpress/class.bp-user.php +398 -0
  143. bp-forums/bbpress/bb-includes/backpress/class.bpdb-multi.php +196 -0
  144. bp-forums/bbpress/bb-includes/backpress/class.bpdb.php +1164 -0
  145. bp-forums/bbpress/bb-includes/backpress/class.ixr.php +900 -0
  146. bp-forums/bbpress/bb-includes/backpress/class.mailer-smtp.php +1061 -0
  147. bp-forums/bbpress/bb-includes/backpress/class.mailer.php +1921 -0
  148. bp-forums/bbpress/bb-includes/backpress/class.passwordhash.php +258 -0
  149. bp-forums/bbpress/bb-includes/backpress/class.wp-ajax-response.php +138 -0
  150. bp-forums/bbpress/bb-includes/backpress/class.wp-auth.php +298 -0
  151. bp-forums/bbpress/bb-includes/backpress/class.wp-dependencies.php +23 -0
bp-activity.php CHANGED
@@ -1,82 +1,37 @@
1
  <?php
2
 
3
- define ( 'BP_ACTIVITY_DB_VERSION', '1300' );
4
 
5
  /* Define the slug for the component */
6
  if ( !defined( 'BP_ACTIVITY_SLUG' ) )
7
  define ( 'BP_ACTIVITY_SLUG', 'activity' );
8
 
9
- /* How long before activity items in streams are re-cached? */
10
- if ( !defined( 'BP_ACTIVITY_CACHE_LENGTH' ) )
11
- define ( 'BP_ACTIVITY_CACHE_LENGTH', '6 HOURS' );
12
-
13
  require ( BP_PLUGIN_DIR . '/bp-activity/bp-activity-classes.php' );
14
  require ( BP_PLUGIN_DIR . '/bp-activity/bp-activity-templatetags.php' );
15
  require ( BP_PLUGIN_DIR . '/bp-activity/bp-activity-widgets.php' );
16
- require ( BP_PLUGIN_DIR . '/bp-activity/bp-activity-cssjs.php' );
17
  require ( BP_PLUGIN_DIR . '/bp-activity/bp-activity-filters.php' );
18
 
19
-
20
- /**************************************************************************
21
- bp_bp_activity_install()
22
-
23
- Sets up the component ready for use on a site installation.
24
- **************************************************************************/
25
-
26
  function bp_activity_install() {
27
  global $wpdb, $bp;
28
 
29
  if ( !empty($wpdb->charset) )
30
  $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
31
 
32
- $sql[] = "CREATE TABLE {$bp->activity->table_name_user_activity} (
33
- id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
34
- user_id bigint(20) NOT NULL,
35
- component_name varchar(75) NOT NULL,
36
- component_action varchar(75) NOT NULL,
37
- item_id bigint(20) NOT NULL,
38
- secondary_item_id bigint(20) NOT NULL,
39
- date_recorded datetime NOT NULL,
40
- is_private tinyint(1) NOT NULL DEFAULT 0,
41
- no_sitewide_cache tinyint(1) NOT NULL DEFAULT 0,
42
- KEY item_id (item_id),
43
- KEY user_id (user_id),
44
- KEY is_private (is_private),
45
- KEY component_name (component_name)
46
- ) {$charset_collate};";
47
-
48
- $sql[] = "CREATE TABLE {$bp->activity->table_name_user_activity_cached} (
49
  id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
50
  user_id bigint(20) NOT NULL,
51
  component_name varchar(75) NOT NULL,
52
  component_action varchar(75) NOT NULL,
53
  content longtext NOT NULL,
54
  primary_link varchar(150) NOT NULL,
55
- item_id bigint(20) NOT NULL,
56
- secondary_item_id bigint(20) NOT NULL,
57
- date_cached datetime NOT NULL,
58
- date_recorded datetime NOT NULL,
59
- is_private tinyint(1) NOT NULL DEFAULT 0,
60
- KEY date_cached (date_cached),
61
- KEY date_recorded (date_recorded),
62
- KEY is_private (is_private),
63
- KEY user_id (user_id),
64
- KEY item_id (item_id),
65
- KEY component_name (component_name)
66
- ) {$charset_collate};";
67
-
68
- $sql[] = "CREATE TABLE {$bp->activity->table_name_sitewide} (
69
- id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
70
- user_id bigint(20) NOT NULL,
71
- item_id bigint(20) NOT NULL,
72
- secondary_item_id bigint(20),
73
- content longtext NOT NULL,
74
- primary_link varchar(150) NOT NULL,
75
- component_name varchar(75) NOT NULL,
76
- component_action varchar(75) NOT NULL,
77
- date_cached datetime NOT NULL,
78
  date_recorded datetime NOT NULL,
79
- KEY date_cached (date_cached),
80
  KEY date_recorded (date_recorded),
81
  KEY user_id (user_id),
82
  KEY item_id (item_id),
@@ -86,84 +41,81 @@ function bp_activity_install() {
86
  require_once( ABSPATH . 'wp-admin/upgrade-functions.php' );
87
  dbDelta($sql);
88
 
89
- if ( '' == get_site_option( 'bp-activity-db-merge' ) || !get_site_option( 'bp-activity-db-merge' ) ) {
90
- $users = $wpdb->get_col( "SELECT ID FROM " . CUSTOM_USER_TABLE );
91
-
92
- foreach ( $users as $user_id ) {
93
- BP_Activity_Activity::convert_tables_for_user( $user_id );
94
- BP_Activity_Activity::kill_tables_for_user( $user_id );
95
- }
96
-
97
- add_site_option( 'bp-activity-db-merge', 1 );
98
- }
99
 
100
  update_site_option( 'bp-activity-db-version', BP_ACTIVITY_DB_VERSION );
101
  }
102
 
103
- /**************************************************************************
104
- bp_activity_setup_globals()
105
-
106
- Set up and add all global variables for this component, and add them to
107
- the $bp global variable array.
108
- **************************************************************************/
109
-
110
  function bp_activity_setup_globals() {
111
  global $bp, $wpdb, $current_blog;
112
 
113
- $bp->activity->table_name_user_activity = $wpdb->base_prefix . 'bp_activity_user_activity';
114
- $bp->activity->table_name_user_activity_cached = $wpdb->base_prefix . 'bp_activity_user_activity_cached';
115
- $bp->activity->table_name_sitewide = $wpdb->base_prefix . 'bp_activity_sitewide';
116
 
117
- $bp->activity->image_base = BP_PLUGIN_URL . '/bp-activity/images';
118
  $bp->activity->slug = BP_ACTIVITY_SLUG;
 
 
 
119
 
120
- $bp->version_numbers->activity = BP_ACTIVITY_VERSION;
 
 
 
121
 
122
- if ( is_site_admin() && get_site_option( 'bp-activity-db-version' ) < BP_ACTIVITY_DB_VERSION )
 
 
 
123
  bp_activity_install();
124
  }
125
- add_action( 'plugins_loaded', 'bp_activity_setup_globals', 5 );
126
- add_action( 'admin_menu', 'bp_activity_setup_globals', 1 );
127
 
128
  function bp_activity_setup_root_component() {
129
- /* Register 'groups' as a root component */
130
  bp_core_add_root_component( BP_ACTIVITY_SLUG );
131
  }
132
- add_action( 'plugins_loaded', 'bp_activity_setup_root_component', 1 );
133
-
134
-
135
- /**************************************************************************
136
- bp_activity_setup_nav()
137
-
138
- Set up front end navigation.
139
- **************************************************************************/
140
 
141
  function bp_activity_setup_nav() {
142
  global $bp;
143
-
144
  /* Add 'Activity' to the main navigation */
145
- bp_core_add_nav_item( __('Activity', 'buddypress'), $bp->activity->slug );
146
- bp_core_add_nav_default( $bp->activity->slug, 'bp_activity_screen_my_activity', 'just-me' );
147
-
148
  $activity_link = $bp->loggedin_user->domain . $bp->activity->slug . '/';
149
-
150
  /* Add the subnav items to the activity nav item */
151
- bp_core_add_subnav_item( $bp->activity->slug, 'just-me', __('Just Me', 'buddypress'), $activity_link, 'bp_activity_screen_my_activity' );
152
- bp_core_add_subnav_item( $bp->activity->slug, 'my-friends', __('My Friends', 'buddypress'), $activity_link, 'bp_activity_screen_friends_activity', 'activity-my-friends', bp_is_home() );
153
-
154
  if ( $bp->current_component == $bp->activity->slug ) {
155
  if ( bp_is_home() ) {
156
  $bp->bp_options_title = __( 'My Activity', 'buddypress' );
157
  } else {
158
- $bp->bp_options_avatar = bp_core_get_avatar( $bp->displayed_user->id, 1 );
159
  $bp->bp_options_title = $bp->displayed_user->fullname;
160
  }
161
  }
 
 
162
  }
163
- add_action( 'wp', 'bp_activity_setup_nav', 2 );
164
- add_action( 'admin_menu', 'bp_activity_setup_nav', 2 );
165
 
166
- /***** Screens **********/
 
 
 
 
 
 
 
167
 
168
  function bp_activity_screen_my_activity() {
169
  do_action( 'bp_activity_screen_my_activity' );
@@ -175,49 +127,49 @@ function bp_activity_screen_friends_activity() {
175
  bp_core_load_template( apply_filters( 'bp_activity_template_friends_activity', 'activity/my-friends' ) );
176
  }
177
 
178
- /***** Actions **********/
179
 
180
- function bp_activity_record( $item_id, $component_name, $component_action, $is_private, $secondary_item_id = false, $user_id = false, $secondary_user_id = false, $recorded_time = false ) {
181
- global $bp, $wpdb;
182
-
183
- if ( !$user_id )
184
- $user_id = $bp->loggedin_user->id;
 
 
185
 
186
- if ( !$recorded_time )
187
- $recorded_time = time();
188
-
189
- $activity = new BP_Activity_Activity;
190
- $activity->item_id = $item_id;
191
- $activity->secondary_item_id = $secondary_item_id;
192
- $activity->user_id = $user_id;
193
- $activity->component_name = $component_name;
194
- $activity->component_action = $component_action;
195
- $activity->date_recorded = $recorded_time;
196
- $activity->is_private = $is_private;
197
 
198
- $loggedin_user_save = $activity->save();
 
 
 
 
 
 
 
 
 
199
 
200
- /* Save an activity entry for both logged in and secondary user. For example for a new friend connection
201
- you would want to show "X and Y are now friends" on both users activity stream */
202
- if ( $secondary_user_id ) {
203
- $activity = new BP_Activity_Activity;
204
- $activity->item_id = $item_id;
205
- $activity->user_id = $secondary_user_id;
206
- $activity->component_name = $component_name;
207
- $activity->component_action = $component_action;
208
- $activity->date_recorded = $recorded_time;
209
- $activity->is_private = $is_private;
210
-
211
- // We don't want to record this on the sitewide stream, otherwise we will get duplicates.
212
- $activity->no_sitewide_cache = true;
213
-
214
- $secondary_user_save = $activity->save();
215
  }
216
 
217
- do_action( 'bp_activity_record', $item_id, $component_name, $component_action, $is_private, $secondary_item_id, $user_id, $secondary_user_id );
 
 
 
 
 
 
218
 
219
- return true;
220
  }
 
 
221
 
222
  function bp_activity_action_sitewide_feed() {
223
  global $bp, $wp_query;
@@ -261,46 +213,191 @@ function bp_activity_action_friends_feed() {
261
  }
262
  add_action( 'wp', 'bp_activity_action_friends_feed', 3 );
263
 
264
- function bp_activity_get_last_updated() {
265
- return BP_Activity_Activity::get_last_updated();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
  }
267
 
268
- function bp_activity_get_sitewide_activity( $max_items = 30, $pag_num = false, $pag_page = false ) {
269
- return BP_Activity_Activity::get_sitewide_activity( $max_items, $pag_num, $pag_page );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  }
271
 
272
- function bp_activity_get_user_activity( $user_id, $max_items = 30, $since = '-4 weeks', $pag_num = false, $pag_page = false ) {
273
- return BP_Activity_Activity::get_activity_for_user( $user_id, $max_items, $since, $pag_num, $pag_page );
 
 
 
 
 
274
  }
275
 
276
- function bp_activity_get_friends_activity( $user_id, $max_items = 30, $since = '-4 weeks', $max_items_per_friend = false, $pag_num = false, $pag_page = false ) {
277
- return BP_Activity_Activity::get_activity_for_friends( $user_id, $max_items, $since, $max_items_per_friend, $pag_num, $pag_page );
 
 
 
 
 
 
 
 
278
  }
279
 
280
- function bp_activity_delete( $item_id, $component_name, $component_action, $user_id, $secondary_item_id ) {
281
- if ( !BP_Activity_Activity::delete( $item_id, $component_name, $component_action, $user_id, $secondary_item_id ) )
282
  return false;
283
-
284
- do_action( 'bp_activity_delete', $item_id, $component_name, $component_action, $user_id, $secondary_item_id );
285
 
286
  return true;
287
  }
288
 
289
- function bp_activity_order_by_date( $a, $b ) {
290
- return strcasecmp( $b['date_recorded'], $a['date_recorded'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
  }
292
 
293
  function bp_activity_remove_data( $user_id ) {
294
  // Clear the user's activity from the sitewide stream and clear their activity tables
295
- BP_Activity_Activity::delete_activity_for_user( $user_id );
296
-
297
- // Remove the deleted users activity tables
298
- BP_Activity_Activity::kill_tables_for_user( $user_id );
299
 
300
  do_action( 'bp_activity_remove_data', $user_id );
301
  }
302
  add_action( 'wpmu_delete_user', 'bp_activity_remove_data' );
303
  add_action( 'delete_user', 'bp_activity_remove_data' );
 
304
 
 
 
 
 
305
 
306
  ?>
1
  <?php
2
 
3
+ define ( 'BP_ACTIVITY_DB_VERSION', '1800' );
4
 
5
  /* Define the slug for the component */
6
  if ( !defined( 'BP_ACTIVITY_SLUG' ) )
7
  define ( 'BP_ACTIVITY_SLUG', 'activity' );
8
 
 
 
 
 
9
  require ( BP_PLUGIN_DIR . '/bp-activity/bp-activity-classes.php' );
10
  require ( BP_PLUGIN_DIR . '/bp-activity/bp-activity-templatetags.php' );
11
  require ( BP_PLUGIN_DIR . '/bp-activity/bp-activity-widgets.php' );
 
12
  require ( BP_PLUGIN_DIR . '/bp-activity/bp-activity-filters.php' );
13
 
14
+ /* Include deprecated functions if settings allow */
15
+ if ( !defined( 'BP_IGNORE_DEPRECATED' ) )
16
+ require ( BP_PLUGIN_DIR . '/bp-activity/deprecated/bp-activity-deprecated.php' );
17
+
 
 
 
18
  function bp_activity_install() {
19
  global $wpdb, $bp;
20
 
21
  if ( !empty($wpdb->charset) )
22
  $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
23
 
24
+ $sql[] = "CREATE TABLE {$bp->activity->table_name} (
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
26
  user_id bigint(20) NOT NULL,
27
  component_name varchar(75) NOT NULL,
28
  component_action varchar(75) NOT NULL,
29
  content longtext NOT NULL,
30
  primary_link varchar(150) NOT NULL,
31
+ item_id varchar(75) NOT NULL,
32
+ secondary_item_id varchar(75) NOT NULL,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  date_recorded datetime NOT NULL,
34
+ hide_sitewide bool DEFAULT 0,
35
  KEY date_recorded (date_recorded),
36
  KEY user_id (user_id),
37
  KEY item_id (item_id),
41
  require_once( ABSPATH . 'wp-admin/upgrade-functions.php' );
42
  dbDelta($sql);
43
 
44
+ /* Drop the old sitewide and user activity tables */
45
+ $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->base_prefix}bp_activity_user_activity" );
46
+ $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->base_prefix}bp_activity_sitewide" );
47
+
48
+ /* TODO: Rename the old user activity cached table */
49
+ //$wpdb->query( "RENAME TABLE {$wpdb->base_prefix}bp_activity_user_activity_cached TO {$bp->activity->table_name}" );
 
 
 
 
50
 
51
  update_site_option( 'bp-activity-db-version', BP_ACTIVITY_DB_VERSION );
52
  }
53
 
 
 
 
 
 
 
 
54
  function bp_activity_setup_globals() {
55
  global $bp, $wpdb, $current_blog;
56
 
57
+ /* Internal identifier */
58
+ $bp->activity->id = 'activity';
 
59
 
60
+ $bp->activity->table_name = $wpdb->base_prefix . 'bp_activity_user_activity_cached';
61
  $bp->activity->slug = BP_ACTIVITY_SLUG;
62
+
63
+ /* Register this in the active components array */
64
+ $bp->active_components[$bp->activity->slug] = $bp->activity->id;
65
 
66
+ do_action( 'bp_activity_setup_globals' );
67
+ }
68
+ add_action( 'plugins_loaded', 'bp_activity_setup_globals', 5 );
69
+ add_action( 'admin_menu', 'bp_activity_setup_globals', 2 );
70
 
71
+ function bp_activity_check_installed() {
72
+ global $wpdb, $bp;
73
+
74
+ if ( get_site_option('bp-activity-db-version') < BP_ACTIVITY_DB_VERSION )
75
  bp_activity_install();
76
  }
77
+ add_action( 'admin_menu', 'bp_activity_check_installed' );
 
78
 
79
  function bp_activity_setup_root_component() {
80
+ /* Register 'activity' as a root component (for RSS feed use) */
81
  bp_core_add_root_component( BP_ACTIVITY_SLUG );
82
  }
83
+ add_action( 'plugins_loaded', 'bp_activity_setup_root_component', 2 );
 
 
 
 
 
 
 
84
 
85
  function bp_activity_setup_nav() {
86
  global $bp;
87
+
88
  /* Add 'Activity' to the main navigation */
89
+ bp_core_new_nav_item( array( 'name' => __( 'Activity', 'buddypress' ), 'slug' => $bp->activity->slug, 'position' => 10, 'screen_function' => 'bp_activity_screen_my_activity', 'default_subnav_slug' => 'just-me', 'item_css_id' => $bp->activity->id ) );
90
+
 
91
  $activity_link = $bp->loggedin_user->domain . $bp->activity->slug . '/';
92
+
93
  /* Add the subnav items to the activity nav item */
94
+ bp_core_new_subnav_item( array( 'name' => __( 'Just Me', 'buddypress' ), 'slug' => 'just-me', 'parent_url' => $activity_link, 'parent_slug' => $bp->activity->slug, 'screen_function' => 'bp_activity_screen_my_activity', 'position' => 10 ) );
95
+ bp_core_new_subnav_item( array( 'name' => __( 'My Friends', 'buddypress' ), 'slug' => 'my-friends', 'parent_url' => $activity_link, 'parent_slug' => $bp->activity->slug, 'screen_function' => 'bp_activity_screen_friends_activity', 'position' => 20, 'item_css_id' => 'activity-my-friends' ) );
96
+
97
  if ( $bp->current_component == $bp->activity->slug ) {
98
  if ( bp_is_home() ) {
99
  $bp->bp_options_title = __( 'My Activity', 'buddypress' );
100
  } else {
101
+ $bp->bp_options_avatar = bp_core_fetch_avatar( array( 'item_id' => $bp->displayed_user->id, 'type' => 'thumb' ) );
102
  $bp->bp_options_title = $bp->displayed_user->fullname;
103
  }
104
  }
105
+
106
+ do_action( 'bp_activity_setup_nav' );
107
  }
108
+ add_action( 'plugins_loaded', 'bp_activity_setup_nav' );
109
+ add_action( 'admin_menu', 'bp_activity_setup_nav' );
110
 
111
+
112
+ /********************************************************************************
113
+ * Screen Functions
114
+ *
115
+ * Screen functions are the controllers of BuddyPress. They will execute when their
116
+ * specific URL is caught. They will first save or manipulate data using business
117
+ * functions, then pass on the user to a template file.
118
+ */
119
 
120
  function bp_activity_screen_my_activity() {
121
  do_action( 'bp_activity_screen_my_activity' );
127
  bp_core_load_template( apply_filters( 'bp_activity_template_friends_activity', 'activity/my-friends' ) );
128
  }
129
 
 
130
 
131
+ /********************************************************************************
132
+ * Action Functions
133
+ *
134
+ * Action functions are exactly the same as screen functions, however they do not
135
+ * have a template screen associated with them. Usually they will send the user
136
+ * back to the default screen after execution.
137
+ */
138
 
139
+ function bp_activity_action_delete_activity() {
140
+ global $bp;
 
 
 
 
 
 
 
 
 
141
 
142
+ if ( $bp->current_component != $bp->activity->slug || $bp->current_action != 'delete' )
143
+ return false;
144
+
145
+ if ( empty( $bp->action_variables[0] ) || !is_numeric( $bp->action_variables[0] ) )
146
+ return false;
147
+
148
+ /* Check the nonce */
149
+ check_admin_referer( 'bp_activity_delete_link' );
150
+
151
+ $activity_id = $bp->action_variables[0];
152
 
153
+ /* Check access */
154
+ if ( !is_site_admin() ) {
155
+ $activity = new BP_Activity_Activity( $activity_id );
156
+
157
+ if ( $activity->user_id != $bp->loggedin_user->id )
158
+ return false;
 
 
 
 
 
 
 
 
 
159
  }
160
 
161
+ /* Now delete the activity item */
162
+ if ( bp_activity_delete_by_activity_id( $activity_id ) )
163
+ bp_core_add_message( __( 'Activity deleted', 'buddypress' ) );
164
+ else
165
+ bp_core_add_message( __( 'There was an error when deleting that activity', 'buddypress' ), 'error' );
166
+
167
+ do_action( 'bp_activity_action_delete_activity', $activity_id );
168
 
169
+ bp_core_redirect( $_SERVER['HTTP_REFERER'] );
170
  }
171
+ add_action( 'wp', 'bp_activity_action_delete_activity', 3 );
172
+
173
 
174
  function bp_activity_action_sitewide_feed() {
175
  global $bp, $wp_query;
213
  }
214
  add_action( 'wp', 'bp_activity_action_friends_feed', 3 );
215
 
216
+
217
+ /********************************************************************************
218
+ * Business Functions
219
+ *
220
+ * Business functions are where all the magic happens in BuddyPress. They will
221
+ * handle the actual saving or manipulation of information. Usually they will
222
+ * hand off to a database class for data access, then return
223
+ * true or false on success or failure.
224
+ */
225
+
226
+ function bp_activity_add( $args = '' ) {
227
+ global $bp, $wpdb;
228
+
229
+ $defaults = array(
230
+ 'content' => false, // The content of the activity item
231
+ 'primary_link' => false, // The primary URL for this item in RSS feeds
232
+ 'component_name' => false, // The name/ID of the component e.g. groups, profile, mycomponent
233
+ 'component_action' => false, // The component action e.g. new_wire_post, profile_updated
234
+
235
+ 'user_id' => $bp->loggedin_user->id, // Optional: The user to record the activity for, can be false if this activity is not for a user.
236
+ 'item_id' => false, // Optional: The ID of the specific item being recorded, e.g. a blog_id, or wire_post_id
237
+ 'secondary_item_id' => false, // Optional: A second ID used to further filter e.g. a comment_id
238
+ 'recorded_time' => time(), // The time that this activity was recorded
239
+ 'hide_sitewide' => false // Should this be hidden on the sitewide activity stream?
240
+ );
241
+
242
+ $r = wp_parse_args( $args, $defaults );
243
+ extract( $r, EXTR_SKIP );
244
+
245
+ /* Insert the "time-since" placeholder */
246
+ if ( $content )
247
+ $content = bp_activity_add_timesince_placeholder( $content );
248
+
249
+ $activity = new BP_Activity_Activity;
250
+ $activity->user_id = $user_id;
251
+ $activity->content = $content;
252
+ $activity->primary_link = $primary_link;
253
+ $activity->component_name = $component_name;
254
+ $activity->component_action = $component_action;
255
+ $activity->item_id = $item_id;
256
+ $activity->secondary_item_id = $secondary_item_id;
257
+ $activity->date_recorded = $recorded_time;
258
+ $activity->hide_sitewide = $hide_sitewide;
259
+
260
+ if ( !$activity->save() )
261
+ return false;
262
+
263
+ do_action( 'bp_activity_add', $args );
264
+
265
+ return true;
266
  }
267
 
268
+ /* There are multiple ways to delete activity items, depending on the information you have at the time. */
269
+
270
+ function bp_activity_delete_by_item_id( $args = '' ) {
271
+ global $bp;
272
+
273
+ $defaults = array(
274
+ 'item_id' => false,
275
+ 'component_name' => false,
276
+ 'component_action' => false, // optional
277
+ 'user_id' => false, // optional
278
+ 'secondary_item_id' => false // optional
279
+ );
280
+
281
+ $r = wp_parse_args( $args, $defaults );
282
+ extract( $r, EXTR_SKIP );
283
+
284
+ if ( !BP_Activity_Activity::delete_by_item_id( $item_id, $component_name, $component_action, $user_id, $secondary_item_id ) )
285
+ return false;
286
+
287
+ do_action( 'bp_activity_delete_by_item_id', $item_id, $component_name, $component_action, $user_id, $secondary_item_id );
288
+
289
+ return true;
290
  }
291
 
292
+ function bp_activity_delete_by_activity_id( $activity_id ) {
293
+ if ( !BP_Activity_Activity::delete_by_activity_id( $activity_id ) )
294
+ return false;
295
+
296
+ do_action( 'bp_activity_delete_by_activity_id', $activity_id );
297
+
298
+ return true;
299
  }
300
 
301
+ function bp_activity_delete_by_content( $user_id, $content, $component_name, $component_action ) {
302
+ /* Insert the "time-since" placeholder to match the existing content in the DB */
303
+ $content = bp_activity_add_timesince_placeholder( $content );
304
+
305
+ if ( !BP_Activity_Activity::delete_by_content( $user_id, $content, $component_name, $component_action ) )
306
+ return false;
307
+
308
+ do_action( 'bp_activity_delete_by_content', $user_id, $content, $component_name, $component_action );
309
+
310
+ return true;
311
  }
312
 
313
+ function bp_activity_delete_for_user_by_component( $user_id, $component_name ) {
314
+ if ( !BP_Activity_Activity::delete_for_user_by_component( $user_id, $component_name ) )
315
  return false;
316
+
317
+ do_action( 'bp_activity_delete_for_user_by_component', $user_id, $component_name );
318
 
319
  return true;
320
  }
321
 
322
+ function bp_activity_add_timesince_placeholder( $content ) {
323
+ /* Check a time-since span doesn't already exist */
324
+ if ( false === strpos( $content, '<span class="time-since">' ) ) {
325
+ if ( !$pos = strpos( $content, '<blockquote' ) ) {
326
+ if ( !$pos = strpos( $content, '<div' ) ) {
327
+ if ( !$pos = strpos( $content, '<ul' ) ) {
328
+ $content .= ' <span class="time-since">%s</span>';
329
+ }
330
+ }
331
+ }
332
+ }
333
+
334
+ if ( (int) $pos ) {
335
+ $before = substr( $content, 0, (int) $pos );
336
+ $after = substr( $content, (int) $pos, strlen( $content ) );
337
+
338
+ $content = $before . ' <span class="time-since">%s</span>' . $after;
339
+ }
340
+
341
+ return apply_filters( 'bp_activity_add_timesince_placeholder', $content );
342
+ }
343
+
344
+ function bp_activity_set_action( $component_id, $key, $value ) {
345
+ global $bp;
346
+
347
+ if ( empty( $component_id ) || empty( $key ) || empty( $value ) )
348
+ return false;
349
+
350
+ $bp->activity->actions->{$component_id}->{$key} = apply_filters( 'bp_activity_set_action', array(
351
+ 'key' => $key,
352
+ 'value' => $value
353
+ ), $component_id, $key, $value );
354
+ }
355
+
356
+ function bp_activity_get_action( $component_id, $key ) {
357
+ global $bp;
358
+
359
+ if ( empty( $component_id ) || empty( $key ) )
360
+ return false;
361
+
362
+ return apply_filters( 'bp_activity_get_action', $bp->activity->actions->{$component_id}->{$key}, $component_id, $key );
363
+ }
364
+
365
+ function bp_activity_check_exists_by_content( $content ) {
366
+ /* Insert the "time-since" placeholder to match the existing content in the DB */
367
+ $content = bp_activity_add_timesince_placeholder( $content );
368
+
369
+ return apply_filters( 'bp_activity_check_exists_by_content', BP_Activity_Activity::check_exists_by_content( $content ) );
370
+ }
371
+
372
+ function bp_activity_get_last_updated() {
373
+ return apply_filters( 'bp_activity_get_last_updated', BP_Activity_Activity::get_last_updated() );
374
+ }
375
+
376
+ function bp_activity_get_sitewide_activity( $max_items = 30, $pag_num = false, $pag_page = false, $filter = false ) {
377
+ return apply_filters( 'bp_activity_get_sitewide_activity', BP_Activity_Activity::get_sitewide_activity( $max_items, $pag_num, $pag_page, $filter ), $max_items, $pag_num, $pag_page, $filter );
378
+ }
379
+
380
+ function bp_activity_get_user_activity( $user_id, $max_items = 30, $pag_num = false, $pag_page = false, $filter = false ) {
381
+ return apply_filters( 'bp_activity_get_user_activity', BP_Activity_Activity::get_activity_for_user( $user_id, $max_items, $pag_num, $pag_page, $filter ), $user_id, $max_items, $pag_num, $pag_page, $filter );
382
+ }
383
+
384
+ function bp_activity_get_friends_activity( $user_id, $max_items = 30, $max_items_per_friend = false, $pag_num = false, $pag_page = false, $filter = false ) {
385
+ return apply_filters( 'bp_activity_get_friends_activity', BP_Activity_Activity::get_activity_for_friends( $user_id, $max_items, $max_items_per_friend, $pag_num, $pag_page, $filter ), $user_id, $max_items, $max_items_per_friend, $pag_num, $pag_page, $filter );
386
  }
387
 
388
  function bp_activity_remove_data( $user_id ) {
389
  // Clear the user's activity from the sitewide stream and clear their activity tables
390
+ BP_Activity_Activity::delete_for_user( $user_id );
 
 
 
391
 
392
  do_action( 'bp_activity_remove_data', $user_id );
393
  }
394
  add_action( 'wpmu_delete_user', 'bp_activity_remove_data' );
395
  add_action( 'delete_user', 'bp_activity_remove_data' );
396
+ add_action( 'make_spam_user', 'bp_activity_remove_data' );
397
 
398
+ /* Ordering function - don't call this directly */
399
+ function bp_activity_order_by_date( $a, $b ) {
400
+ return apply_filters( 'bp_activity_order_by_date', strcasecmp( $b['date_recorded'], $a['date_recorded'] ) );
401
+ }
402
 
403
  ?>
bp-activity/bp-activity-classes.php CHANGED
@@ -9,37 +9,32 @@ Class BP_Activity_Activity {
9
  var $component_name;
10
  var $component_action;
11
  var $date_recorded;
12
- var $is_private = false;
13
- var $no_sitewide_cache = false;
14
 
15
- var $table_name;
16
- var $table_name_cached;
17
- var $for_secondary_user = false;
18
-
19
- function bp_activity_activity( $id = null, $populate = true ) {
20
  global $bp;
21
 
22
  if ( $id ) {
23
  $this->id = $id;
24
-
25
- if ( $populate )
26
- $this->populate();
27
  }
28
  }
29
 
30
  function populate() {
31
  global $wpdb, $bp;
32
 
33
- $activity = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$this->table_name} WHERE id = %d", $this->id ) );
34
-
 
35
  $this->item_id = $activity->item_id;
36
  $this->secondary_item_id = $activity->secondary_item_id;
37
  $this->user_id = $activity->user_id;
 
 
38
  $this->component_name = $activity->component_name;
39
  $this->component_action = $activity->component_action;
40
  $this->date_recorded = $activity->date_recorded;
41
- $this->is_private = $activity->is_private;
42
- $this->no_sitewide_cache = $activity->no_sitewide_cache;
43
  }
44
 
45
  function save() {
@@ -47,73 +42,108 @@ Class BP_Activity_Activity {
47
 
48
  do_action( 'bp_activity_before_save', $this );
49
 
50
- if ( !$this->item_id || !$this->user_id || $this->is_private || !$this->component_name )
51
  return false;
52
-
53
- // Set the table names
54
- $this->table_name = $bp->activity->table_name_user_activity;
55
- $this->table_name_cached = $bp->activity->table_name_user_activity_cached;
56
-
57
- if ( !$this->exists() ) {
58
- // Insert the new activity into the activity table.
59
- $activity = $wpdb->query( $wpdb->prepare( "INSERT INTO {$this->table_name} ( item_id, secondary_item_id, user_id, component_name, component_action, date_recorded, is_private, no_sitewide_cache ) VALUES ( %d, %d, %d, %s, %s, FROM_UNIXTIME(%d), %d, %d )", $this->item_id, $this->secondary_item_id, $this->user_id, $this->component_name, $this->component_action, $this->date_recorded, $this->is_private, $this->no_sitewide_cache ) );
60
-
61
- // Fetch the formatted activity content so we can add it to the cache.
62
  if ( function_exists( $bp->{$this->component_name}->format_activity_function ) ) {
63
- if ( !$activity_content = call_user_func( $bp->{$this->component_name}->format_activity_function, $this->item_id, $this->user_id, $this->component_action, $this->secondary_item_id, $this->for_secondary_user ) )
64
  return false;
 
 
 
65
  }
66
-
67
- // Add the cached version of the activity to the cached activity table.
68
- $activity_cached = $wpdb->query( $wpdb->prepare( "INSERT INTO {$this->table_name_cached} ( user_id, item_id, secondary_item_id, content, primary_link, component_name, component_action, date_cached, date_recorded, is_private ) VALUES ( %d, %d, %d, %s, %s, %s, %s, FROM_UNIXTIME(%d), FROM_UNIXTIME(%d), %d )", $this->user_id, $this->item_id, $this->secondary_item_id, $activity_content['content'], $activity_content['primary_link'], $this->component_name, $this->component_action, time(), $this->date_recorded, $this->is_private ) );
69
-
70
- // Add the cached version of the activity to the sitewide activity table.
71
- if ( !$this->no_sitewide_cache )
72
- $sitewide_cached = $wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->activity->table_name_sitewide} ( user_id, item_id, secondary_item_id, content, primary_link, component_name, component_action, date_cached, date_recorded ) VALUES ( %d, %d, %d, %s, %s, %s, %s, FROM_UNIXTIME(%d), FROM_UNIXTIME(%d) )", $this->user_id, $this->item_id, $this->secondary_item_id, $activity_content['content'], $activity_content['primary_link'], $this->component_name, $this->component_action, time(), $this->date_recorded ) );
73
-
74
- if ( $activity && $activity_cached ) {
 
 
 
 
 
 
 
75
  do_action( 'bp_activity_after_save', $this );
76
  return true;
77
  }
78
-
79
- return false;
80
  }
 
 
81
  }
82
 
83
  function exists() {
84
  global $wpdb, $bp;
85
- return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$this->table_name} WHERE item_id = %d AND secondary_item_id = %d AND user_id = %d AND component_name = %s AND component_action = %s", $this->item_id, $this->secondary_item_id, $this->user_id, $this->component_name, $this->component_action ) );
 
 
 
 
 
 
 
 
 
 
 
 
86
  }
87
 
88
  /* Static Functions */
89
 
90
- function delete( $item_id, $component_name, $component_action, $user_id, $secondary_item_id = false ) {
91
  global $wpdb, $bp;
92
-
93
- if ( !$user_id )
94
- return false;
95
 
96
- if ( !$bp->activity )
97
- bp_activity_setup_globals();
98
 
99
- if ( $secondary_item_id )
100
- $secondary_sql = $wpdb->prepare( "AND secondary_item_id = %d", $secondary_item_id );
 
 
 
 
 
 
 
 
 
 
101
 
102
- if ( $component_action ) {
103
- $component_action_sql = $wpdb->prepare( "AND component_action = %s AND user_id = %d", $component_action, $user_id );
104
- $cached_component_action_sql = $wpdb->prepare( "AND component_action = %s", $component_action );
105
- }
106
-
107
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_user_activity} WHERE item_id = %d {$secondary_sql} AND component_name = %s {$component_action_sql}", $item_id, $component_name ) );
108
-
109
- // Delete this entry from the user activity cache table and the sitewide cache table
110
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_user_activity_cached} WHERE user_id = %d AND item_id = %d {$secondary_sql} AND component_name = %s {$cached_component_action_sql}", $user_id, $item_id, $component_name ) );
111
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_sitewide} WHERE item_id = %d {$secondary_sql} AND component_name = %s {$component_action_sql}", $item_id, $component_name ) );
 
 
 
 
 
 
 
112
 
113
- return true;
114
  }
115
 
116
- function get_activity_for_user( $user_id, $max_items, $since, $limit, $page ) {
117
  global $wpdb, $bp;
118
 
119
  $since = strtotime($since);
@@ -121,34 +151,24 @@ Class BP_Activity_Activity {
121
  if ( $limit && $page )
122
  $pag_sql = $wpdb->prepare( "LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
123
 
124
- if ( $max )
125
- $max_sql = $wpdb->prepare( "LIMIT %d", $max );
126
 
127
- if ( !bp_is_home() )
128
- $privacy_sql = " AND is_private = 0";
129
-
130
- if ( $limit && $page && $max )
131
- $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name_user_activity_cached} WHERE user_id = %d AND date_recorded >= FROM_UNIXTIME(%d) $privacy_sql ORDER BY date_recorded DESC $pag_sql", $user_id, $since ) );
 
132
  else
133
- $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name_user_activity_cached} WHERE user_id = %d AND date_recorded >= FROM_UNIXTIME(%d) $privacy_sql ORDER BY date_recorded DESC $pag_sql $max_sql", $user_id, $since ) );
134
-
135
- $total_activities = $wpdb->get_var( $wpdb->prepare( "SELECT count(id) FROM {$bp->activity->table_name_user_activity_cached} WHERE user_id = %d AND date_recorded >= FROM_UNIXTIME(%d) $privacy_sql ORDER BY date_recorded DESC $max_sql", $user_id, $since ) );
136
-
137
- for ( $i = 0; $i < count( $activities ); $i++ ) {
138
- if ( !$activities[$i]->is_private ) {
139
- $activities_formatted[$i]['content'] = $activities[$i]->content;
140
- $activities_formatted[$i]['primary_link'] = $activities[$i]->primary_link;
141
- $activities_formatted[$i]['date_recorded'] = $activities[$i]->date_recorded;
142
- $activities_formatted[$i]['component_name'] = $activities[$i]->component_name;
143
- $activities_formatted[$i]['component_action'] = $activities[$i]->component_action;
144
- $activities_formatted[$i]['is_private'] = $activities[$i]->is_private;
145
- }
146
- }
147
 
148
- return array( 'activities' => $activities_formatted, 'total' => (int)$total_activities );
149
  }
150
 
151
- function get_activity_for_friends( $user_id, $max_items, $since, $max_items_per_friend, $limit, $page ) {
152
  global $wpdb, $bp;
153
 
154
  // TODO: Max items per friend not yet implemented.
@@ -159,10 +179,12 @@ Class BP_Activity_Activity {
159
  if ( $limit && $page )
160
  $pag_sql = $wpdb->prepare( "LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
161
 
162
- if ( $max )
163
- $max_sql = $wpdb->prepare( "LIMIT %d", $max );
164
-
165
- $since = strtotime($since);
 
 
166
 
167
  $friend_ids = friends_get_friend_user_ids( $user_id );
168
 
@@ -171,17 +193,17 @@ Class BP_Activity_Activity {
171
 
172
  $friend_ids = implode( ',', $friend_ids );
173
 
174
- if ( $limit && $page && $max )
175
- $activities = $wpdb->get_results( $wpdb->prepare( "SELECT DISTINCT user_id, content, primary_link, date_recorded, component_name, component_action FROM {$bp->activity->table_name_sitewide} WHERE user_id IN ({$friend_ids}) AND date_recorded >= FROM_UNIXTIME(%d) ORDER BY date_recorded DESC $pag_sql", $since ) );
176
  else
177
- $activities = $wpdb->get_results( $wpdb->prepare( "SELECT DISTINCT user_id, content, primary_link, date_recorded, component_name, component_action FROM {$bp->activity->table_name_sitewide} WHERE user_id IN ({$friend_ids}) AND date_recorded >= FROM_UNIXTIME(%d) ORDER BY date_recorded DESC $pag_sql $max_sql", $since ) );
178
-
179
- $total_activities = $wpdb->get_var( $wpdb->prepare( "SELECT DISTINCT count(user_id) FROM {$bp->activity->table_name_sitewide} WHERE user_id IN ({$friend_ids}) AND date_recorded >= FROM_UNIXTIME(%d) ORDER BY date_recorded DESC $max_sql", $since ) );
180
 
181
  return array( 'activities' => $activities, 'total' => (int)$total_activities );
182
  }
183
 
184
- function get_sitewide_activity( $max, $limit, $page ) {
185
  global $wpdb, $bp;
186
 
187
  if ( $limit && $page )
@@ -189,26 +211,25 @@ Class BP_Activity_Activity {
189
 
190
  if ( $max )
191
  $max_sql = $wpdb->prepare( "LIMIT %d", $max );
 
 
 
 
192
 
193
- /* Remove entries that are older than 6 months */
194
- $wpdb->query( $wpdb->prepare( "DELETE FROM " . $bp->activity->table_name_sitewide . " WHERE DATE_ADD(date_recorded, INTERVAL 6 MONTH) <= NOW()" ) );
195
-
196
  if ( $limit && $page && $max )
197
- $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name_sitewide} ORDER BY date_recorded DESC $pag_sql" ) );
198
  else
199
- $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name_sitewide} ORDER BY date_recorded DESC $pag_sql $max_sql" ) );
200
 
201
- $total_activities = $wpdb->get_var( $wpdb->prepare( "SELECT count(id) FROM {$bp->activity->table_name_sitewide} ORDER BY date_recorded DESC $max_sql" ) );
202
-
203
- for ( $i = 0; $i < count( $activities ); $i++ ) {
204
- $activities_formatted[$i]['content'] = $activities[$i]->content;
205
- $activities_formatted[$i]['primary_link'] = $activities[$i]->primary_link;
206
- $activities_formatted[$i]['date_recorded'] = $activities[$i]->date_recorded;
207
- $activities_formatted[$i]['component_name'] = $activities[$i]->component_name;
208
- $activities_formatted[$i]['component_action'] = $activities[$i]->component_action;
209
- }
210
 
211
- return array( 'activities' => $activities_formatted, 'total' => (int)$total_activities );
 
 
 
 
 
 
212
  }
213
 
214
  function get_sitewide_items_for_feed( $limit = 35 ) {
@@ -227,105 +248,90 @@ Class BP_Activity_Activity {
227
  return $activity_feed;
228
  }
229
 
230
- function cache_friends_activities( $activity_array ) {
231
- global $wpdb, $bp;
232
 
233
- /* Empty the cache */
234
- $wpdb->query( "TRUNCATE TABLE {$bp->activity->table_name_loggedin_user_friends_cached}" );
235
-
236
- for ( $i = 0; $i < count($activity_array); $i++ ) {
237
- // Cache that sucka...
238
- $cached = $wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->activity->table_name_loggedin_user_friends_cached} ( user_id, content, primary_link, component_name, component_action, date_cached, date_recorded ) VALUES ( %d, %s, %s, %s, %s, FROM_UNIXTIME(%d), %s )", $activity_array[$i]['user_id'], $activity_array[$i]['content'], $activity_array[$i]['primary_link'], $activity_array[$i]['component_name'], $activity_array[$i]['component_action'], time(), $activity_array[$i]['date_recorded'] ) );
 
 
 
 
 
 
 
 
 
239
  }
240
-
241
- update_usermeta( $bp->loggedin_user->id, 'bp_activity_friends_last_cached', time() );
242
- }
243
-
244
- function cache_activities( $activity_array, $user_id ) {
245
- global $wpdb, $bp;
246
 
247
- /* Delete cached items older than 30 days for the user */
248
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_user_activity_cached} WHERE user_id = %d AND DATE_ADD(date_recorded, INTERVAL 30 DAY) <= NOW()", $user_id ) );
249
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_sitewide} WHERE user_id = %d AND DATE_ADD(date_recorded, INTERVAL 30 DAY) <= NOW()", $user_id ) );
250
-
251
- for ( $i = 0; $i < count($activity_array); $i++ ) {
252
- if ( empty( $activity_array[$i]['content'] ) ) continue;
253
-
254
- // Cache that sucka...
255
- $wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->activity->table_name_user_activity_cached} ( user_id, content, item_id, secondary_item_id, primary_link, component_name, component_action, date_cached, date_recorded, is_private ) VALUES ( %d, %s, %d, %d, %s, %s, %s, FROM_UNIXTIME(%d), %s, %d )", $user_id, $activity_array[$i]['content'], $activity_array[$i]['item_id'], $activity_array[$i]['secondary_item_id'], $activity_array[$i]['primary_link'], $activity_array[$i]['component_name'], $activity_array[$i]['component_action'], time(), $activity_array[$i]['date_recorded'], $activity_array[$i]['is_private'] ) );
256
-
257
- // Add to the sitewide activity stream
258
- if ( !$activity_array[$i]['is_private'] && !$activity_array[$i]['no_sitewide_cache'] )
259
- $wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->activity->table_name_sitewide} ( user_id, content, item_id, secondary_item_id, primary_link, component_name, component_action, date_cached, date_recorded ) VALUES ( %d, %s, %d, %d, %s, %s, %s, FROM_UNIXTIME(%d), %s )", $user_id, $activity_array[$i]['content'], $activity_array[$i]['item_id'], $activity_array[$i]['secondary_item_id'], $activity_array[$i]['primary_link'], $activity_array[$i]['component_name'], $activity_array[$i]['component_action'], time(), $activity_array[$i]['date_recorded'] ) );
 
 
260
  }
261
 
262
- update_usermeta( $bp->displayed_user->id, 'bp_activity_last_cached', time() );
263
- }
264
-
265
- function delete_activity_for_user( $user_id ) {
266
- global $wpdb, $bp;
267
-
268
- /* Empty user's activities from the sitewide stream */
269
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_sitewide} WHERE user_id = %d", $user_id ) );
 
 
 
 
 
 
 
 
270
 
271
- /* Empty the user's activity items and cached activity items */
272
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_user_activity} WHERE user_id = %d", $user_id ) );
273
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_user_activity_cached} WHERE user_id = %d", $user_id ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
274
 
275
- return true;
276
  }
277
 
278
  function get_last_updated() {
279
  global $bp, $wpdb;
280
 
281
- return $wpdb->get_var( $wpdb->prepare( "SELECT date_recorded FROM " . $bp->activity->table_name_sitewide . " ORDER BY date_recorded ASC LIMIT 1" ) );
282
  }
283
 
284
- function kill_tables_for_user( $user_id ) {
285
- global $bp, $wpdb;
286
 
287
- if ( !$wpdb->get_var( "SHOW TABLES LIKE 'wp_user_{$user_id}_activity'" ) )
288
- return false;
289
-
290
- $wpdb->query( $wpdb->prepare( "DROP TABLE wp_user_{$user_id}_activity" ) );
291
- $wpdb->query( $wpdb->prepare( "DROP TABLE wp_user_{$user_id}_activity_cached" ) );
292
- $wpdb->query( $wpdb->prepare( "DROP TABLE wp_user_{$user_id}_friends_activity_cached" ) );
293
-
294
- return true;
295
- }
296
-
297
- function convert_tables_for_user( $user_id ) {
298
- global $bp, $wpdb;
299
-
300
- if ( !$wpdb->get_var( "SHOW TABLES LIKE 'wp_user_{$user_id}_activity'" ) )
301
- return false;
302
-
303
- $activity_items = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM wp_user_{$user_id}_activity" ) );
304
- $activity_cached_items = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM wp_user_{$user_id}_activity_cached" ) );
305
-
306
- if ( $activity_items ) {
307
- foreach ( $activity_items as $activity_item ) {
308
- $wpdb->query( $wpdb->prepare(
309
- "INSERT INTO {$bp->activity->table_name_user_activity}
310
- ( item_id, secondary_item_id, user_id, component_name, component_action, date_recorded, is_private, no_sitewide_cache )
311
- VALUES
312
- ( %d, %d, %d, %s, %s, %s, %d, %d )",
313
- $activity_item->item_id, $activity_item->secondary_item_id, $user_id, $activity_item->component_name, $activity_item->component_action, $activity_item->date_recorded, $activity_item->is_private, $activity_item->no_sitewide_cache
314
- ) );
315
- }
316
- }
317
-
318
- if ( $activity_cached_items ) {
319
- foreach ( $activity_cached_items as $activity_cached_item ) {
320
- $wpdb->query( $wpdb->prepare(
321
- "INSERT INTO {$bp->activity->table_name_user_activity_cached}
322
- ( content, primary_link, item_id, secondary_item_id, user_id, component_name, component_action, date_recorded, date_cached, is_private )
323
- VALUES
324
- ( %s, %s, %d, %d, %d, %s, %s, %s, %s, %d )",
325
- $activity_cached_item->content, $activity_cached_item->primary_link, $activity_cached_item->item_id, $activity_cached_item->secondary_item_id, $user_id, $activity_cached_item->component_name, $activity_cached_item->component_action, $activity_cached_item->date_recorded, $activity_cached_item->date_cached, $activity_cached_item->is_private
326
- ) );
327
- }
328
- }
329
  }
330
  }
331
 
9
  var $component_name;
10
  var $component_action;
11
  var $date_recorded;
12
+ var $hide_sitewide = false;
 
13
 
14
+ function bp_activity_activity( $id = false ) {
 
 
 
 
15
  global $bp;
16
 
17
  if ( $id ) {
18
  $this->id = $id;
19
+ $this->populate();
 
 
20
  }
21
  }
22
 
23
  function populate() {
24
  global $wpdb, $bp;
25
 
26
+ $activity = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE id = %d", $this->id ) );
27
+
28
+ $this->id = $activity->id;
29
  $this->item_id = $activity->item_id;
30
  $this->secondary_item_id = $activity->secondary_item_id;
31
  $this->user_id = $activity->user_id;
32
+ $this->content = $activity->content;
33
+ $this->primary_link = $activity->primary_link;
34
  $this->component_name = $activity->component_name;
35
  $this->component_action = $activity->component_action;
36
  $this->date_recorded = $activity->date_recorded;
37
+ $this->hide_sitewide = $activity->hide_sitewide;
 
38
  }
39
 
40
  function save() {
42
 
43
  do_action( 'bp_activity_before_save', $this );
44
 
45
+ if ( !$this->component_name || !$this->component_action )
46
  return false;
47
+
48
+ /***
49
+ * Before v1.1 of BuddyPress, activity content was calculated at a later point. This is no longer the
50
+ * case, to to be backwards compatible we need to fetch content here to continue.
51
+ */
52
+ if ( empty( $this->content ) || !$this->content ) {
 
 
 
 
53
  if ( function_exists( $bp->{$this->component_name}->format_activity_function ) ) {
54
+ if ( !$fetched_content = call_user_func( $bp->{$this->component_name}->format_activity_function, $this->item_id, $this->user_id, $this->component_action, $this->secondary_item_id, $this->for_secondary_user ) )
55
  return false;
56
+
57
+ $this->content = $fetched_content['content'];
58
+ $this->primary_link = $fetched_content['primary_link'];
59
  }
60
+ }
61
+
62
+ if ( !$this->primary_link )
63
+ $this->primary_link = $bp->loggedin_user->domain;
64
+
65
+ if ( $existing_activity_id = $this->exists() )
66
+ BP_Activity_Activity::delete_by_activity_id( $existing_activity_id );
67
+
68
+ /* If we have an existing ID, update the activity item, otherwise insert it. */
69
+ if ( $this->id ) {
70
+ if ( $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET user_id = %d, component_name = %s, component_action = %s, content = %s, primary_link = %s, date_recorded = FROM_UNIXTIME(%d), item_id = %s, secondary_item_id = %s, hide_sitewide = %d WHERE id = %d", $this->user_id, $this->component_name, $this->component_action, $this->content, $this->primary_link, $this->date_recorded, $this->item_id, $this->secondary_item_id, $this->hide_sitewide, $this->id ) ) ) {
71
+ do_action( 'bp_activity_after_save', $this );
72
+ return true;
73
+ }
74
+ } else {
75
+ if ( $wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->activity->table_name} ( user_id, component_name, component_action, content, primary_link, date_recorded, item_id, secondary_item_id, hide_sitewide ) VALUES ( %d, %s, %s, %s, %s, FROM_UNIXTIME(%d), %s, %s, %d )", $this->user_id, $this->component_name, $this->component_action, $this->content, $this->primary_link, $this->date_recorded, $this->item_id, $this->secondary_item_id, $this->hide_sitewide ) ) ) {
76
  do_action( 'bp_activity_after_save', $this );
77
  return true;
78
  }
 
 
79
  }
80
+
81
+ return false;
82
  }
83
 
84
  function exists() {
85
  global $wpdb, $bp;
86
+
87
+ /* This doesn't seem to be working correctly at the moment, so it is disabled [TODO] */
88
+ return false;
89
+
90
+ /* If we have an item id, try and match on that, if not do a content match */
91
+ if ( $this->item_id ) {
92
+ if ( $this->secondary_item_id )
93
+ $secondary_sql = $wpdb->prepare( " AND secondary_item_id = %s", $secondary_item_id );
94
+
95
+ return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE user_id = %d AND item_id = %s{$secondary_sql} AND component_name = %s AND component_action = %s", $this->user_id, $this->item_id, $this->component_name, $this->component_action ) );
96
+ } else {
97
+ return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE user_id = %d AND content = %s AND component_name = %s AND component_action = %s", $this->user_id, $this->content, $this->component_name, $this->component_action ) );
98
+ }
99
  }
100
 
101
  /* Static Functions */
102
 
103
+ function delete( $item_id, $component_name, $component_action, $user_id = false, $secondary_item_id = false ) {
104
  global $wpdb, $bp;
105
+
106
+ if ( $secondary_item_id )
107
+ $secondary_sql = $wpdb->prepare( "AND secondary_item_id = %s", $secondary_item_id );
108
 
109
+ if ( $component_action )
110
+ $component_action_sql = $wpdb->prepare( "AND component_action = %s", $component_action );
111
 
112
+ if ( $user_id )
113
+ $user_sql = $wpdb->prepare( "AND user_id = %d", $user_id );
114
+
115
+ return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name} WHERE item_id = %s {$secondary_sql} AND component_name = %s {$component_action_sql} {$user_sql}", $item_id, $component_name ) );
116
+ }
117
+
118
+ function delete_by_item_id( $item_id, $component_name, $component_action, $user_id = false, $secondary_item_id = false ) {
119
+ return BP_Activity_Activity::delete( $item_id, $component_name, $component_action, $user_id, $secondary_item_id );
120
+ }
121
+
122
+ function delete_by_activity_id( $activity_id ) {
123
+ global $bp, $wpdb;
124
 
125
+ return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name} WHERE id = %d", $activity_id ) );
126
+ }
127
+
128
+ function delete_by_content( $user_id, $content, $component_name, $component_action ) {
129
+ global $bp, $wpdb;
130
+
131
+ return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name} WHERE user_id = %d AND content = %s AND component_name = %s AND component_action = %s", $user_id, $content, $component_name, $component_action ) );
132
+ }
133
+
134
+ function delete_for_user_by_component( $user_id, $component_name ) {
135
+ global $bp, $wpdb;
136
+
137
+ return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name} WHERE user_id = %d AND component_name = %s", $user_id, $component_name ) );
138
+ }
139
+
140
+ function delete_for_user( $user_id ) {
141
+ global $wpdb, $bp;
142
 
143
+ return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name} WHERE user_id = %d", $user_id ) );
144
  }
145
 
146
+ function get_activity_for_user( $user_id, $max_items, $limit, $page, $filter ) {
147
  global $wpdb, $bp;
148
 
149
  $since = strtotime($since);
151
  if ( $limit && $page )
152
  $pag_sql = $wpdb->prepare( "LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
153
 
154
+ if ( $max_items )
155
+ $max_sql = $wpdb->prepare( "LIMIT %d", $max_items );
156
 
157
+ /* Sort out filtering */
158
+ if ( $filter )
159
+ $filter_sql = BP_Activity_Activity::get_filter_sql( $filter );
160
+
161
+ if ( $limit && $page && $max_items )
162
+ $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE user_id = %d $filter_sql ORDER BY date_recorded DESC $pag_sql", $user_id ) );
163
  else
164
+ $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE user_id = %d $filter_sql ORDER BY date_recorded DESC $pag_sql $max_sql", $user_id ) );
165
+
166
+ $total_activities = $wpdb->get_var( $wpdb->prepare( "SELECT count(id) FROM {$bp->activity->table_name} WHERE user_id = %d $filter_sql ORDER BY date_recorded DESC $max_sql", $user_id ) );
 
 
 
 
 
 
 
 
 
 
 
167
 
168
+ return array( 'activities' => $activities, 'total' => (int)$total_activities );
169
  }
170
 
171
+ function get_activity_for_friends( $user_id, $max_items, $max_items_per_friend, $limit, $page, $filter ) {
172
  global $wpdb, $bp;
173
 
174
  // TODO: Max items per friend not yet implemented.
179
  if ( $limit && $page )
180
  $pag_sql = $wpdb->prepare( "LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
181
 
182
+ if ( $max_items )
183
+ $max_sql = $wpdb->prepare( "LIMIT %d", $max_items );
184
+
185
+ /* Sort out filtering */
186
+ if ( $filter )
187
+ $filter_sql = BP_Activity_Activity::get_filter_sql( $filter );
188
 
189
  $friend_ids = friends_get_friend_user_ids( $user_id );
190
 
193
 
194
  $friend_ids = implode( ',', $friend_ids );
195
 
196
+ if ( $limit && $page && $max_items )
197
+ $activities = $wpdb->get_results( $wpdb->prepare( "SELECT DISTINCT id, user_id, content, primary_link, date_recorded, component_name, component_action FROM {$bp->activity->table_name} WHERE user_id IN ({$friend_ids}) $filter_sql ORDER BY date_recorded DESC $pag_sql" ) );
198
  else
199
+ $activities = $wpdb->get_results( $wpdb->prepare( "SELECT DISTINCT id, user_id, content, primary_link, date_recorded, component_name, component_action FROM {$bp->activity->table_name} WHERE user_id IN ({$friend_ids}) $filter_sql ORDER BY date_recorded DESC $pag_sql $max_sql" ) );
200
+
201
+ $total_activities = $wpdb->get_var( $wpdb->prepare( "SELECT DISTINCT count(user_id) FROM {$bp->activity->table_name} WHERE user_id IN ({$friend_ids}) $filter_sql ORDER BY date_recorded DESC $max_sql" ) );
202
 
203
  return array( 'activities' => $activities, 'total' => (int)$total_activities );
204
  }
205
 
206
+ function get_sitewide_activity( $max, $limit, $page, $filter ) {
207
  global $wpdb, $bp;
208
 
209
  if ( $limit && $page )
211
 
212
  if ( $max )
213
  $max_sql = $wpdb->prepare( "LIMIT %d", $max );
214
+
215
+ /* Sort out filtering */
216
+ if ( $filter )
217
+ $filter_sql = BP_Activity_Activity::get_filter_sql( $filter );
218
 
 
 
 
219
  if ( $limit && $page && $max )
220
+ $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE hide_sitewide = 0 $filter_sql ORDER BY date_recorded DESC $pag_sql" ) );
221
  else
222
+ $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE hide_sitewide = 0 $filter_sql ORDER BY date_recorded DESC $pag_sql $max_sql" ) );
223
 
224
+ $total_activities = $wpdb->get_var( $wpdb->prepare( "SELECT count(id) FROM {$bp->activity->table_name} WHERE hide_sitewide = 0 $filter_sql ORDER BY date_recorded DESC $max_sql" ) );
 
 
 
 
 
 
 
 
225
 
226
+ return array( 'activities' => $activities, 'total' => (int)$total_activities );
227
+ }
228
+
229
+ function get_recorded_component_names() {
230
+ global $wpdb, $bp;
231
+
232
+ return $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT component_name FROM {$bp->activity->table_name} ORDER BY component_name ASC" ) );
233
  }
234
 
235
  function get_sitewide_items_for_feed( $limit = 35 ) {
248
  return $activity_feed;
249
  }
250
 
251
+ function get_filter_sql( $filter_array ) {
252
+ global $wpdb;
253
 
254
+ if ( !empty( $filter_array['object'] ) ) {
255
+ $object_filter = explode( ',', $filter_array['object'] );
256
+ $object_sql = ' AND ( ';
257
+
258
+ $counter = 1;
259
+ foreach( (array) $object_filter as $object ) {
260
+ $object_sql .= $wpdb->prepare( "component_name = %s", trim( $object ) );
261
+
262
+ if ( $counter != count( $object_filter ) )
263
+ $object_sql .= ' || ';
264
+
265
+ $counter++;
266
+ }
267
+
268
+ $object_sql .= ' )';
269
  }
 
 
 
 
 
 
270
 
271
+ if ( !empty( $filter_array['action'] ) ) {
272
+ $action_filter = explode( ',', $filter_array['action'] );
273
+ $action_sql = ' AND ( ';
274
+
275
+ $counter = 1;
276
+ foreach( (array) $action_filter as $action ) {
277
+ $action_sql .= $wpdb->prepare( "component_action = %s", trim( $action ) );
278
+
279
+ if ( $counter != count( $action_filter ) )
280
+ $action_sql .= ' || ';
281
+
282
+ $counter++;
283
+ }
284
+
285
+ $action_sql .= ' )';
286
  }
287
 
288
+ if ( !empty( $filter_array['primary_id'] ) ) {
289
+ $pid_filter = explode( ',', $filter_array['primary_id'] );
290
+ $pid_sql = ' AND ( ';
291
+
292
+ $counter = 1;
293
+ foreach( (array) $pid_filter as $pid ) {
294
+ $pid_sql .= $wpdb->prepare( "item_id = %s", trim( $pid ) );
295
+
296
+ if ( $counter != count( $pid_filter ) )
297
+ $pid_sql .= ' || ';
298
+
299
+ $counter++;
300
+ }
301
+
302
+ $pid_sql .= ' )';
303
+ }
304
 
305
+ if ( !empty( $filter_array['secondary_id'] ) ) {
306
+ $sid_filter = explode( ',', $filter_array['secondary_id'] );
307
+ $sid_sql = ' AND ( ';
308
+
309
+ $counter = 1;
310
+ foreach( (array) $sid_filter as $sid ) {
311
+ $sid_sql .= $wpdb->prepare( "secondary_item_id = %s", trim( $sid ) );
312
+
313
+ if ( $counter != count( $sid_filter ) )
314
+ $sid_sql .= ' || ';
315
+
316
+ $counter++;
317
+ }
318
+
319
+ $sid_sql .= ' )';
320
+ }
321
 
322
+ return $object_sql . $action_sql . $pid_sql . $sid_sql;
323
  }
324
 
325
  function get_last_updated() {
326
  global $bp, $wpdb;
327
 
328
+ return $wpdb->get_var( $wpdb->prepare( "SELECT date_recorded FROM {$bp->activity->table_name} ORDER BY date_recorded ASC LIMIT 1" ) );
329
  }
330
 
331
+ function check_exists_by_content( $content ) {
332
+ global $wpdb, $bp;
333
 
334
+ return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE content = %s", $content ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
  }
336
  }
337
 
bp-activity/bp-activity-cssjs.php DELETED
@@ -1,10 +0,0 @@
1
- <?php
2
-
3
- function bp_activity_add_structure_css() {
4
- /* Enqueue the structure CSS file to give basic positional formatting for components */
5
- wp_enqueue_style( 'bp-activity-structure', BP_PLUGIN_URL . '/bp-activity/css/structure.css' );
6
- }
7
- add_action( 'bp_styles', 'bp_activity_add_structure_css' );
8
-
9
-
10
- ?>
 
 
 
 
 
 
 
 
 
 
bp-activity/bp-activity-filters.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /* Apply WordPress defined filters */
4
- add_filter( 'bp_get_activity_content', 'wp_filter_kses', 1 );
5
  add_filter( 'bp_get_activity_content', 'force_balance_tags' );
6
  add_filter( 'bp_get_activity_content', 'wptexturize' );
7
  add_filter( 'bp_get_activity_content', 'convert_smilies' );
@@ -10,11 +10,24 @@ add_filter( 'bp_get_activity_content', 'wpautop' );
10
  add_filter( 'bp_get_activity_content', 'make_clickable' );
11
  add_filter( 'bp_get_activity_content', 'stripslashes_deep' );
12
 
13
- function bp_activity_add_allowed_tags( $allowedtags ) {
14
- $allowedtags['span'] = array();
15
- $allowedtags['span']['class'] = array();
16
- return $allowedtags;
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
- add_filter( 'edit_allowedtags', 'bp_activity_add_allowed_tags', 1 );
19
 
20
  ?>
1
  <?php
2
 
3
  /* Apply WordPress defined filters */
4
+ add_filter( 'bp_get_activity_content', 'bp_activity_filter_kses', 1 );
5
  add_filter( 'bp_get_activity_content', 'force_balance_tags' );
6
  add_filter( 'bp_get_activity_content', 'wptexturize' );
7
  add_filter( 'bp_get_activity_content', 'convert_smilies' );
10
  add_filter( 'bp_get_activity_content', 'make_clickable' );
11
  add_filter( 'bp_get_activity_content', 'stripslashes_deep' );
12
 
13
+ function bp_activity_filter_kses( $content ) {
14
+ global $allowedtags;
15
+
16
+ $activity_allowedtags = $allowedtags;
17
+ $activity_allowedtags['span'] = array();
18
+ $activity_allowedtags['span']['class'] = array();
19
+ $activity_allowedtags['a']['class'] = array();
20
+ $activity_allowedtags['img'] = array();
21
+ $activity_allowedtags['img']['src'] = array();
22
+ $activity_allowedtags['img']['alt'] = array();
23
+ $activity_allowedtags['img']['class'] = array();
24
+ $activity_allowedtags['img']['width'] = array();
25
+ $activity_allowedtags['img']['height'] = array();
26
+ $activity_allowedtags['img']['class'] = array();
27
+ $activity_allowedtags['img']['id'] = array();
28
+
29
+ return wp_kses( $content, $activity_allowedtags );
30
  }
31
+
32
 
33
  ?>
bp-activity/bp-activity-templatetags.php CHANGED
@@ -16,22 +16,21 @@ class BP_Activity_Template {
16
 
17
  var $full_name;
18
 
19
- function bp_activity_template( $type, $user_id, $per_page, $max, $timeframe ) {
20
  global $bp;
21
 
22
  $this->pag_page = isset( $_REQUEST['acpage'] ) ? intval( $_REQUEST['acpage'] ) : 1;
23
  $this->pag_num = isset( $_REQUEST['num'] ) ? intval( $_REQUEST['num'] ) : $per_page;
24
- $this->filter_content = false;
25
  $this->activity_type = $type;
26
 
27
  if ( $type == 'sitewide' )
28
- $this->activities = bp_activity_get_sitewide_activity( $max, $this->pag_num, $this->pag_page );
29
 
30
  if ( $type == 'personal' )
31
- $this->activities = bp_activity_get_user_activity( $user_id, $timeframe, $this->page_num, $this->pag_page );
32
 
33
  if ( $type == 'friends' && ( bp_is_home() || is_site_admin() || $bp->loggedin_user->id == $user_id ) )
34
- $this->activities = bp_activity_get_friends_activity( $user_id, $timeframe, $this->pag_num, $this->pag_page );
35
 
36
  if ( !$max || $max >= (int)$this->activities['total'] )
37
  $this->total_activity_count = (int)$this->activities['total'];
@@ -51,15 +50,17 @@ class BP_Activity_Template {
51
 
52
  $this->full_name = $bp->displayed_user->fullname;
53
 
54
- $this->pag_links = paginate_links( array(
55
- 'base' => add_query_arg( 'acpage', '%#%' ),
56
- 'format' => '',
57
- 'total' => ceil( (int)$this->total_activity_count / (int)$this->pag_num ),
58
- 'current' => (int)$this->pag_page,
59
- 'prev_text' => '&laquo;',
60
- 'next_text' => '&raquo;',
61
- 'mid_size' => 1
62
- ));
 
 
63
  }
64
 
65
  function has_activities() {
@@ -87,7 +88,7 @@ class BP_Activity_Template {
87
  if ( $this->current_activity + 1 < $this->activity_count ) {
88
  return true;
89
  } elseif ( $this->current_activity + 1 == $this->activity_count ) {
90
- do_action('loop_end');
91
  // Do some cleaning up after the loop
92
  $this->rewind_activities();
93
  }
@@ -106,49 +107,28 @@ class BP_Activity_Template {
106
  $this->activity = (object) $this->activity;
107
 
108
  if ( $this->current_activity == 0 ) // loop has just started
109
- do_action('loop_start');
110
  }
111
  }
112
 
113
- function bp_activity_get_list( $user_id, $title, $no_activity, $limit = false ) {
114
- global $bp_activity_user_id, $bp_activity_limit, $bp_activity_title, $bp_activity_no_activity;
115
 
116
- $bp_activity_user_id = $user_id;
117
- $bp_activity_limit = $limit;
118
- $bp_activity_title = $title;
119
- $bp_activity_no_activity = $no_activity;
120
 
121
- load_template( TEMPLATEPATH . '/activity/activity-list.php' );
122
- }
123
-
124
- function bp_has_activities( $args = '' ) {
125
- global $bp, $activities_template, $bp_activity_user_id, $bp_activity_limit;
126
-
127
  $defaults = array(
128
  'type' => 'sitewide',
129
- 'user_id' => false,
130
  'per_page' => 25,
131
  'max' => false,
132
- 'timeframe' => '-4 weeks'
 
 
 
 
133
  );
134
 
135
  $r = wp_parse_args( $args, $defaults );
136
  extract( $r, EXTR_SKIP );
137
-
138
- // The following lines are for backwards template compatibility.
139
- if ( 'my-friends' == $bp->current_action && $bp->activity->slug == $bp->current_component )
140
- $type = 'friends';
141
-
142
- if ( $bp->displayed_user->id && $bp->activity->slug == $bp->current_component && ( !$bp->current_action || 'just-me' == $bp->current_action ) )
143
- $type = 'personal';
144
-
145
- if ( $bp->displayed_user->id && $bp->profile->slug == $bp->current_component )
146
- $type = 'personal';
147
-
148
- if ( $bp_activity_limit )
149
- $max = $bp_activity_limit;
150
-
151
- // END backwards compatibility ---
152
 
153
  if ( ( 'personal' == $type || 'friends' == $type ) && !$user_id )
154
  $user_id = (int)$bp->displayed_user->id;
@@ -158,8 +138,13 @@ function bp_has_activities( $args = '' ) {
158
  $per_page = $max;
159
  }
160
 
161
- $activities_template = new BP_Activity_Template( $type, $user_id, $per_page, $max, $timeframe );
162
- return $activities_template->has_activities();
 
 
 
 
 
163
  }
164
 
165
  function bp_activities() {
@@ -179,7 +164,7 @@ function bp_activity_pagination_count() {
179
  $to_num = ( $from_num + ( $activities_template->pag_num - 1 ) > $activities_template->total_activity_count ) ? $activities_template->total_activity_count : $from_num + ( $activities_template->pag_num - 1) ;
180
 
181
  echo sprintf( __( 'Viewing item %d to %d (of %d items)', 'buddypress' ), $from_num, $to_num, $activities_template->total_activity_count ); ?> &nbsp;
182
- <img id="ajax-loader-activity" src="<?php echo $bp->core->image_base ?>/ajax-loader.gif" height="7" alt="<?php _e( "Loading", "buddypress" ) ?>" style="display: none;" /><?php
183
  }
184
 
185
  function bp_activity_pagination_links() {
@@ -213,25 +198,68 @@ function bp_activities_no_activity() {
213
  return apply_filters( 'bp_get_activities_no_activity', $bp_activity_no_activity );
214
  }
215
 
216
- function bp_activity_content() {
217
- global $activities_template;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
 
 
219
  echo bp_get_activity_content();
220
  }
221
  function bp_get_activity_content() {
222
- global $activities_template, $allowed_tags;
223
 
224
- if ( bp_is_home() && $activities_template->activity_type == 'personal' ) {
225
  $content = bp_activity_content_filter( $activities_template->activity->content, $activities_template->activity->date_recorded, $activities_template->full_name );
226
- } else {
227
- $activities_template->activity->content = bp_activity_insert_time_since( $activities_template->activity->content, $activities_template->activity->date_recorded );
228
- $content = $activities_template->activity->content;
229
- }
 
230
 
231
  return apply_filters( 'bp_get_activity_content', $content );
232
  }
233
 
234
  function bp_activity_content_filter( $content, $date_recorded, $full_name, $insert_time = true, $filter_words = true, $filter_you = true ) {
 
 
235
  if ( !$content )
236
  return false;
237
 
@@ -244,7 +272,7 @@ function bp_activity_content_filter( $content, $date_recorded, $full_name, $inse
244
  /* Insert the time since */
245
  if ( $insert_time )
246
  $content[0] = bp_activity_insert_time_since( $content[0], $date_recorded );
247
-
248
  // The "You" and "Your" conversion is only done in english, if a translation file is present
249
  // then do not translate as it causes problems in other languages.
250
  if ( '' == get_locale() ) {
@@ -255,9 +283,13 @@ function bp_activity_content_filter( $content, $date_recorded, $full_name, $inse
255
 
256
  /* Remove the 'You' and replace if with the persons name */
257
  if ( $filter_you && $full_name != '' ) {
258
- $content[0] = preg_replace( "/{$full_name}[<]/", 'You<', $content[0] );
259
  }
260
  }
 
 
 
 
261
 
262
  $content_new = '';
263
 
@@ -286,13 +318,84 @@ function bp_activity_css_class() {
286
  return apply_filters( 'bp_get_activity_css_class', $activities_template->activity->component_name );
287
  }
288
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
  function bp_sitewide_activity_feed_link() {
290
  echo bp_get_sitewide_activity_feed_link();
291
  }
292
  function bp_get_sitewide_activity_feed_link() {
293
  global $bp;
294
 
295
- return apply_filters( 'bp_get_sitewide_activity_feed_link', site_url() . '/' . $bp->activity->slug . '/feed' );
296
  }
297
 
298
  function bp_activities_member_rss_link() {
16
 
17
  var $full_name;
18
 
19
+ function bp_activity_template( $type, $user_id, $per_page, $max, $filter ) {
20
  global $bp;
21
 
22
  $this->pag_page = isset( $_REQUEST['acpage'] ) ? intval( $_REQUEST['acpage'] ) : 1;
23
  $this->pag_num = isset( $_REQUEST['num'] ) ? intval( $_REQUEST['num'] ) : $per_page;
 
24
  $this->activity_type = $type;
25
 
26
  if ( $type == 'sitewide' )
27
+ $this->activities = bp_activity_get_sitewide_activity( $max, $this->pag_num, $this->pag_page, $filter );
28
 
29
  if ( $type == 'personal' )
30
+ $this->activities = bp_activity_get_user_activity( $user_id, $max, $this->pag_num, $this->pag_page, $filter );
31
 
32
  if ( $type == 'friends' && ( bp_is_home() || is_site_admin() || $bp->loggedin_user->id == $user_id ) )
33
+ $this->activities = bp_activity_get_friends_activity( $user_id, $max, false, $this->pag_num, $this->pag_page, $filter );
34
 
35
  if ( !$max || $max >= (int)$this->activities['total'] )
36
  $this->total_activity_count = (int)$this->activities['total'];
50
 
51
  $this->full_name = $bp->displayed_user->fullname;
52
 
53
+ if ( (int) $this->total_activity_count && (int) $this->pag_num ) {
54
+ $this->pag_links = paginate_links( array(
55
+ 'base' => add_query_arg( 'acpage', '%#%' ),
56
+ 'format' => '',
57
+ 'total' => ceil( (int)$this->total_activity_count / (int)$this->pag_num ),
58
+ 'current' => (int)$this->pag_page,
59
+ 'prev_text' => '&laquo;',
60
+ 'next_text' => '&raquo;',
61
+ 'mid_size' => 1
62
+ ));
63
+ }
64
  }
65
 
66
  function has_activities() {
88
  if ( $this->current_activity + 1 < $this->activity_count ) {
89
  return true;
90
  } elseif ( $this->current_activity + 1 == $this->activity_count ) {
91
+ do_action('activity_loop_end');
92
  // Do some cleaning up after the loop
93
  $this->rewind_activities();
94
  }
107
  $this->activity = (object) $this->activity;
108
 
109
  if ( $this->current_activity == 0 ) // loop has just started
110
+ do_action('activity_loop_start');
111
  }
112
  }
113
 
114
+ function bp_has_activities( $args = '' ) {
115
+ global $bp, $activities_template;
116
 
117
+ /* Note: any params used for filtering can be a single value, or multiple values comma separated. */
 
 
 
118
 
 
 
 
 
 
 
119
  $defaults = array(
120
  'type' => 'sitewide',
 
121
  'per_page' => 25,
122
  'max' => false,
123
+ 'user_id' => false, // user_id to filter on
124
+ 'object' => false, // object to filter on e.g. groups, profile, status, friends
125
+ 'action' => false, // action to filter on e.g. new_wire_post, new_forum_post, profile_updated
126
+ 'primary_id' => false, // object ID to filter on e.g. a group_id or forum_id or blog_id etc.
127
+ 'secondary_id' => false, // secondary object ID to filter on e.g. a post_id
128
  );
129
 
130
  $r = wp_parse_args( $args, $defaults );
131
  extract( $r, EXTR_SKIP );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
 
133
  if ( ( 'personal' == $type || 'friends' == $type ) && !$user_id )
134
  $user_id = (int)$bp->displayed_user->id;
138
  $per_page = $max;
139
  }
140
 
141
+ if ( isset( $_GET['afilter'] ) )
142
+ $filter = array( 'object' => $_GET['afilter'] );
143
+ else
144
+ $filter = array( 'object' => $object, 'action' => $action, 'primary_id' => $primary_id, 'secondary_id' => $secondary_id );
145
+
146
+ $activities_template = new BP_Activity_Template( $type, $user_id, $per_page, $max, $filter );
147
+ return apply_filters( 'bp_has_activities', $activities_template->has_activities(), &$activities_template );
148
  }
149
 
150
  function bp_activities() {
164
  $to_num = ( $from_num + ( $activities_template->pag_num - 1 ) > $activities_template->total_activity_count ) ? $activities_template->total_activity_count : $from_num + ( $activities_template->pag_num - 1) ;
165
 
166
  echo sprintf( __( 'Viewing item %d to %d (of %d items)', 'buddypress' ), $from_num, $to_num, $activities_template->total_activity_count ); ?> &nbsp;
167
+ <span class="ajax-loader"></span><?php
168
  }
169
 
170
  function bp_activity_pagination_links() {
198
  return apply_filters( 'bp_get_activities_no_activity', $bp_activity_no_activity );
199
  }
200
 
201
+ function bp_activity_user_id() {
202
+ echo bp_get_activity_user_id();
203
+ }
204
+ function bp_get_activity_user_id() {
205
+ global $activities_template;
206
+ return apply_filters( 'bp_get_activity_user_id', $activities_template->activity->user_id );
207
+ }
208
+
209
+ function bp_activity_avatar( $args = '' ) {
210
+ echo bp_get_activity_avatar( $args );
211
+ }
212
+ function bp_get_activity_avatar( $args = '' ) {
213
+ global $bp, $activities_template;
214
+
215
+ $defaults = array(
216
+ 'type' => 'thumb',
217
+ 'width' => 20,
218
+ 'height' => 20,
219
+ 'class' => 'avatar',
220
+ 'alt' => __( 'Avatar', 'buddypress' )
221
+ );
222
+
223
+ $r = wp_parse_args( $args, $defaults );
224
+ extract( $r, EXTR_SKIP );
225
+
226
+ $item_id = false;
227
+ if ( (int)$activities_template->activity->user_id )
228
+ $item_id = $activities_template->activity->user_id;
229
+ else if ( $activities_template->activity->item_id )
230
+ $item_id = $activities_template->activity->item_id;
231
+
232
+ $object = 'user';
233
+ if ( $bp->groups->id == $activities_template->activity->component_name && !(int) $activities_template->activity->user_id )
234
+ $object = 'group';
235
+ if ( $bp->blogs->id == $activities_template->activity->component_name && !(int) $activities_template->activity->user_id )
236
+ $object = 'blog';
237
+
238
+ $object = apply_filters( 'bp_get_activity_avatar_object_' . $activities_template->activity->component_name, $object );
239
+
240
+ return apply_filters( 'bp_get_group_avatar', bp_core_fetch_avatar( array( 'item_id' => $item_id, 'object' => $object, 'type' => $type, 'alt' => $alt, 'class' => $class, 'width' => $width, 'height' => $height ) ) );
241
+ }
242
 
243
+ function bp_activity_content() {
244
  echo bp_get_activity_content();
245
  }
246
  function bp_get_activity_content() {
247
+ global $activities_template, $allowed_tags, $bp;
248
 
249
+ if ( bp_is_home() && $activities_template->activity_type == 'personal' )
250
  $content = bp_activity_content_filter( $activities_template->activity->content, $activities_template->activity->date_recorded, $activities_template->full_name );
251
+ else
252
+ $content = bp_activity_content_filter( $activities_template->activity->content, $activities_template->activity->date_recorded, $activities_template->full_name, true, false, false );
253
+
254
+ /* Add 'the_content' filter to activity to allow existing plugins to replace text as they would on post text. (extra smilies etc) */
255
+ $content = apply_filters( 'the_content', $content );
256
 
257
  return apply_filters( 'bp_get_activity_content', $content );
258
  }
259
 
260
  function bp_activity_content_filter( $content, $date_recorded, $full_name, $insert_time = true, $filter_words = true, $filter_you = true ) {
261
+ global $activities_template, $bp;
262
+
263
  if ( !$content )
264
  return false;
265
 
272
  /* Insert the time since */
273
  if ( $insert_time )
274
  $content[0] = bp_activity_insert_time_since( $content[0], $date_recorded );
275
+
276
  // The "You" and "Your" conversion is only done in english, if a translation file is present
277
  // then do not translate as it causes problems in other languages.
278
  if ( '' == get_locale() ) {
283
 
284
  /* Remove the 'You' and replace if with the persons name */
285
  if ( $filter_you && $full_name != '' ) {
286
+ $content[0] = preg_replace( "/{$full_name}[<]/", 'You<', $content[0], 1 );
287
  }
288
  }
289
+
290
+ /* Add the delete link if the user has permission on this item */
291
+ if ( ( $activities_template->activity->user_id == $bp->loggedin_user->id ) || $bp->is_item_admin || is_site_admin() )
292
+ $content[1] = '</span> <span class="activity-delete-link">' . bp_get_activity_delete_link() . '</span>' . $content[1];
293
 
294
  $content_new = '';
295
 
318
  return apply_filters( 'bp_get_activity_css_class', $activities_template->activity->component_name );
319
  }
320
 
321
+ function bp_activity_delete_link() {
322
+ echo bp_get_activity_delete_link();
323
+ }
324
+ function bp_get_activity_delete_link() {
325
+ global $activities_template, $bp;
326
+
327
+ return apply_filters( 'bp_get_activity_delete_link', '<a href="' . wp_nonce_url( $bp->root_domain . '/' . $bp->activity->slug . '/delete/' . $activities_template->activity->id, 'bp_activity_delete_link' ) . '" class="item-button delete-activity confirm">' . __( 'Delete', 'buddypress' ) . '</a>' );
328
+ }
329
+
330
+ function bp_activity_filter_links( $args = false ) {
331
+ echo bp_get_activity_filter_links( $args );
332
+ }
333
+ function bp_get_activity_filter_links( $args = false ) {
334
+ global $activities_template, $bp;
335
+
336
+ $defaults = array(
337
+ 'style' => 'list'
338
+ );
339
+
340
+ $r = wp_parse_args( $args, $defaults );
341
+ extract( $r, EXTR_SKIP );
342
+
343
+ /* Fetch the names of components that have activity recorded in the DB */
344
+ $component_names = BP_Activity_Activity::get_recorded_component_names();
345
+
346
+ if ( !$component_names )
347
+ return false;
348
+
349
+ foreach ( (array) $component_names as $component_name ) {
350
+ if ( isset( $_GET['afilter'] ) && $component_name == $_GET['afilter'] )
351
+ $selected = ' class="selected"';
352
+ else
353
+ unset($selected);
354
+
355
+ switch ( $style ) {
356
+ case 'list':
357
+ $tag = 'li';
358
+ $before = '<li id="afilter-' . $component_name . '"' . $selected . '>';
359
+ $after = '</li>';
360
+ break;
361
+ case 'paragraph':
362
+ $tag = 'p';
363
+ $before = '<p id="afilter-' . $component_name . '"' . $selected . '>';
364
+ $after = '</p>';
365
+ break;
366
+ case 'span':
367
+ $tag = 'span';
368
+ $before = '<span id="afilter-' . $component_name . '"' . $selected . '>';
369
+ $after = '</span>';
370
+ break;
371
+ }
372
+
373
+ $link = add_query_arg( 'afilter', $component_name );
374
+ $link = remove_query_arg( 'acpage' , $link );
375
+
376
+ $link = apply_filters( 'bp_get_activity_filter_link_href', $link, $component_name );
377
+
378
+ /* Make sure all core internal component names are translatable */
379
+ $translatable_component_names = array( __( 'profile', 'buddypress'), __( 'friends', 'buddypress' ), __( 'groups', 'buddypress' ), __( 'status', 'buddypress' ), __( 'blogs', 'buddypress' ) );
380
+
381
+ $component_links[] = $before . '<a href="' . $link . '">' . ucwords( __( $component_name, 'buddypress' ) ) . '</a>' . $after;
382
+ }
383
+
384
+ $link = remove_query_arg( 'afilter' , $link );
385
+
386
+ if ( isset( $_GET['afilter'] ) )
387
+ $component_links[] = '<' . $tag . ' id="afilter-clear"><a href="' . $link . '"">' . __( 'Clear Filter', 'buddypress' ) . '</a></' . $tag . '>';
388
+
389
+ return apply_filters( 'bp_get_activity_filter_links', implode( "\n", $component_links ) );
390
+ }
391
+
392
  function bp_sitewide_activity_feed_link() {
393
  echo bp_get_sitewide_activity_feed_link();
394
  }
395
  function bp_get_sitewide_activity_feed_link() {
396
  global $bp;
397
 
398
+ return apply_filters( 'bp_get_sitewide_activity_feed_link', site_url( $bp->activity->slug . '/feed' ) );
399
  }
400
 
401
  function bp_activities_member_rss_link() {
bp-activity/bp-activity-widgets.php CHANGED
@@ -8,60 +8,78 @@ add_action( 'plugins_loaded', 'bp_activity_register_widgets' );
8
 
9
  class BP_Activity_Widget extends WP_Widget {
10
  function bp_activity_widget() {
11
- parent::WP_Widget( false, $name = 'Site Wide Activity' );
12
- wp_enqueue_style( 'bp-activity-widget-activity-css', BP_PLUGIN_URL . '/bp-activity/css/widget-activity.css' );
13
  }
14
 
15
  function widget($args, $instance) {
16
  global $bp;
17
 
18
- extract( $args );
19
 
20
  echo $before_widget;
21
  echo $before_title
22
- . $widget_name
 
23
  . $after_title; ?>
24
-
25
- <?php
26
- if ( !$activity = wp_cache_get( 'sitewide_activity', 'bp' ) ) {
27
- $activity = bp_activity_get_sitewide_activity( $instance['max_items'] );
28
- wp_cache_set( 'sitewide_activity', $activity, 'bp' );
29
- }
30
- ?>
31
 
32
- <?php if ( $activity['activities'] ) : ?>
33
- <div class="item-options" id="activity-list-options">
34
- <img src="<?php echo $bp->activity->image_base; ?>/rss.png" alt="<?php _e( 'RSS Feed', 'buddypress' ) ?>" /> <a href="<?php bp_sitewide_activity_feed_link() ?>" title="<?php _e( 'Site Wide Activity RSS Feed', 'buddypress' ) ?>"><?php _e( 'RSS Feed', 'buddypress' ) ?></a>
 
 
 
 
 
 
35
  </div>
36
- <ul id="site-wide-stream" class="activity-list">
37
- <?php foreach( $activity['activities'] as $item ) : ?>
38
- <li class="<?php echo $item['component_name'] ?>">
39
- <?php echo apply_filters( 'bp_get_activity_content', bp_activity_content_filter( $item['content'], $item['date_recorded'], '', true, false, true ) ); ?>
40
- </li>
41
- <?php endforeach; ?>
42
  </ul>
43
- <?php else: ?>
44
- <div class="widget-error">
45
- <?php _e('There has been no recent site activity.', 'buddypress') ?>
46
- </div>
47
  <?php endif; ?>
48
-
49
- <?php echo $after_widget; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  <?php
51
  }
52
 
53
  function update( $new_instance, $old_instance ) {
54
  $instance = $old_instance;
55
  $instance['max_items'] = strip_tags( $new_instance['max_items'] );
 
56
 
57
  return $instance;
58
  }
59
 
60
  function form( $instance ) {
61
- $instance = wp_parse_args( (array) $instance, array( 'max_items' => 30 ) );
 
62
  $max_items = strip_tags( $instance['max_items'] );
63
  ?>
64
 
 
65
  <p><label for="bp-core-widget-members-max"><?php _e('Max items to show:', 'buddypress'); ?> <input class="widefat" id="<?php echo $this->get_field_id( 'max_items' ); ?>" name="<?php echo $this->get_field_name( 'max_items' ); ?>" type="text" value="<?php echo attribute_escape( $max_items ); ?>" style="width: 30%" /></label></p>
66
  <?php
67
  }
8
 
9
  class BP_Activity_Widget extends WP_Widget {
10
  function bp_activity_widget() {
11
+ parent::WP_Widget( false, $name = __( 'Site Wide Activity', 'buddypress' ) );
 
12
  }
13
 
14
  function widget($args, $instance) {
15
  global $bp;
16
 
17
+ extract( $args );
18
 
19
  echo $before_widget;
20
  echo $before_title
21
+ . $widget_name .
22
+ ' <a class="rss-image" href="' . bp_get_sitewide_activity_feed_link() . '" title="' . __( 'Site Wide Activity RSS Feed', 'buddypress' ) . '">' . __( '[RSS]', 'buddypress' ) . '</a>'
23
  . $after_title; ?>
24
+
25
+ <?php if ( bp_has_activities( 'type=sitewide&max=' . $instance['max_items'] . '&per_page=' . $instance['per_page'] ) ) : ?>
 
 
 
 
 
26
 
27
+ <?php if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) ) : ?>
28
+ <div class="pagination">
29
+ <div class="pag-count" id="activity-count">
30
+ <?php bp_activity_pagination_count() ?>
31
+ </div>
32
+
33
+ <div class="pagination-links" id="activity-pag">
34
+ &nbsp; <?php bp_activity_pagination_links() ?>
35
+ </div>
36
  </div>
37
+
38
+ <ul id="activity-filter-links">
39
+ <?php bp_activity_filter_links() ?>
 
 
 
40
  </ul>
 
 
 
 
41
  <?php endif; ?>
42
+
43
+ <ul id="site-wide-stream" class="activity-list">
44
+ <?php while ( bp_activities() ) : bp_the_activity(); ?>
45
+ <li class="<?php bp_activity_css_class() ?>">
46
+ <?php if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) ) : ?>
47
+ <div class="activity-avatar">
48
+ <?php bp_activity_avatar() ?>
49
+ </div>
50
+ <?php endif; ?>
51
+
52
+ <?php bp_activity_content() ?>
53
+ </li>
54
+ <?php endwhile; ?>
55
+ </ul>
56
+
57
+ <?php else: ?>
58
+
59
+ <div class="widget-error">
60
+ <?php _e('There has been no recent site activity.', 'buddypress') ?>
61
+ </div>
62
+ <?php endif;?>
63
+
64
+ <?php echo $after_widget; ?>
65
  <?php
66
  }
67
 
68
  function update( $new_instance, $old_instance ) {
69
  $instance = $old_instance;
70
  $instance['max_items'] = strip_tags( $new_instance['max_items'] );
71
+ $instance['per_page'] = strip_tags( $new_instance['per_page'] );
72
 
73
  return $instance;
74
  }
75
 
76
  function form( $instance ) {
77
+ $instance = wp_parse_args( (array) $instance, array( 'max_items' => 200, 'per_page' => 25 ) );
78
+ $per_page = strip_tags( $instance['per_page'] );
79
  $max_items = strip_tags( $instance['max_items'] );
80
  ?>
81
 
82
+ <p><label for="bp-activity-widget-sitewide-per-page"><?php _e('Number of Items Per Page:', 'buddypress'); ?> <input class="widefat" id="<?php echo $this->get_field_id( 'per_page' ); ?>" name="<?php echo $this->get_field_name( 'per_page' ); ?>" type="text" value="<?php echo attribute_escape( $per_page ); ?>" style="width: 30%" /></label></p>
83
  <p><label for="bp-core-widget-members-max"><?php _e('Max items to show:', 'buddypress'); ?> <input class="widefat" id="<?php echo $this->get_field_id( 'max_items' ); ?>" name="<?php echo $this->get_field_name( 'max_items' ); ?>" type="text" value="<?php echo attribute_escape( $max_items ); ?>" style="width: 30%" /></label></p>
84
  <?php
85
  }
bp-activity/css/widget-activity.css DELETED
@@ -1,14 +0,0 @@
1
- .bp_activity_widget_sitewide_activity span.time-since {
2
- font-size: 11px;
3
- }
4
-
5
- .bp_activity_widget_sitewide_activity ul#site-wide-stream {
6
- margin: 0;
7
- padding: 0;
8
- list-style: none;
9
- }
10
-
11
- .widget_bp_core_recently_active_widget div.item-avatar {
12
- display: inline;
13
- margin: 0 5px 5x 0;
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/deprecated/bp-activity-deprecated.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /***
3
+ * Deprecated Activity Stream Functionality
4
+ *
5
+ * This file contains functions that are deprecated.
6
+ * You should not under any circumstance use these functions as they are
7
+ * either no longer valid, or have been replaced with something much more awesome.
8
+ *
9
+ * If you are using functions in this file you should slap the back of your head
10
+ * and then use the functions or solutions that have replaced them.
11
+ * Most functions contain a note telling you what you should be doing or using instead.
12
+ *
13
+ * Of course, things will still work if you use these functions but you will
14
+ * be the laughing stock of the BuddyPress community. We will all point and laugh at
15
+ * you. You'll also be making things harder for yourself in the long run,
16
+ * and you will miss out on lovely performance and functionality improvements.
17
+ *
18
+ * If you've checked you are not using any deprecated functions and finished your little
19
+ * dance, you can add the following line to your wp-config.php file to prevent any of
20
+ * these old functions from being loaded:
21
+ *
22
+ * define( 'BP_IGNORE_DEPRECATED', true );
23
+ */
24
+
25
+ function bp_activity_deprecated_globals() {
26
+ global $bp;
27
+
28
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
29
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
30
+ return $template;
31
+
32
+ $bp->activity->image_base = BP_PLUGIN_URL . '/bp-activity/images';
33
+ }
34
+ add_action( 'plugins_loaded', 'bp_activity_deprecated_globals', 5 );
35
+ add_action( 'admin_menu', 'bp_activity_deprecated_globals', 2 );
36
+
37
+ /* DEPRECATED - use bp_activity_add() */
38
+ function bp_activity_record( $item_id, $component_name, $component_action, $is_private, $secondary_item_id = false, $user_id = false, $secondary_user_id = false, $recorded_time = false ) {
39
+ global $bp, $wpdb;
40
+
41
+ if ( !$user_id )
42
+ $user_id = $bp->loggedin_user->id;
43
+
44
+ if ( !$recorded_time )
45
+ $recorded_time = time();
46
+
47
+ $args = compact( 'user_id', 'content', 'component_name', 'component_action', 'item_id', 'secondary_item_id', 'recorded_time' );
48
+ bp_activity_add( $args );
49
+
50
+ if ( $secondary_user_id ) {
51
+ $hide_sitewide = true;
52
+ $args = compact( 'user_id', 'content', 'component_name', 'component_action', 'item_id', 'secondary_item_id', 'recorded_time', 'hide_sitewide' );
53
+ bp_activity_add( $args );
54
+ }
55
+
56
+ do_action( 'bp_activity_record', $item_id, $component_name, $component_action, $is_private, $secondary_item_id, $user_id, $secondary_user_id );
57
+
58
+ return true;
59
+ }
60
+
61
+ /* DEPRECATED - use bp_activity_delete_by_item_id() */
62
+ function bp_activity_delete( $item_id, $component_name, $component_action, $user_id, $secondary_item_id ) {
63
+ if ( !bp_activity_delete_by_item_id( array( 'item_id' => $item_id, 'component_name' => $component_name, 'component_action' => $component_action, 'user_id' => $user_id, 'secondary_item_id' => $secondary_item_id ) ) )
64
+ return false;
65
+
66
+ do_action( 'bp_activity_delete', $item_id, $component_name, $component_action, $user_id, $secondary_item_id );
67
+
68
+ return true;
69
+ }
70
+
71
+ /* DEPRECATED - use the activity template loop directly */
72
+ function bp_activity_get_list( $user_id, $title, $no_activity, $limit = false ) {
73
+ global $bp_activity_user_id, $bp_activity_limit, $bp_activity_title, $bp_activity_no_activity;
74
+
75
+ $bp_activity_user_id = $user_id;
76
+ $bp_activity_limit = $limit;
77
+ $bp_activity_title = $title;
78
+ $bp_activity_no_activity = $no_activity;
79
+
80
+ locate_template( array( '/activity/activity-list.php' ), true );
81
+ }
82
+
83
+
84
+ /* DEPRECATED - Structural CSS is now theme based. */
85
+ function bp_activity_add_structure_css() {
86
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
87
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
88
+ return $template;
89
+
90
+ /* Enqueue the structure CSS file to give basic positional formatting for components */
91
+ wp_enqueue_style( 'bp-activity-structure', BP_PLUGIN_URL . '/bp-activity/deprecated/css/structure.css' );
92
+ }
93
+ add_action( 'bp_styles', 'bp_activity_add_structure_css' );
94
+
95
+ ?>
bp-activity/{css → deprecated/css}/structure.css RENAMED
File without changes
bp-activity/{images → deprecated/images}/rss.png RENAMED
File without changes
bp-activity/feeds/bp-activity-friends-feed.php CHANGED
@@ -22,7 +22,7 @@ header('Status: 200 OK');
22
  <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
23
  <link><?php echo $bp->displayed_user->domain . $bp->activity->slug . '/my-friends/feed' ?></link>
24
  <description><?php printf( __( '%s - Friends Activity Feed', 'buddypress' ), $bp->displayed_user->fullname ) ?></description>
25
- <pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', bp_activity_get_last_updated(), false); ?></pubDate>
26
  <generator>http://buddypress.org/?v=<?php echo BP_VERSION ?></generator>
27
  <language><?php echo get_option('rss_language'); ?></language>
28
  <?php do_action('bp_activity_friends_feed_head'); ?>
@@ -33,7 +33,7 @@ header('Status: 200 OK');
33
  <guid><?php bp_activity_feed_item_guid() ?></guid>
34
  <title><![CDATA[<?php bp_activity_feed_item_title() ?>]]></title>
35
  <link><?php echo bp_activity_feed_item_link() ?></link>
36
- <pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', bp_get_activity_feed_item_date(), false); ?></pubDate>
37
 
38
  <description><![CDATA[<?php bp_activity_feed_item_description() ?>]]></description>
39
  <?php do_action('bp_activity_personal_feed_item'); ?>
22
  <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
23
  <link><?php echo $bp->displayed_user->domain . $bp->activity->slug . '/my-friends/feed' ?></link>
24
  <description><?php printf( __( '%s - Friends Activity Feed', 'buddypress' ), $bp->displayed_user->fullname ) ?></description>
25
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_activity_get_last_updated(), false); ?></pubDate>
26
  <generator>http://buddypress.org/?v=<?php echo BP_VERSION ?></generator>
27
  <language><?php echo get_option('rss_language'); ?></language>
28
  <?php do_action('bp_activity_friends_feed_head'); ?>
33
  <guid><?php bp_activity_feed_item_guid() ?></guid>
34
  <title><![CDATA[<?php bp_activity_feed_item_title() ?>]]></title>
35
  <link><?php echo bp_activity_feed_item_link() ?></link>
36
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_get_activity_feed_item_date(), false); ?></pubDate>
37
 
38
  <description><![CDATA[<?php bp_activity_feed_item_description() ?>]]></description>
39
  <?php do_action('bp_activity_personal_feed_item'); ?>
bp-activity/feeds/bp-activity-personal-feed.php CHANGED
@@ -22,7 +22,7 @@ header('Status: 200 OK');
22
  <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
23
  <link><?php echo $bp->displayed_user->domain . $bp->activity->slug . '/feed' ?></link>
24
  <description><?php printf( __( '%s - Activity Feed', 'buddypress' ), $bp->displayed_user->fullname ) ?></description>
25
- <pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', bp_activity_get_last_updated(), false); ?></pubDate>
26
  <generator>http://buddypress.org/?v=<?php echo BP_VERSION ?></generator>
27
  <language><?php echo get_option('rss_language'); ?></language>
28
  <?php do_action('bp_activity_personal_feed_head'); ?>
@@ -33,7 +33,7 @@ header('Status: 200 OK');
33
  <guid><?php bp_activity_feed_item_guid() ?></guid>
34
  <title><![CDATA[<?php bp_activity_feed_item_title() ?>]]></title>
35
  <link><?php echo bp_activity_feed_item_link() ?></link>
36
- <pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', bp_get_activity_feed_item_date(), false); ?></pubDate>
37
 
38
  <description><![CDATA[<?php bp_activity_feed_item_description() ?>]]></description>
39
  <?php do_action('bp_activity_personal_feed_item'); ?>
22
  <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
23
  <link><?php echo $bp->displayed_user->domain . $bp->activity->slug . '/feed' ?></link>
24
  <description><?php printf( __( '%s - Activity Feed', 'buddypress' ), $bp->displayed_user->fullname ) ?></description>
25
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_activity_get_last_updated(), false); ?></pubDate>
26
  <generator>http://buddypress.org/?v=<?php echo BP_VERSION ?></generator>
27
  <language><?php echo get_option('rss_language'); ?></language>
28
  <?php do_action('bp_activity_personal_feed_head'); ?>
33
  <guid><?php bp_activity_feed_item_guid() ?></guid>
34
  <title><![CDATA[<?php bp_activity_feed_item_title() ?>]]></title>
35
  <link><?php echo bp_activity_feed_item_link() ?></link>
36
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_get_activity_feed_item_date(), false); ?></pubDate>
37
 
38
  <description><![CDATA[<?php bp_activity_feed_item_description() ?>]]></description>
39
  <?php do_action('bp_activity_personal_feed_item'); ?>
bp-activity/feeds/bp-activity-sitewide-feed.php CHANGED
@@ -23,7 +23,7 @@ header('Status: 200 OK');
23
  <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
24
  <link><?php echo site_url() . '/' . $bp->activity->slug . '/feed' ?></link>
25
  <description><?php _e( 'Site Wide Activity Feed', 'buddypress' ) ?></description>
26
- <pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', bp_activity_get_last_updated(), false); ?></pubDate>
27
  <generator>http://buddypress.org/?v=<?php echo BP_VERSION ?></generator>
28
  <language><?php echo get_option('rss_language'); ?></language>
29
  <?php do_action('bp_activity_sitewide_feed_head'); ?>
@@ -34,7 +34,7 @@ header('Status: 200 OK');
34
  <guid><?php bp_activity_feed_item_guid() ?></guid>
35
  <title><![CDATA[<?php bp_activity_feed_item_title() ?>]]></title>
36
  <link><?php bp_activity_feed_item_link() ?></link>
37
- <pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', bp_get_activity_feed_item_date(), false); ?></pubDate>
38
 
39
  <description><![CDATA[<?php bp_activity_feed_item_description() ?>]]></description>
40
  <?php do_action('bp_activity_personal_feed_item'); ?>
23
  <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
24
  <link><?php echo site_url() . '/' . $bp->activity->slug . '/feed' ?></link>
25
  <description><?php _e( 'Site Wide Activity Feed', 'buddypress' ) ?></description>
26
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_activity_get_last_updated(), false); ?></pubDate>
27
  <generator>http://buddypress.org/?v=<?php echo BP_VERSION ?></generator>
28
  <language><?php echo get_option('rss_language'); ?></language>
29
  <?php do_action('bp_activity_sitewide_feed_head'); ?>
34
  <guid><?php bp_activity_feed_item_guid() ?></guid>
35
  <title><![CDATA[<?php bp_activity_feed_item_title() ?>]]></title>
36
  <link><?php bp_activity_feed_item_link() ?></link>
37
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s O', bp_get_activity_feed_item_date(), false); ?></pubDate>
38
 
39
  <description><![CDATA[<?php bp_activity_feed_item_description() ?>]]></description>
40
  <?php do_action('bp_activity_personal_feed_item'); ?>
bp-blogs.php CHANGED
@@ -1,24 +1,19 @@
1
  <?php
2
 
3
- define ( 'BP_BLOGS_DB_VERSION', '1300' );
4
 
5
  /* Define the slug for the component */
6
  if ( !defined( 'BP_BLOGS_SLUG' ) )
7
  define ( 'BP_BLOGS_SLUG', 'blogs' );
8
 
9
  require ( BP_PLUGIN_DIR . '/bp-blogs/bp-blogs-classes.php' );
10
- require ( BP_PLUGIN_DIR . '/bp-blogs/bp-blogs-cssjs.php' );
11
  require ( BP_PLUGIN_DIR . '/bp-blogs/bp-blogs-templatetags.php' );
12
  require ( BP_PLUGIN_DIR . '/bp-blogs/bp-blogs-widgets.php' );
13
- require ( BP_PLUGIN_DIR . '/bp-blogs/bp-blogs-ajax.php' );
14
-
15
-
16
- /**************************************************************************
17
- bp_blogs_install()
18
-
19
- Sets up the database tables ready for use on a site installation.
20
- **************************************************************************/
21
 
 
 
 
 
22
  function bp_blogs_install() {
23
  global $wpdb, $bp;
24
 
@@ -98,7 +93,6 @@ function bp_blogs_install() {
98
  update_site_option( 'bp-blogs-db-version', BP_BLOGS_DB_VERSION );
99
  }
100
 
101
-
102
  function bp_blogs_check_installed() {
103
  global $wpdb, $bp, $userdata;
104
 
@@ -110,36 +104,32 @@ function bp_blogs_check_installed() {
110
  }
111
  add_action( 'admin_menu', 'bp_blogs_check_installed' );
112
 
113
-
114
- /**************************************************************************
115
- bp_blogs_setup_globals()
116
-
117
- Set up and add all global variables for this component, and add them to
118
- the $bp global variable array.
119
- **************************************************************************/
120
-
121
  function bp_blogs_setup_globals() {
122
  global $bp, $wpdb;
123
-
 
 
 
124
  $bp->blogs->table_name = $wpdb->base_prefix . 'bp_user_blogs';
125
  $bp->blogs->table_name_blog_posts = $wpdb->base_prefix . 'bp_user_blogs_posts';
126
  $bp->blogs->table_name_blog_comments = $wpdb->base_prefix . 'bp_user_blogs_comments';
127
  $bp->blogs->table_name_blogmeta = $wpdb->base_prefix . 'bp_user_blogs_blogmeta';
128
- $bp->blogs->format_activity_function = 'bp_blogs_format_activity';
129
  $bp->blogs->format_notification_function = 'bp_blogs_format_notifications';
130
- $bp->blogs->image_base = BP_PLUGIN_URL . '/bp-groups/images';
131
  $bp->blogs->slug = BP_BLOGS_SLUG;
 
 
 
132
 
133
- $bp->version_numbers->blogs = BP_BLOGS_VERSION;
134
  }
135
  add_action( 'plugins_loaded', 'bp_blogs_setup_globals', 5 );
136
- add_action( 'admin_menu', 'bp_blogs_setup_globals', 1 );
137
 
138
  function bp_blogs_setup_root_component() {
139
  /* Register 'groups' as a root component */
140
  bp_core_add_root_component( BP_BLOGS_SLUG );
141
  }
142
- add_action( 'plugins_loaded', 'bp_blogs_setup_root_component', 1 );
143
 
144
  /**
145
  * bp_blogs_setup_nav()
@@ -154,19 +144,16 @@ function bp_blogs_setup_nav() {
154
  global $bp;
155
 
156
  /* Add 'Blogs' to the main navigation */
157
- bp_core_add_nav_item( __( 'Blogs', 'buddypress' ), $bp->blogs->slug );
158
-
159
- if ( $bp->displayed_user->id )
160
- bp_core_add_nav_default( $bp->blogs->slug, 'bp_blogs_screen_my_blogs', 'my-blogs' );
161
 
162
  $blogs_link = $bp->loggedin_user->domain . $bp->blogs->slug . '/';
163
 
164
  /* Add the subnav items to the blogs nav item */
165
- bp_core_add_subnav_item( $bp->blogs->slug, 'my-blogs', __('My Blogs', 'buddypress'), $blogs_link, 'bp_blogs_screen_my_blogs', 'my-blogs-list' );
166
- bp_core_add_subnav_item( $bp->blogs->slug, 'recent-posts', __('Recent Posts', 'buddypress'), $blogs_link, 'bp_blogs_screen_recent_posts' );
167
- bp_core_add_subnav_item( $bp->blogs->slug, 'recent-comments', __('Recent Comments', 'buddypress'), $blogs_link, 'bp_blogs_screen_recent_comments' );
168
- bp_core_add_subnav_item( $bp->blogs->slug, 'create-a-blog', __('Create a Blog', 'buddypress'), $blogs_link, 'bp_blogs_screen_create_a_blog' );
169
-
170
  /* Set up the component options navigation for Blog */
171
  if ( 'blogs' == $bp->current_component ) {
172
  if ( bp_is_home() ) {
@@ -175,26 +162,37 @@ function bp_blogs_setup_nav() {
175
  }
176
  } else {
177
  /* If we are not viewing the logged in user, set up the current users avatar and name */
178
- $bp->bp_options_avatar = bp_core_get_avatar( $bp->displayed_user->id, 1 );
179
  $bp->bp_options_title = $bp->displayed_user->fullname;
180
  }
181
  }
 
 
182
  }
183
- add_action( 'wp', 'bp_blogs_setup_nav', 2 );
184
- add_action( 'admin_menu', 'bp_blogs_setup_nav', 2 );
185
 
186
  function bp_blogs_directory_blogs_setup() {
187
  global $bp;
188
-
189
  if ( $bp->current_component == $bp->blogs->slug && empty( $bp->current_action ) ) {
190
  $bp->is_directory = true;
191
-
192
- wp_enqueue_script( 'bp-blogs-directory-blogs', BP_PLUGIN_URL . '/bp-blogs/js/directory-blogs.js', array( 'jquery', 'jquery-livequery-pack' ) );
193
  bp_core_load_template( apply_filters( 'bp_blogs_template_directory_blogs_setup', 'directories/blogs/index' ) );
194
  }
195
  }
196
  add_action( 'wp', 'bp_blogs_directory_blogs_setup', 2 );
197
 
 
 
 
 
 
 
 
 
 
198
  function bp_blogs_screen_my_blogs() {
199
  do_action( 'bp_blogs_screen_my_blogs' );
200
  bp_core_load_template( apply_filters( 'bp_blogs_template_my_blogs', 'blogs/my-blogs' ) );
@@ -216,122 +214,79 @@ function bp_blogs_screen_create_a_blog() {
216
  }
217
 
218
 
219
- /**************************************************************************
220
- bp_blogs_record_activity()
221
-
222
- Records activity for the logged in user within the friends component so that
223
- it will show in the users activity stream (if installed)
224
- **************************************************************************/
225
 
226
- function bp_blogs_record_activity( $args = true ) {
227
  global $bp;
228
 
229
- /* Because blog, comment, and blog post code execution happens before anything else
230
- we need to manually instantiate the activity component globals */
231
- if ( !$bp->activity && function_exists('bp_activity_setup_globals') )
232
- bp_activity_setup_globals();
233
 
234
- if ( function_exists('bp_activity_record') ) {
235
- extract($args);
236
-
237
- bp_activity_record( $item_id, $component_name, $component_action, $is_private, $secondary_item_id, $user_id, $secondary_user_id, $recorded_time );
238
- }
239
- }
240
 
241
- function bp_blogs_delete_activity( $args = true ) {
242
- if ( function_exists('bp_activity_delete') ) {
243
- extract($args);
244
- bp_activity_delete( $item_id, $component_name, $component_action, $user_id, $secondary_item_id );
245
- }
246
  }
 
247
 
248
- /**************************************************************************
249
- bp_blogs_format_activity()
250
-
251
- Selects and formats recorded blogs component activity.
252
- **************************************************************************/
253
-
254
- function bp_blogs_format_activity( $item_id, $user_id, $action, $secondary_item_id = false, $for_secondary_user = false ) {
255
  global $bp;
256
 
257
- switch( $action ) {
258
- case 'new_blog':
259
- $blog = new BP_Blogs_Blog($item_id);
260
-
261
- if ( !$blog )
262
- return false;
263
-
264
- if ( !$user_id )
265
- return false;
266
-
267
- $blog_url = get_blog_option( $blog->blog_id, 'siteurl' );
268
- $user_link = bp_core_get_userlink($user_id);
269
- $blog_name = get_blog_option( $blog->blog_id, 'blogname' );
270
-
271
- return array(
272
- 'primary_link' => $blog_url,
273
- 'content' => apply_filters( 'bp_blogs_new_blog_activity', sprintf( __( '%s created a new blog: %s', 'buddypress' ), $user_link, '<a href="' . $blog_url . '">' . $blog_name . '</a>' ) . ' <span class="time-since">%s</span>', $user_link, $blog_url, $blog_name )
274
- );
275
- break;
276
- case 'new_blog_post':
277
- $post = new BP_Blogs_Post( $item_id );
278
-
279
- if ( !$post )
280
- return false;
281
-
282
- $post = BP_Blogs_Post::fetch_post_content($post);
283
-
284
- if ( !$post || $post->post_type != 'post' )
285
- return false;
286
-
287
- $post_link = bp_post_get_permalink( $post, $post->blog_id );
288
- $user_link = bp_core_get_userlink($user_id);
289
-
290
- $content = sprintf( __( '%s wrote a new blog post: %s', 'buddypress' ), $user_link, '<a href="' . $post_link . '">' . $post->post_title . '</a>' ) . ' <span class="time-since">%s</span>';
291
- $content .= '<blockquote>' . bp_create_excerpt($post->post_content) . '</blockquote>';
292
-
293
- $content = apply_filters( 'bp_blogs_new_post_activity', $content, $user_link, $post );
294
-
295
- return array(
296
- 'primary_link' => $post_link,
297
- 'content' => $content
298
- );
299
- break;
300
- case 'new_blog_comment':
301
 
302
- if ( !is_user_logged_in() )
303
- return false;
304
-
305
- $comment = new BP_Blogs_Comment($secondary_item_id);
306
-
307
- if ( !$comment )
308
- return false;
 
 
 
 
 
 
 
 
 
309
 
310
- $comment = BP_Blogs_Comment::fetch_comment_content($comment);
311
-
312
- if ( !$comment )
313
- return false;
314
-
315
- $comment_link = bp_post_get_permalink( $comment->post, $comment->blog_id );
316
- $user_link = bp_core_get_userlink($user_id);
317
-
318
- $content = sprintf( __( '%s commented on the blog post %s', 'buddypress' ), $user_link, '<a href="' . $comment_link . '#comment-' . $comment->comment_ID . '">' . $comment->post->post_title . '</a>' ) . ' <span class="time-since">%s</span>';
319
- $content .= '<blockquote>' . bp_create_excerpt($comment->comment_content) . '</blockquote>';
320
-
321
- $content = apply_filters( 'bp_blogs_new_comment_activity', $content, $user_link, $comment );
322
 
323
- return array(
324
- 'primary_link' => $post_link . '#comment-' . $comment->comment_ID,
325
- 'content' => $content
326
- );
327
- break;
 
 
 
 
 
 
328
  }
329
-
330
- do_action( 'bp_blogs_format_activity', $action, $item_id, $user_id, $action, $secondary_item_id, $for_secondary_user );
331
-
332
- return false;
333
  }
334
 
 
 
 
 
 
 
 
 
 
335
  function bp_blogs_record_existing_blogs() {
336
  global $wpdb;
337
 
@@ -353,54 +308,55 @@ function bp_blogs_record_existing_blogs() {
353
  }
354
  }
355
 
356
-
357
- function bp_blogs_record_blog( $blog_id, $user_id ) {
358
  global $bp;
359
-
360
  if ( !$user_id )
361
  $user_id = $bp->loggedin_user->id;
362
-
363
  $name = get_blog_option( $blog_id, 'blogname' );
364
  $description = get_blog_option( $blog_id, 'blogdescription' );
365
 
366
  $recorded_blog = new BP_Blogs_Blog;
367
  $recorded_blog->user_id = $user_id;
368
  $recorded_blog->blog_id = $blog_id;
369
-
370
  $recorded_blog_id = $recorded_blog->save();
371
 
372
  bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'name', $name );
373
  bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'description', $description );
374
  bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'last_activity', time() );
375
-
376
- if ( (int)$_POST['blog_public'] )
377
- $is_private = 0;
378
- else
379
- $is_private = 1;
380
-
381
- // Record in activity streams
382
- bp_blogs_record_activity( array( 'item_id' => $recorded_blog_id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog', 'is_private' => $is_private, 'user_id' => $recorded_blog->user_id ) );
383
 
384
- do_action( 'bp_blogs_new_blog', $recorded_blog, $is_private, $is_recorded );
 
 
 
 
 
 
 
 
 
 
 
 
385
  }
386
  add_action( 'wpmu_new_blog', 'bp_blogs_record_blog', 10, 2 );
387
 
388
- function bp_blogs_record_post( $post_id, $blog_id = false, $user_id = false ) {
389
  global $bp, $wpdb;
390
-
391
  $post_id = (int)$post_id;
392
- $post = get_post($post_id);
393
 
394
  if ( !$user_id )
395
  $user_id = (int)$post->post_author;
396
-
397
- if ( !$blog_id )
398
- $blog_id = (int)$wpdb->blogid;
399
 
 
400
  /* This is to stop infinate loops with Donncha's sitewide tags plugin */
401
  if ( (int)get_site_option('tags_blog_id') == (int)$blog_id )
402
  return false;
403
-
404
  /* Don't record this if it's not a post */
405
  if ( $post->post_type != 'post' )
406
  return false;
@@ -417,40 +373,62 @@ function bp_blogs_record_post( $post_id, $blog_id = false, $user_id = false ) {
417
  $recorded_post_id = $recorded_post->save();
418
 
419
  bp_blogs_update_blogmeta( $recorded_post->blog_id, 'last_activity', time() );
420
- bp_blogs_record_activity( array( 'item_id' => $recorded_post->id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog_post', 'is_private' => bp_blogs_is_blog_hidden( $recorded_post->blog_id ), 'user_id' => $recorded_post->user_id, 'recorded_time' => strtotime( $post->post_date ) ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
421
  }
422
  } else {
423
  $existing_post = new BP_Blogs_Post( null, $blog_id, $post_id );
424
 
425
- /**
426
- * Delete the recorded post if:
427
- * - The status is no longer "published"
428
- * - The post is password protected
429
- */
430
- if ( 'publish' != $post->post_status || '' != $post->post_password )
431
- bp_blogs_remove_post( $post_id, $blog_id );
432
 
433
- // Check to see if the post author has changed.
434
- if ( (int)$existing_post->user_id != (int)$post->post_author ) {
435
  // Delete the existing recorded post
436
- bp_blogs_remove_post( $post_id, $blog_id );
437
 
438
  // Re-record the post with the new author.
439
- bp_blogs_record_post( $post_id );
440
  }
441
 
442
- $recorded_post = $existing_post;
 
 
443
 
444
- /* Delete and re-add the activity stream item to reflect potential content changes. */
445
- bp_blogs_delete_activity( array( 'item_id' => $recorded_post->id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog_post', 'user_id' => $recorded_post->user_id ) );
446
- bp_blogs_record_activity( array( 'item_id' => $recorded_post->id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog_post', 'is_private' => bp_blogs_is_blog_hidden( $recorded_post->blog_id ), 'user_id' => $recorded_post->user_id, 'recorded_time' => strtotime( $post->post_date ) ) );
 
 
 
 
 
 
 
 
 
447
  }
448
 
449
- do_action( 'bp_blogs_new_blog_post', $recorded_post, $is_private, $is_recorded );
450
  }
451
- add_action( 'publish_post', 'bp_blogs_record_post' );
452
- add_action( 'edit_post', 'bp_blogs_record_post' );
453
-
454
 
455
  function bp_blogs_record_comment( $comment_id, $is_approved ) {
456
  global $wpdb, $bp;
@@ -459,6 +437,7 @@ function bp_blogs_record_comment( $comment_id, $is_approved ) {
459
  return false;
460
 
461
  $comment = get_comment($comment_id);
 
462
 
463
  /* Get the user_id from the author email. */
464
  $user = get_user_by_email( $comment->comment_author_email );
@@ -477,30 +456,64 @@ function bp_blogs_record_comment( $comment_id, $is_approved ) {
477
  $recorded_commment_id = $recorded_comment->save();
478
 
479
  bp_blogs_update_blogmeta( $recorded_comment->blog_id, 'last_activity', time() );
480
- bp_blogs_record_activity( array( 'item_id' => $recorded_comment->blog_id, 'secondary_item_id' => $recorded_commment_id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog_comment', 'is_private' => $is_private, 'user_id' => $recorded_comment->user_id, 'recorded_time' => $recorded_comment->date_created ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
  }
482
  add_action( 'comment_post', 'bp_blogs_record_comment', 10, 2 );
483
 
484
- function bp_blogs_approve_comment( $comment_id, $comment ) {
485
  global $bp, $wpdb;
 
 
 
486
 
487
  $recorded_comment = bp_blogs_record_comment( $comment_id, true );
 
 
 
 
 
 
 
 
488
 
489
- bp_blogs_delete_activity( array( 'item_id' => $recorded_comment->blog_id, 'secondary_item_id' => $recorded_commment_id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog_comment', 'user_id' => $recorded_comment->user_id ) );
490
- bp_blogs_record_activity( array( 'item_id' => $recorded_comment->blog_id, 'secondary_item_id' => $recorded_commment_id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog_comment', 'is_private' => $is_private, 'user_id' => $recorded_comment->user_id, 'recorded_time' => $recorded_comment->date_created ) );
 
 
 
 
 
 
 
 
491
  }
492
- add_action( 'comment_approved_', 'bp_blogs_approve_comment', 10, 2 );
493
 
494
- function bp_blogs_unapprove_comment( $comment_id, $status = false ) {
495
- if ( 'spam' == $status || !$status )
496
  bp_blogs_remove_comment( $comment_id );
497
  }
498
- add_action( 'comment_unapproved_', 'bp_blogs_unapprove_comment' );
499
  add_action( 'wp_set_comment_status', 'bp_blogs_unapprove_comment', 10, 2 );
500
 
501
  function bp_blogs_add_user_to_blog( $user_id, $role, $blog_id ) {
502
  if ( $role != 'subscriber' ) {
503
- bp_blogs_record_blog( $blog_id, $user_id );
504
  }
505
  }
506
  add_action( 'add_user_to_blog', 'bp_blogs_add_user_to_blog', 10, 3 );
@@ -518,7 +531,7 @@ function bp_blogs_remove_blog( $blog_id ) {
518
  BP_Blogs_Blog::delete_blog_for_all( $blog_id );
519
 
520
  // Delete activity stream item
521
- bp_blogs_delete_activity( array( 'item_id' => $blog_id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog', 'user_id' => $bp->loggedin_user->id ) );
522
 
523
  do_action( 'bp_blogs_remove_blog', $blog_id );
524
  }
@@ -533,25 +546,28 @@ function bp_blogs_remove_blog_for_user( $user_id, $blog_id ) {
533
  BP_Blogs_Blog::delete_blog_for_user( $blog_id, $user_id );
534
 
535
  // Delete activity stream item
536
- bp_blogs_delete_activity( array( 'item_id' => $blog_id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog', 'user_id' => $current_user->ID ) );
537
 
538
  do_action( 'bp_blogs_remove_blog_for_user', $blog_id, $user_id );
539
  }
540
  add_action( 'remove_user_from_blog', 'bp_blogs_remove_blog_for_user', 10, 2 );
541
 
542
- function bp_blogs_remove_post( $post_id ) {
543
  global $current_blog, $bp;
544
 
545
  $post_id = (int)$post_id;
546
- $blog_id = (int)$current_blog->blog_id;
547
 
548
- $post = new BP_Blogs_Post( null, $blog_id, $post_id );
 
 
 
 
549
 
550
  // Delete post from the bp_blogs table
551
  BP_Blogs_Post::delete( $post_id, $blog_id );
552
 
553
  // Delete activity stream item
554
- bp_blogs_delete_activity( array( 'item_id' => $post->id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog_post', 'user_id' => $post->user_id ) );
555
 
556
  do_action( 'bp_blogs_remove_post', $blog_id, $post_id, $post->user_id );
557
  }
@@ -564,7 +580,7 @@ function bp_blogs_remove_comment( $comment_id ) {
564
  BP_Blogs_Comment::delete( $comment_id, $wpdb->blogid );
565
 
566
  // Delete activity stream item
567
- bp_blogs_delete_activity( array( 'item_id' => $recorded_comment->blog_id, 'secondary_item_id' => $recorded_comment->id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog_comment', 'user_id' => $recorded_comment->user_id ) );
568
 
569
  do_action( 'bp_blogs_remove_comment', $blog_id, $comment_id, $bp->loggedin_user->id );
570
  }
@@ -579,7 +595,7 @@ function bp_blogs_remove_data_for_blog( $blog_id ) {
579
  BP_Blogs_Comment::delete_comments_for_blog( $blog_id );
580
 
581
  // Delete activity stream item
582
- bp_blogs_delete_activity( array( 'item_id' => $blog_id, 'component_name' => $bp->blogs->slug, 'component_action' => false, 'user_id' => $bp->loggedin_user->id ) );
583
 
584
  do_action( 'bp_blogs_remove_data_for_blog', $blog_id );
585
  }
@@ -747,46 +763,6 @@ function bp_blogs_update_blogmeta( $blog_id, $meta_key, $meta_value ) {
747
  return true;
748
  }
749
 
750
- function bp_blogs_force_buddypress_theme( $template ) {
751
- global $bp;
752
-
753
- if ( $bp->current_component == $bp->blogs->slug && empty( $bp->current_action ) ) {
754
- $member_theme = get_site_option( 'active-member-theme' );
755
-
756
- if ( empty( $member_theme ) )
757
- $member_theme = 'bpmember';
758
-
759
- add_filter( 'theme_root', 'bp_core_filter_buddypress_theme_root' );
760
- add_filter( 'theme_root_uri', 'bp_core_filter_buddypress_theme_root_uri' );
761
-
762
- return $member_theme;
763
- } else {
764
- return $template;
765
- }
766
- }
767
- add_filter( 'template', 'bp_blogs_force_buddypress_theme', 1, 1 );
768
-
769
- function bp_blogs_force_buddypress_stylesheet( $stylesheet ) {
770
- global $bp;
771
-
772
- if ( $bp->current_component == $bp->blogs->slug && empty( $bp->current_action ) ) {
773
- $member_theme = get_site_option( 'active-member-theme' );
774
-
775
- if ( empty( $member_theme ) )
776
- $member_theme = 'bpmember';
777
-
778
- add_filter( 'theme_root', 'bp_core_filter_buddypress_theme_root' );
779
- add_filter( 'theme_root_uri', 'bp_core_filter_buddypress_theme_root_uri' );
780
-
781
- return $member_theme;
782
- } else {
783
- return $stylesheet;
784
- }
785
- }
786
- add_filter( 'stylesheet', 'bp_blogs_force_buddypress_stylesheet', 1, 1 );
787
-
788
-
789
-
790
  function bp_blogs_remove_data( $user_id ) {
791
  /* If this is regular blog, delete all data for that blog. */
792
  BP_Blogs_Blog::delete_blogs_for_user( $user_id );
@@ -798,7 +774,6 @@ function bp_blogs_remove_data( $user_id ) {
798
  add_action( 'wpmu_delete_user', 'bp_blogs_remove_data', 1 );
799
  add_action( 'delete_user', 'bp_blogs_remove_data', 1 );
800
 
801
-
802
  function bp_blogs_clear_blog_object_cache( $blog_id, $user_id ) {
803
  wp_cache_delete( 'bp_blogs_of_user_' . $user_id, 'bp' );
804
  wp_cache_delete( 'bp_blogs_for_user_' . $user_id, 'bp' );
@@ -856,6 +831,4 @@ add_action( 'bp_blogs_new_blog_post', 'bp_core_clear_cache' );
856
  add_action( 'bp_blogs_new_blog', 'bp_core_clear_cache' );
857
  add_action( 'bp_blogs_remove_data', 'bp_core_clear_cache' );
858
 
859
-
860
-
861
  ?>
1
  <?php
2
 
3
+ define ( 'BP_BLOGS_DB_VERSION', '1800' );
4
 
5
  /* Define the slug for the component */
6
  if ( !defined( 'BP_BLOGS_SLUG' ) )
7
  define ( 'BP_BLOGS_SLUG', 'blogs' );
8
 
9
  require ( BP_PLUGIN_DIR . '/bp-blogs/bp-blogs-classes.php' );
 
10
  require ( BP_PLUGIN_DIR . '/bp-blogs/bp-blogs-templatetags.php' );
11
  require ( BP_PLUGIN_DIR . '/bp-blogs/bp-blogs-widgets.php' );
 
 
 
 
 
 
 
 
12
 
13
+ /* Include deprecated functions if settings allow */
14
+ if ( !defined( 'BP_IGNORE_DEPRECATED' ) )
15
+ require ( BP_PLUGIN_DIR . '/bp-blogs/deprecated/bp-blogs-deprecated.php' );
16
+
17
  function bp_blogs_install() {
18
  global $wpdb, $bp;
19
 
93
  update_site_option( 'bp-blogs-db-version', BP_BLOGS_DB_VERSION );
94
  }
95
 
 
96
  function bp_blogs_check_installed() {
97
  global $wpdb, $bp, $userdata;
98
 
104
  }
105
  add_action( 'admin_menu', 'bp_blogs_check_installed' );
106
 
 
 
 
 
 
 
 
 
107
  function bp_blogs_setup_globals() {
108
  global $bp, $wpdb;
109
+
110
+ /* For internal identification */
111
+ $bp->blogs->id = 'blogs';
112
+
113
  $bp->blogs->table_name = $wpdb->base_prefix . 'bp_user_blogs';
114
  $bp->blogs->table_name_blog_posts = $wpdb->base_prefix . 'bp_user_blogs_posts';
115
  $bp->blogs->table_name_blog_comments = $wpdb->base_prefix . 'bp_user_blogs_comments';
116
  $bp->blogs->table_name_blogmeta = $wpdb->base_prefix . 'bp_user_blogs_blogmeta';
 
117
  $bp->blogs->format_notification_function = 'bp_blogs_format_notifications';
 
118
  $bp->blogs->slug = BP_BLOGS_SLUG;
119
+
120
+ /* Register this in the active components array */
121
+ $bp->active_components[$bp->blogs->slug] = $bp->blogs->id;
122
 
123
+ do_action( 'bp_blogs_setup_globals' );
124
  }
125
  add_action( 'plugins_loaded', 'bp_blogs_setup_globals', 5 );
126
+ add_action( 'admin_menu', 'bp_blogs_setup_globals', 2 );
127
 
128
  function bp_blogs_setup_root_component() {
129
  /* Register 'groups' as a root component */
130
  bp_core_add_root_component( BP_BLOGS_SLUG );
131
  }
132
+ add_action( 'plugins_loaded', 'bp_blogs_setup_root_component', 2 );
133
 
134
  /**
135
  * bp_blogs_setup_nav()
144
  global $bp;
145
 
146
  /* Add 'Blogs' to the main navigation */
147
+ bp_core_new_nav_item( array( 'name' => __( 'Blogs', 'buddypress' ), 'slug' => $bp->blogs->slug, 'position' => 30, 'screen_function' => 'bp_blogs_screen_my_blogs', 'default_subnav_slug' => 'my-blogs', 'item_css_id' => $bp->blogs->id ) );
 
 
 
148
 
149
  $blogs_link = $bp->loggedin_user->domain . $bp->blogs->slug . '/';
150
 
151
  /* Add the subnav items to the blogs nav item */
152
+ bp_core_new_subnav_item( array( 'name' => __( 'My Blogs', 'buddypress' ), 'slug' => 'my-blogs', 'parent_url' => $blogs_link, 'parent_slug' => $bp->blogs->slug, 'screen_function' => 'bp_blogs_screen_my_blogs', 'position' => 10, 'item_css_id' => 'my-blogs-list' ) );
153
+ bp_core_new_subnav_item( array( 'name' => __( 'Recent Posts', 'buddypress' ), 'slug' => 'recent-posts', 'parent_url' => $blogs_link, 'parent_slug' => $bp->blogs->slug, 'screen_function' => 'bp_blogs_screen_recent_posts', 'position' => 20 ) );
154
+ bp_core_new_subnav_item( array( 'name' => __( 'Recent Comments', 'buddypress' ), 'slug' => 'recent-comments', 'parent_url' => $blogs_link, 'parent_slug' => $bp->blogs->slug, 'screen_function' => 'bp_blogs_screen_recent_comments', 'position' => 30 ) );
155
+ bp_core_new_subnav_item( array( 'name' => __( 'Create a Blog', 'buddypress' ), 'slug' => 'create-a-blog', 'parent_url' => $blogs_link, 'parent_slug' => $bp->blogs->slug, 'screen_function' => 'bp_blogs_screen_create_a_blog', 'position' => 40 ) );
156
+
157
  /* Set up the component options navigation for Blog */
158
  if ( 'blogs' == $bp->current_component ) {
159
  if ( bp_is_home() ) {
162
  }
163
  } else {
164
  /* If we are not viewing the logged in user, set up the current users avatar and name */
165
+ $bp->bp_options_avatar = bp_core_fetch_avatar( array( 'item_id' => $bp->displayed_user->id, 'type' => 'thumb' ) );
166
  $bp->bp_options_title = $bp->displayed_user->fullname;
167
  }
168
  }
169
+
170
+ do_action( 'bp_blogs_setup_nav' );
171
  }
172
+ add_action( 'plugins_loaded', 'bp_blogs_setup_nav' );
173
+ add_action( 'admin_menu', 'bp_blogs_setup_nav' );
174
 
175
  function bp_blogs_directory_blogs_setup() {
176
  global $bp;
177
+
178
  if ( $bp->current_component == $bp->blogs->slug && empty( $bp->current_action ) ) {
179
  $bp->is_directory = true;
180
+
181
+ do_action( 'bp_blogs_directory_blogs_setup' );
182
  bp_core_load_template( apply_filters( 'bp_blogs_template_directory_blogs_setup', 'directories/blogs/index' ) );
183
  }
184
  }
185
  add_action( 'wp', 'bp_blogs_directory_blogs_setup', 2 );
186
 
187
+
188
+ /********************************************************************************
189
+ * Screen Functions
190
+ *
191
+ * Screen functions are the controllers of BuddyPress. They will execute when their
192
+ * specific URL is caught. They will first save or manipulate data using business
193
+ * functions, then pass on the user to a template file.
194
+ */
195
+
196
  function bp_blogs_screen_my_blogs() {
197
  do_action( 'bp_blogs_screen_my_blogs' );
198
  bp_core_load_template( apply_filters( 'bp_blogs_template_my_blogs', 'blogs/my-blogs' ) );
214
  }
215
 
216
 
217
+ /********************************************************************************
218
+ * Activity & Notification Functions
219
+ *
220
+ * These functions handle the recording, deleting and formatting of activity and
221
+ * notifications for the user and for this specific component.
222
+ */
223
 
224
+ function bp_blogs_register_activity_actions() {
225
  global $bp;
226
 
227
+ if ( !function_exists( 'bp_activity_set_action' ) )
228
+ return false;
 
 
229
 
230
+ bp_activity_set_action( $bp->blogs->id, 'new_blog', __( 'New blog created', 'buddypress' ) );
231
+ bp_activity_set_action( $bp->blogs->id, 'new_blog_post', __( 'New blog post published', 'buddypress' ) );
232
+ bp_activity_set_action( $bp->blogs->id, 'new_blog_comment', __( 'New blog post comment posted', 'buddypress' ) );
 
 
 
233
 
234
+ do_action( 'bp_blogs_register_activity_actions' );
 
 
 
 
235
  }
236
+ add_action( 'plugins_loaded', 'bp_blogs_register_activity_actions' );
237
 
238
+ function bp_blogs_record_activity( $args = '' ) {
 
 
 
 
 
 
239
  global $bp;
240
 
241
+ if ( !function_exists( 'bp_activity_add' ) )
242
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
 
244
+ /* Because blog, comment, and blog post code execution happens before anything else
245
+ we may need to manually instantiate the activity component globals */
246
+ if ( !$bp->activity && function_exists('bp_activity_setup_globals') )
247
+ bp_activity_setup_globals();
248
+
249
+ $defaults = array(
250
+ 'user_id' => $bp->loggedin_user->id,
251
+ 'content' => false,
252
+ 'primary_link' => false,
253
+ 'component_name' => $bp->blogs->id,
254
+ 'component_action' => false,
255
+ 'item_id' => false,
256
+ 'secondary_item_id' => false,
257
+ 'recorded_time' => time(),
258
+ 'hide_sitewide' => false
259
+ );
260
 
261
+ $r = wp_parse_args( $args, $defaults );
262
+ extract( $r, EXTR_SKIP );
263
+
264
+ return bp_activity_add( array( 'user_id' => $user_id, 'content' => $content, 'primary_link' => $primary_link, 'component_name' => $component_name, 'component_action' => $component_action, 'item_id' => $item_id, 'secondary_item_id' => $secondary_item_id, 'recorded_time' => $recorded_time, 'hide_sitewide' => $hide_sitewide ) );
265
+ }
 
 
 
 
 
 
 
266
 
267
+ function bp_blogs_delete_activity( $args = true ) {
268
+ if ( function_exists('bp_activity_delete_by_item_id') ) {
269
+ extract($args);
270
+
271
+ bp_activity_delete_by_item_id( array(
272
+ 'item_id' => $item_id,
273
+ 'component_name' => $component_name,
274
+ 'component_action' => $component_action,
275
+ 'user_id' => $user_id,
276
+ 'secondary_item_id' => $secondary_item_id
277
+ ) );
278
  }
 
 
 
 
279
  }
280
 
281
+ /********************************************************************************
282
+ * Business Functions
283
+ *
284
+ * Business functions are where all the magic happens in BuddyPress. They will
285
+ * handle the actual saving or manipulation of information. Usually they will
286
+ * hand off to a database class for data access, then return
287
+ * true or false on success or failure.
288
+ */
289
+
290
  function bp_blogs_record_existing_blogs() {
291
  global $wpdb;
292
 
308
  }
309
  }
310
 
311
+ function bp_blogs_record_blog( $blog_id, $user_id, $no_activity = false ) {
 
312
  global $bp;
313
+
314
  if ( !$user_id )
315
  $user_id = $bp->loggedin_user->id;
316
+
317
  $name = get_blog_option( $blog_id, 'blogname' );
318
  $description = get_blog_option( $blog_id, 'blogdescription' );
319
 
320
  $recorded_blog = new BP_Blogs_Blog;
321
  $recorded_blog->user_id = $user_id;
322
  $recorded_blog->blog_id = $blog_id;
323
+
324
  $recorded_blog_id = $recorded_blog->save();
325
 
326
  bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'name', $name );
327
  bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'description', $description );
328
  bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'last_activity', time() );
 
 
 
 
 
 
 
 
329
 
330
+ /* Only record this activity if the blog is public */
331
+ if ( (int)$_POST['blog_public'] && !$no_activity ) {
332
+ /* Record this in activity streams */
333
+ bp_blogs_record_activity( array(
334
+ 'user_id' => $recorded_blog->user_id,
335
+ 'content' => apply_filters( 'bp_blogs_activity_created_blog', sprintf( __( '%s created the blog %s', 'buddypress'), bp_core_get_userlink( $recorded_blog->user_id ), '<a href="' . get_blog_option( $recorded_blog->blog_id, 'siteurl' ) . '">' . attribute_escape( $name ) . '</a>' ), &$recorded_blog, $name, $description ),
336
+ 'primary_link' => apply_filters( 'bp_blogs_activity_created_blog_primary_link', get_blog_option( $recorded_blog->blog_id, 'siteurl' ), $recorded_blog->blog_id ),
337
+ 'component_action' => 'new_blog',
338
+ 'item_id' => $recorded_blog->blog_id
339
+ ) );
340
+ }
341
+
342
+ do_action( 'bp_blogs_new_blog', &$recorded_blog, $is_private, $is_recorded );
343
  }
344
  add_action( 'wpmu_new_blog', 'bp_blogs_record_blog', 10, 2 );
345
 
346
+ function bp_blogs_record_post( $post_id, $post, $user_id = false ) {
347
  global $bp, $wpdb;
348
+
349
  $post_id = (int)$post_id;
350
+ $blog_id = (int)$wpdb->blogid;
351
 
352
  if ( !$user_id )
353
  $user_id = (int)$post->post_author;
 
 
 
354
 
355
+
356
  /* This is to stop infinate loops with Donncha's sitewide tags plugin */
357
  if ( (int)get_site_option('tags_blog_id') == (int)$blog_id )
358
  return false;
359
+
360
  /* Don't record this if it's not a post */
361
  if ( $post->post_type != 'post' )
362
  return false;
373
  $recorded_post_id = $recorded_post->save();
374
 
375
  bp_blogs_update_blogmeta( $recorded_post->blog_id, 'last_activity', time() );
376
+
377
+ $post_permalink = bp_post_get_permalink( $post, $blog_id );
378
+
379
+ $activity_content = sprintf( __( '%s wrote a new blog post: %s', 'buddypress' ), bp_core_get_userlink( (int)$post->post_author ), '<a href="' . $post_permalink . '">' . $post->post_title . '</a>' );
380
+ $activity_content .= "<blockquote>" . bp_create_excerpt( $post->post_content ) . "</blockquote>";
381
+
382
+ /* Record this in activity streams */
383
+ bp_blogs_record_activity( array(
384
+ 'user_id' => (int)$post->post_author,
385
+ 'content' => apply_filters( 'bp_blogs_activity_new_post', $activity_content, &$post, $post_permalink ),
386
+ 'primary_link' => apply_filters( 'bp_blogs_activity_new_post_primary_link', $post_permalink, $post_id ),
387
+ 'component_action' => 'new_blog_post',
388
+ 'item_id' => $recorded_post_id,
389
+ 'recorded_time' => strtotime( $post->post_date )
390
+ ) );
391
  }
392
  } else {
393
  $existing_post = new BP_Blogs_Post( null, $blog_id, $post_id );
394
 
395
+ /* Delete and the activity stream item as we are probably going to re-add it later with new info. */
396
+ bp_blogs_delete_activity( array( 'item_id' => $existing_post->id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog_post' ) );
397
+
398
+ /* Delete the recorded post if the status is not published or it is password protected */
399
+ if ( 'publish' != $post->post_status || '' != $post->post_password ) {
400
+ return bp_blogs_remove_post( $post_id, $blog_id, $existing_post );
 
401
 
402
+ /* If the post author has changed, delete the post and re-add it. */
403
+ } else if ( (int)$existing_post->user_id != (int)$post->post_author ) {
404
  // Delete the existing recorded post
405
+ bp_blogs_remove_post( $post_id, $blog_id, $existing_post );
406
 
407
  // Re-record the post with the new author.
408
+ bp_blogs_record_post( $post_id );
409
  }
410
 
411
+ /* Now re-record the post in the activity streams */
412
+ $post_permalink = bp_post_get_permalink( $post, $blog_id );
413
+
414
 
415
+ $activity_content = sprintf( __( '%s wrote a new blog post: %s', 'buddypress' ), bp_core_get_userlink( (int)$post->post_author ), '<a href="' . $post_permalink . '">' . $post->post_title . '</a>' );
416
+ $activity_content .= "<blockquote>" . bp_create_excerpt( $post->post_content ) . "</blockquote>";
417
+
418
+ /* Record this in activity streams */
419
+ bp_blogs_record_activity( array(
420
+ 'user_id' => (int)$post->post_author,
421
+ 'content' => apply_filters( 'bp_blogs_activity_new_post', $activity_content, &$post, $post_permalink ),
422
+ 'primary_link' => apply_filters( 'bp_blogs_activity_new_post_primary_link', $post_permalink, $post_id ),
423
+ 'component_action' => 'new_blog_post',
424
+ 'item_id' => $existing_post->id,
425
+ 'recorded_time' => strtotime( $post->post_date )
426
+ ) );
427
  }
428
 
429
+ do_action( 'bp_blogs_new_blog_post', $existing_post, $is_private, $is_recorded );
430
  }
431
+ add_action( 'save_post', 'bp_blogs_record_post', 10, 2 );
 
 
432
 
433
  function bp_blogs_record_comment( $comment_id, $is_approved ) {
434
  global $wpdb, $bp;
437
  return false;
438
 
439
  $comment = get_comment($comment_id);
440
+ $comment->post = get_post( $comment->comment_post_ID );
441
 
442
  /* Get the user_id from the author email. */
443
  $user = get_user_by_email( $comment->comment_author_email );
456
  $recorded_commment_id = $recorded_comment->save();
457
 
458
  bp_blogs_update_blogmeta( $recorded_comment->blog_id, 'last_activity', time() );
459
+
460
+ $comment_link = bp_post_get_permalink( $comment->post, $recorded_comment->blog_id );
461
+ $activity_content = sprintf( __( '%s commented on the blog post %s', 'buddypress' ), bp_core_get_userlink( $user_id ), '<a href="' . $comment_link . '#comment-' . $comment->comment_ID . '">' . $comment->post->post_title . '</a>' );
462
+ $activity_content .= '<blockquote>' . bp_create_excerpt( $comment->comment_content ) . '</blockquote>';
463
+
464
+ /* Record this in activity streams */
465
+ bp_blogs_record_activity( array(
466
+ 'user_id' => $recorded_comment->user_id,
467
+ 'content' => apply_filters( 'bp_blogs_activity_new_comment', $activity_content, &$comment, &$recorded_comment, $comment_link ),
468
+ 'primary_link' => apply_filters( 'bp_blogs_activity_new_comment_primary_link', $comment_link, &$comment, &$recorded_comment ),
469
+ 'component_action' => 'new_blog_comment',
470
+ 'item_id' => $comment_id,
471
+ 'secondary_item_id' => $recorded_comment->blog_id,
472
+ 'recorded_time' => $recorded_comment->date_created
473
+ ) );
474
+
475
+ return $recorded_comment;
476
  }
477
  add_action( 'comment_post', 'bp_blogs_record_comment', 10, 2 );
478
 
479
+ function bp_blogs_approve_comment( $comment_id, $comment_status ) {
480
  global $bp, $wpdb;
481
+
482
+ if ( 'approve' != $comment_status )
483
+ return false;
484
 
485
  $recorded_comment = bp_blogs_record_comment( $comment_id, true );
486
+ $comment = get_comment($comment_id);
487
+ $comment->post = get_post( $comment->comment_post_ID );
488
+
489
+ bp_blogs_delete_activity( array( 'item_id' => $comment_id, 'secondary_item_id' => $recorded_comment->blog_id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog_comment' ) );
490
+
491
+ $comment_link = bp_post_get_permalink( $comment->post, $recorded_comment->blog_id );
492
+ $activity_content = sprintf( __( '%s commented on the blog post %s', 'buddypress' ), bp_core_get_userlink( $recorded_comment->user_id ), '<a href="' . $comment_link . '#comment-' . $comment->comment_ID . '">' . $comment->post->post_title . '</a>' );
493
+ $activity_content .= '<blockquote>' . bp_create_excerpt( $comment->comment_content ) . '</blockquote>';
494
 
495
+ /* Record this in activity streams */
496
+ bp_blogs_record_activity( array(
497
+ 'user_id' => $recorded_comment->user_id,
498
+ 'content' => apply_filters( 'bp_blogs_activity_new_comment', $activity_content, &$comment, &$recorded_comment, $comment_link ),
499
+ 'primary_link' => apply_filters( 'bp_blogs_activity_new_comment_primary_link', $comment_link, &$comment, &$recorded_comment ),
500
+ 'component_action' => 'new_blog_comment',
501
+ 'item_id' => $comment_id,
502
+ 'secondary_item_id' => $recorded_comment->blog_id,
503
+ 'recorded_time' => $recorded_comment->date_created
504
+ ) );
505
  }
506
+ add_action( 'wp_set_comment_status', 'bp_blogs_approve_comment', 10, 2 );
507
 
508
+ function bp_blogs_unapprove_comment( $comment_id, $comment_status ) {
509
+ if ( 'spam' == $comment_status || 'hold' == $comment_status || 'delete' == $comment_status )
510
  bp_blogs_remove_comment( $comment_id );
511
  }
 
512
  add_action( 'wp_set_comment_status', 'bp_blogs_unapprove_comment', 10, 2 );
513
 
514
  function bp_blogs_add_user_to_blog( $user_id, $role, $blog_id ) {
515
  if ( $role != 'subscriber' ) {
516
+ bp_blogs_record_blog( $blog_id, $user_id, $no_activity = true );
517
  }
518
  }
519
  add_action( 'add_user_to_blog', 'bp_blogs_add_user_to_blog', 10, 3 );
531
  BP_Blogs_Blog::delete_blog_for_all( $blog_id );
532
 
533
  // Delete activity stream item
534
+ bp_blogs_delete_activity( array( 'item_id' => $blog_id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog' ) );
535
 
536
  do_action( 'bp_blogs_remove_blog', $blog_id );
537
  }
546
  BP_Blogs_Blog::delete_blog_for_user( $blog_id, $user_id );
547
 
548
  // Delete activity stream item
549
+ bp_blogs_delete_activity( array( 'item_id' => $blog_id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog' ) );
550
 
551
  do_action( 'bp_blogs_remove_blog_for_user', $blog_id, $user_id );
552
  }
553
  add_action( 'remove_user_from_blog', 'bp_blogs_remove_blog_for_user', 10, 2 );
554
 
555
+ function bp_blogs_remove_post( $post_id, $blog_id = false, $existing_post = false ) {
556
  global $current_blog, $bp;
557
 
558
  $post_id = (int)$post_id;
 
559
 
560
+ if ( !$blog_id )
561
+ $blog_id = (int)$current_blog->blog_id;
562
+
563
+ if ( !$existing_post )
564
+ $existing_post = new BP_Blogs_Post( null, $blog_id, $post_id );
565
 
566
  // Delete post from the bp_blogs table
567
  BP_Blogs_Post::delete( $post_id, $blog_id );
568
 
569
  // Delete activity stream item
570
+ bp_blogs_delete_activity( array( 'item_id' => $existing_post->id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog_post' ) );
571
 
572
  do_action( 'bp_blogs_remove_post', $blog_id, $post_id, $post->user_id );
573
  }
580
  BP_Blogs_Comment::delete( $comment_id, $wpdb->blogid );
581
 
582
  // Delete activity stream item
583
+ bp_blogs_delete_activity( array( 'item_id' => $comment_id, 'secondary_item_id' => $recorded_comment->blog_id, 'component_name' => $bp->blogs->slug, 'component_action' => 'new_blog_comment' ) );
584
 
585
  do_action( 'bp_blogs_remove_comment', $blog_id, $comment_id, $bp->loggedin_user->id );
586
  }
595
  BP_Blogs_Comment::delete_comments_for_blog( $blog_id );
596
 
597
  // Delete activity stream item
598
+ bp_blogs_delete_activity( array( 'item_id' => $blog_id, 'component_name' => $bp->blogs->slug, 'component_action' => false ) );
599
 
600
  do_action( 'bp_blogs_remove_data_for_blog', $blog_id );
601
  }
763
  return true;
764
  }
765
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
766
  function bp_blogs_remove_data( $user_id ) {
767
  /* If this is regular blog, delete all data for that blog. */
768
  BP_Blogs_Blog::delete_blogs_for_user( $user_id );
774
  add_action( 'wpmu_delete_user', 'bp_blogs_remove_data', 1 );
775
  add_action( 'delete_user', 'bp_blogs_remove_data', 1 );
776
 
 
777
  function bp_blogs_clear_blog_object_cache( $blog_id, $user_id ) {
778
  wp_cache_delete( 'bp_blogs_of_user_' . $user_id, 'bp' );
779
  wp_cache_delete( 'bp_blogs_for_user_' . $user_id, 'bp' );
831
  add_action( 'bp_blogs_new_blog', 'bp_core_clear_cache' );
832
  add_action( 'bp_blogs_remove_data', 'bp_core_clear_cache' );
833
 
 
 
834
  ?>
bp-blogs/admin-tabs/bp-blogs-comments-tab.php CHANGED
@@ -1,3 +1,3 @@
1
  <div class="wrap">
2
- <?php require( TEMPLATEPATH . "/blogs/recent-comments.php" ); ?>
3
  </div>
1
  <div class="wrap">
2
+ <?php locate_template( array( 'blogs/recent-comments.php' ), true ); ?>
3
  </div>
bp-blogs/admin-tabs/bp-blogs-posts-tab.php CHANGED
@@ -1,3 +1,3 @@
1
  <div class="wrap">
2
- <?php require( TEMPLATEPATH . "/blogs/recent-posts.php" ); ?>
3
  </div>
1
  <div class="wrap">
2
+ <?php locate_template( array( 'blogs/recent-posts.php' ), true ); ?>
3
  </div>
bp-blogs/admin-tabs/bp-blogs-tab.php CHANGED
@@ -1,3 +1,3 @@
1
  <div class="wrap">
2
- <?php require( TEMPLATEPATH . "/blogs/my-blogs.php" ); ?>
3
  </div>
1
  <div class="wrap">
2
+ <?php locate_template( array( 'blogs/my-blogs.php' ), true ); ?>
3
  </div>
bp-blogs/bp-blogs-ajax.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
- function bp_blogs_ajax_directory_blogs() {
3
- global $bp;
4
-
5
- check_ajax_referer('directory_blogs');
6
-
7
- load_template( TEMPLATEPATH . '/directories/blogs/blogs-loop.php' );
8
- }
9
- add_action( 'wp_ajax_directory_blogs', 'bp_blogs_ajax_directory_blogs' );
10
-
11
-
12
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
bp-blogs/bp-blogs-cssjs.php DELETED
@@ -1,10 +0,0 @@
1
- <?php
2
-
3
- function bp_blogs_add_structure_css() {
4
- /* Enqueue the structure CSS file to give basic positional formatting for components */
5
- wp_enqueue_style( 'bp-blogs-structure', BP_PLUGIN_URL . '/bp-blogs/css/structure.css' );
6
- }
7
- add_action( 'bp_styles', 'bp_blogs_add_structure_css' );
8
-
9
-
10
- ?>
 
 
 
 
 
 
 
 
 
 
bp-blogs/bp-blogs-templatetags.php CHANGED
@@ -43,10 +43,11 @@ function bp_show_blog_signup_form($blogname = '', $blog_title = '', $errors = ''
43
 
44
  <p><?php _e("If you&#8217;re not going to use a great blog domain, leave it for a new user. Now have at it!", 'buddypress') ?></p>
45
 
46
- <form id="setupform" method="post" action="<?php echo $bp->loggedin_user->domain . $bp->blogs->slug . '/create-a-blog' ?>">
47
 
48
  <input type="hidden" name="stage" value="gimmeanotherblog" />
49
  <?php do_action( "signup_hidden_fields" ); ?>
 
50
  <?php bp_blogs_signup_blog($blogname, $blog_title, $errors); ?>
51
  <p>
52
  <input id="submit" type="submit" name="submit" class="submit" value="<?php _e('Create Blog &raquo;', 'buddypress') ?>" />
@@ -98,7 +99,8 @@ function bp_blogs_signup_blog( $blogname = '', $blog_title = '', $errors = '' )
98
  <p>
99
  <label for="blog_public_on"><?php _e('Privacy:', 'buddypress') ?></label>
100
  <?php _e('I would like my blog to appear in search engines like Google and Technorati, and in public listings around this site.', 'buddypress'); ?>
101
- <div class="clear"></div>
 
102
  <label class="checkbox" for="blog_public_on">
103
  <input type="radio" id="blog_public_on" name="blog_public" value="1" <?php if( !isset( $_POST['blog_public'] ) || '1' == $_POST['blog_public'] ) { ?>checked="checked"<?php } ?> />
104
  <strong><?php _e( 'Yes' , 'buddypress'); ?></strong>
@@ -306,7 +308,7 @@ function bp_has_blogs( $args = '' ) {
306
  extract( $r, EXTR_SKIP );
307
 
308
  $blogs_template = new BP_Blogs_User_Blogs_Template( $user_id, $per_page, $max );
309
- return $blogs_template->has_blogs();
310
  }
311
 
312
  function bp_blogs() {
@@ -326,7 +328,7 @@ function bp_blogs_pagination_count() {
326
  $to_num = ( $from_num + ( $blogs_template->pag_num - 1 ) > $blogs_template->total_blog_count ) ? $blogs_template->total_blog_count : $from_num + ( $blogs_template->pag_num - 1 ) ;
327
 
328
  echo sprintf( __( 'Viewing blog %d to %d (of %d blogs)', 'buddypress' ), $from_num, $to_num, $blogs_template->total_blog_count ); ?> &nbsp;
329
- <img id="ajax-loader-blogs" src="<?php echo $bp->core->image_base ?>/ajax-loader.gif" height="7" alt="<?php _e( "Loading", "buddypress" ) ?>" style="display: none;" /><?php
330
  }
331
 
332
  function bp_blogs_pagination_links() {
@@ -482,7 +484,7 @@ function bp_has_posts( $args = '' ) {
482
  extract( $r, EXTR_SKIP );
483
 
484
  $posts_template = new BP_Blogs_Blog_Post_Template( $user_id, $per_page, $max );
485
- return $posts_template->has_posts();
486
  }
487
 
488
  function bp_posts() {
@@ -502,7 +504,7 @@ function bp_post_pagination_count() {
502
  $to_num = ( $from_num + ( $posts_template->pag_num - 1 ) > $posts_template->total_post_count ) ? $posts_template->total_post_count : $from_num + ( $posts_template->pag_num - 1 ) ;
503
 
504
  echo sprintf( __( 'Viewing post %d to %d (of %d posts)', 'buddypress' ), $from_num, $to_num, $posts_template->total_post_count ); ?> &nbsp;
505
- <img id="ajax-loader-blogs" src="<?php echo $bp->core->image_base ?>/ajax-loader.gif" height="7" alt="<?php _e( "Loading", "buddypress" ) ?>" style="display: none;" /><?php
506
  }
507
 
508
  function bp_post_pagination_links() {
@@ -519,7 +521,7 @@ function bp_post_id() {
519
  }
520
  function bp_get_post_id() {
521
  global $posts_template;
522
- echo apply_filters( 'bp_get_post_id', $posts_template->post->ID );
523
  }
524
 
525
  function bp_post_title( $deprecated = true ) {
@@ -595,9 +597,9 @@ function bp_post_comment_count() {
595
 
596
  function bp_post_comments( $zero = 'No Comments', $one = '1 Comment', $more = '% Comments', $css_class = '', $none = 'Comments Off' ) {
597
  global $posts_template, $wpdb;
598
-
599
- $number = get_comments_number( $posts_template->post->ID );
600
-
601
  if ( 0 == $number && 'closed' == $posts_template->postcomment_status && 'closed' == $posts_template->postping_status ) {
602
  echo '<span' . ((!empty($css_class)) ? ' class="' . $css_class . '"' : '') . '>' . $none . '</span>';
603
  return;
@@ -626,7 +628,12 @@ function bp_post_comments( $zero = 'No Comments', $one = '1 Comment', $more = '%
626
  echo apply_filters( 'comments_popup_link_attributes', '' );
627
 
628
  echo ' title="' . sprintf( __('Comment on %s', 'buddypress'), $title ) . '">';
629
- comments_number( $zero, $one, $more, $number );
 
 
 
 
 
630
  echo '</a>';
631
  }
632
 
@@ -662,6 +669,9 @@ function bp_post_category( $separator = '', $parents = '', $post_id = false, $de
662
  function bp_post_tags( $before = '', $sep = ', ', $after = '' ) {
663
  global $posts_template, $wpdb;
664
 
 
 
 
665
  switch_to_blog( $posts_template->post->blog_id );
666
  $terms = bp_post_get_term_list( $before, $sep, $after );
667
  restore_current_blog();
@@ -788,7 +798,7 @@ function bp_post_get_term_list( $before = '', $sep = '', $after = '' ) {
788
  return false;
789
 
790
  foreach ( $terms as $term ) {
791
- $link = get_blog_option( 1, 'siteurl') . '/tag/' . $term->slug;
792
  $link = apply_filters('term_link', $link);
793
 
794
  $term_links[] = '<a href="' . $link . '" rel="tag">' . $term->name . '</a>';
@@ -917,8 +927,7 @@ function bp_has_comments( $args = '' ) {
917
  extract( $r, EXTR_SKIP );
918
 
919
  $comments_template = new BP_Blogs_Post_Comment_Template( $user_id, $per_page, $max );
920
-
921
- return $comments_template->has_comments();
922
  }
923
 
924
  function bp_comments() {
@@ -1205,7 +1214,7 @@ function bp_site_blogs_pagination_count() {
1205
  $to_num = ( $from_num + ( $site_blogs_template->pag_num - 1 ) > $site_blogs_template->total_blog_count ) ? $site_blogs_template->total_blog_count : $from_num + ( $site_blogs_template->pag_num - 1 ) ;
1206
 
1207
  echo sprintf( __( 'Viewing blog %d to %d (of %d blogs)', 'buddypress' ), $from_num, $to_num, $site_blogs_template->total_blog_count ); ?> &nbsp;
1208
- <img id="ajax-loader-blogs" src="<?php echo $bp->core->image_base ?>/ajax-loader.gif" height="7" alt="<?php _e( "Loading", "buddypress" ) ?>" style="display: none;" /><?php
1209
  }
1210
 
1211
  function bp_site_blogs_pagination_links() {
@@ -1311,8 +1320,8 @@ function bp_the_site_blog_hidden_fields() {
1311
 
1312
  function bp_directory_blogs_search_form() {
1313
  global $bp; ?>
1314
- <form action="<?php echo $bp->root_domain . '/' . blogs_SLUG . '/search/' ?>" method="post" id="search-blogs-form">
1315
- <label><input type="text" name="blogs_search" id="blogs_search" value="<?php if ( isset( $_GET['s'] ) ) { echo $_GET['s']; } else { _e( 'Search anything...', 'buddypress' ); } ?>" onfocus="if (this.value == '<?php _e( 'Search anything...', 'buddypress' ) ?>') {this.value = '';}" onblur="if (this.value == '') {this.value = '<?php _e( 'Search anything...', 'buddypress' ) ?>';}" /></label>
1316
  <input type="submit" id="blogs_search_submit" name="blogs_search_submit" value="<?php _e( 'Search', 'buddypress' ) ?>" />
1317
  </form>
1318
  <?php
43
 
44
  <p><?php _e("If you&#8217;re not going to use a great blog domain, leave it for a new user. Now have at it!", 'buddypress') ?></p>
45
 
46
+ <form class="standard-form" id="setupform" method="post" action="<?php echo $bp->loggedin_user->domain . $bp->blogs->slug . '/create-a-blog' ?>">
47
 
48
  <input type="hidden" name="stage" value="gimmeanotherblog" />
49
  <?php do_action( "signup_hidden_fields" ); ?>
50
+
51
  <?php bp_blogs_signup_blog($blogname, $blog_title, $errors); ?>
52
  <p>
53
  <input id="submit" type="submit" name="submit" class="submit" value="<?php _e('Create Blog &raquo;', 'buddypress') ?>" />
99
  <p>
100
  <label for="blog_public_on"><?php _e('Privacy:', 'buddypress') ?></label>
101
  <?php _e('I would like my blog to appear in search engines like Google and Technorati, and in public listings around this site.', 'buddypress'); ?>
102
+
103
+
104
  <label class="checkbox" for="blog_public_on">
105
  <input type="radio" id="blog_public_on" name="blog_public" value="1" <?php if( !isset( $_POST['blog_public'] ) || '1' == $_POST['blog_public'] ) { ?>checked="checked"<?php } ?> />
106
  <strong><?php _e( 'Yes' , 'buddypress'); ?></strong>
308
  extract( $r, EXTR_SKIP );
309
 
310
  $blogs_template = new BP_Blogs_User_Blogs_Template( $user_id, $per_page, $max );
311
+ return apply_filters( 'bp_has_blogs', $blogs_template->has_blogs(), &$blogs_template );
312
  }
313
 
314
  function bp_blogs() {
328
  $to_num = ( $from_num + ( $blogs_template->pag_num - 1 ) > $blogs_template->total_blog_count ) ? $blogs_template->total_blog_count : $from_num + ( $blogs_template->pag_num - 1 ) ;
329
 
330
  echo sprintf( __( 'Viewing blog %d to %d (of %d blogs)', 'buddypress' ), $from_num, $to_num, $blogs_template->total_blog_count ); ?> &nbsp;
331
+ <span class="ajax-loader"></span><?php
332
  }
333
 
334
  function bp_blogs_pagination_links() {
484
  extract( $r, EXTR_SKIP );
485
 
486
  $posts_template = new BP_Blogs_Blog_Post_Template( $user_id, $per_page, $max );
487
+ return apply_filters( 'bp_has_posts', $posts_template->has_posts(), &$posts_template );
488
  }
489
 
490
  function bp_posts() {
504
  $to_num = ( $from_num + ( $posts_template->pag_num - 1 ) > $posts_template->total_post_count ) ? $posts_template->total_post_count : $from_num + ( $posts_template->pag_num - 1 ) ;
505
 
506
  echo sprintf( __( 'Viewing post %d to %d (of %d posts)', 'buddypress' ), $from_num, $to_num, $posts_template->total_post_count ); ?> &nbsp;
507
+ <span class="ajax-loader"></span><?php
508
  }
509
 
510
  function bp_post_pagination_links() {
521
  }
522
  function bp_get_post_id() {
523
  global $posts_template;
524
+ return apply_filters( 'bp_get_post_id', $posts_template->post->ID );
525
  }
526
 
527
  function bp_post_title( $deprecated = true ) {
597
 
598
  function bp_post_comments( $zero = 'No Comments', $one = '1 Comment', $more = '% Comments', $css_class = '', $none = 'Comments Off' ) {
599
  global $posts_template, $wpdb;
600
+
601
+ $number = (int)$posts_template->post->comment_count;
602
+
603
  if ( 0 == $number && 'closed' == $posts_template->postcomment_status && 'closed' == $posts_template->postping_status ) {
604
  echo '<span' . ((!empty($css_class)) ? ' class="' . $css_class . '"' : '') . '>' . $none . '</span>';
605
  return;
628
  echo apply_filters( 'comments_popup_link_attributes', '' );
629
 
630
  echo ' title="' . sprintf( __('Comment on %s', 'buddypress'), $title ) . '">';
631
+
632
+ if ( 1 == $number )
633
+ printf( __( '%d Comment', 'buddypress' ), $number );
634
+ else
635
+ printf( __( '%d Comments', 'buddypress' ), $number );
636
+
637
  echo '</a>';
638
  }
639
 
669
  function bp_post_tags( $before = '', $sep = ', ', $after = '' ) {
670
  global $posts_template, $wpdb;
671
 
672
+ /* Disabling this for now as it's too expensive and there is no global tags directory */
673
+ return false;
674
+
675
  switch_to_blog( $posts_template->post->blog_id );
676
  $terms = bp_post_get_term_list( $before, $sep, $after );
677
  restore_current_blog();
798
  return false;
799
 
800
  foreach ( $terms as $term ) {
801
+ $link = get_blog_option( BP_ROOT_BLOG, 'siteurl') . '/tag/' . $term->slug;
802
  $link = apply_filters('term_link', $link);
803
 
804
  $term_links[] = '<a href="' . $link . '" rel="tag">' . $term->name . '</a>';
927
  extract( $r, EXTR_SKIP );
928
 
929
  $comments_template = new BP_Blogs_Post_Comment_Template( $user_id, $per_page, $max );
930
+ return apply_filters( 'bp_has_comments', $comments_template->has_comments(), &$comments_template );
 
931
  }
932
 
933
  function bp_comments() {
1214
  $to_num = ( $from_num + ( $site_blogs_template->pag_num - 1 ) > $site_blogs_template->total_blog_count ) ? $site_blogs_template->total_blog_count : $from_num + ( $site_blogs_template->pag_num - 1 ) ;
1215
 
1216
  echo sprintf( __( 'Viewing blog %d to %d (of %d blogs)', 'buddypress' ), $from_num, $to_num, $site_blogs_template->total_blog_count ); ?> &nbsp;
1217
+ <span class="ajax-loader"></span><?php
1218
  }
1219
 
1220
  function bp_site_blogs_pagination_links() {
1320
 
1321
  function bp_directory_blogs_search_form() {
1322
  global $bp; ?>
1323
+ <form action="" method="get" id="search-blogs-form">
1324
+ <label><input type="text" name="s" id="blogs_search" value="<?php if ( isset( $_GET['s'] ) ) { echo $_GET['s']; } else { _e( 'Search anything...', 'buddypress' ); } ?>" onfocus="if (this.value == '<?php _e( 'Search anything...', 'buddypress' ) ?>') {this.value = '';}" onblur="if (this.value == '') {this.value = '<?php _e( 'Search anything...', 'buddypress' ) ?>';}" /></label>
1325
  <input type="submit" id="blogs_search_submit" name="blogs_search_submit" value="<?php _e( 'Search', 'buddypress' ) ?>" />
1326
  </form>
1327
  <?php
bp-blogs/bp-blogs-widgets.php CHANGED
@@ -8,8 +8,7 @@ add_action( 'plugins_loaded', 'bp_blogs_register_widgets' );
8
 
9
  class BP_Blogs_Recent_Posts_Widget extends WP_Widget {
10
  function bp_blogs_recent_posts_widget() {
11
- parent::WP_Widget( false, $name = 'Recent Site Wide Posts' );
12
- wp_enqueue_style( 'bp-blogs-widget-posts-css', BP_PLUGIN_URL . '/bp-blogs/css/widget-blogs.css' );
13
  }
14
 
15
  function widget($args, $instance) {
@@ -22,6 +21,10 @@ class BP_Blogs_Recent_Posts_Widget extends WP_Widget {
22
  . $widget_name
23
  . $after_title; ?>
24
 
 
 
 
 
25
  <?php $posts = bp_blogs_get_latest_posts( null, $instance['max_posts'] ) ?>
26
  <?php $counter = 0; ?>
27
 
@@ -33,7 +36,7 @@ class BP_Blogs_Recent_Posts_Widget extends WP_Widget {
33
  <?php foreach ( $posts as $post ) : ?>
34
  <li>
35
  <div class="item-avatar">
36
- <a href="<?php echo bp_post_get_permalink( $post, $post->blog_id ) ?>" title="<?php echo apply_filters( 'the_title', $post->post_title ) ?>"><?php echo bp_core_get_avatar( $post->post_author, 1 ) ?></a>
37
  </div>
38
 
39
  <div class="item">
8
 
9
  class BP_Blogs_Recent_Posts_Widget extends WP_Widget {
10
  function bp_blogs_recent_posts_widget() {
11
+ parent::WP_Widget( false, $name = __( 'Recent Site Wide Posts', 'buddypress' ) );
 
12
  }
13
 
14
  function widget($args, $instance) {
21
  . $widget_name
22
  . $after_title; ?>
23
 
24
+ <?php
25
+ if ( empty( $instance['max_posts'] ) || !$instance['max_posts'] )
26
+ $instance['max_posts'] = 10; ?>
27
+
28
  <?php $posts = bp_blogs_get_latest_posts( null, $instance['max_posts'] ) ?>
29
  <?php $counter = 0; ?>
30
 
36
  <?php foreach ( $posts as $post ) : ?>
37
  <li>
38
  <div class="item-avatar">
39
+ <a href="<?php echo bp_post_get_permalink( $post, $post->blog_id ) ?>" title="<?php echo apply_filters( 'the_title', $post->post_title ) ?>"><?php echo bp_core_fetch_avatar( array( 'item_id' => $post->post_author, 'type' => 'thumb' ) ) ?></a>
40
  </div>
41
 
42
  <div class="item">
bp-blogs/css/widget-blogs.css DELETED
@@ -1,29 +0,0 @@
1
- .widget_bp_blogs_recent_posts_widget ul.item-list {
2
- margin: 15px 0 0 0;
3
- padding: 0;
4
- list-style: none;
5
- }
6
-
7
- .widget_bp_blogs_recent_posts_widget ul.item-list li {
8
- min-height: 60px;
9
- }
10
-
11
- .widget_bp_blogs_recent_posts_widget ul.item-list li .item-meta {
12
- margin-left: 10px;
13
- }
14
- .widget_bp_blogs_recent_posts_widget ul.item-list li .item h4.item-title {
15
- clear: none !important;
16
- }
17
-
18
- .widget_bp_blogs_recent_posts_widget ul.item-list li .item-avatar {
19
- float: left;
20
- margin: 0 10px 0 0;
21
- }
22
- .widget_bp_blogs_recent_posts_widget ul.item-list li .item-avatar img.avatar {
23
- width: 25px;
24
- height: 25px;
25
- }
26
-
27
- .widget_bp_blogs_recent_posts_widget ul li em {
28
- font-size: 11px;
29
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-blogs/deprecated/bp-blogs-deprecated.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /***
3
+ * Deprecated Blogs Functionality
4
+ *
5
+ * This file contains functions that are deprecated.
6
+ * You should not under any circumstance use these functions as they are
7
+ * either no longer valid, or have been replaced with something much more awesome.
8
+ *
9
+ * If you are using functions in this file you should slap the back of your head
10
+ * and then use the functions or solutions that have replaced them.
11
+ * Most functions contain a note telling you what you should be doing or using instead.
12
+ *
13
+ * Of course, things will still work if you use these functions but you will
14
+ * be the laughing stock of the BuddyPress community. We will all point and laugh at
15
+ * you. You'll also be making things harder for yourself in the long run,
16
+ * and you will miss out on lovely performance and functionality improvements.
17
+ *
18
+ * If you've checked you are not using any deprecated functions and finished your little
19
+ * dance, you can add the following line to your wp-config.php file to prevent any of
20
+ * these old functions from being loaded:
21
+ *
22
+ * define( 'BP_IGNORE_DEPRECATED', true );
23
+ */
24
+
25
+ function bp_blogs_force_buddypress_theme( $template ) {
26
+ global $bp;
27
+
28
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
29
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
30
+ return $template;
31
+
32
+ if ( $bp->current_component == $bp->blogs->slug && empty( $bp->current_action ) ) {
33
+ $member_theme = get_site_option( 'active-member-theme' );
34
+
35
+ if ( empty( $member_theme ) )
36
+ $member_theme = 'bpmember';
37
+
38
+ add_filter( 'theme_root', 'bp_core_filter_buddypress_theme_root' );
39
+ add_filter( 'theme_root_uri', 'bp_core_filter_buddypress_theme_root_uri' );
40
+
41
+ return $member_theme;
42
+ } else {
43
+ return $template;
44
+ }
45
+ }
46
+ add_filter( 'template', 'bp_blogs_force_buddypress_theme' );
47
+
48
+ function bp_blogs_force_buddypress_stylesheet( $stylesheet ) {
49
+ global $bp;
50
+
51
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
52
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
53
+ return $stylesheet;
54
+
55
+ if ( $bp->current_component == $bp->blogs->slug && empty( $bp->current_action ) ) {
56
+ $member_theme = get_site_option( 'active-member-theme' );
57
+
58
+ if ( empty( $member_theme ) )
59
+ $member_theme = 'bpmember';
60
+
61
+ add_filter( 'theme_root', 'bp_core_filter_buddypress_theme_root' );
62
+ add_filter( 'theme_root_uri', 'bp_core_filter_buddypress_theme_root_uri' );
63
+
64
+ return $member_theme;
65
+ } else {
66
+ return $stylesheet;
67
+ }
68
+ }
69
+ add_filter( 'stylesheet', 'bp_blogs_force_buddypress_stylesheet' );
70
+
71
+ function bp_blogs_add_structure_css() {
72
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
73
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
74
+ return $template;
75
+
76
+ /* Enqueue the structure CSS file to give basic positional formatting for components */
77
+ wp_enqueue_style( 'bp-blogs-structure', BP_PLUGIN_URL . '/bp-blogs/deprecated/css/structure.css' );
78
+ }
79
+ add_action( 'bp_styles', 'bp_blogs_add_structure_css' );
80
+
81
+ function bp_blogs_directory_js() {
82
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
83
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
84
+ return $template;
85
+
86
+ wp_enqueue_script( 'bp-blogs-directory-blogs', BP_PLUGIN_URL . '/bp-blogs/deprecated/js/directory-blogs.js', array( 'jquery', 'jquery-livequery-pack' ) );
87
+ }
88
+ add_action( 'bp_blogs_directory_blogs_setup', 'bp_blogs_directory_js' );
89
+
90
+ function bp_blogs_ajax_directory_blogs() {
91
+ global $bp;
92
+
93
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
94
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
95
+ return false;
96
+
97
+ check_ajax_referer('directory_blogs');
98
+
99
+ locate_template( array( 'directories/blogs/blogs-loop.php' ), true );
100
+ }
101
+ add_action( 'wp_ajax_directory_blogs', 'bp_blogs_ajax_directory_blogs' );
102
+
103
+
104
+
105
+ ?>
bp-blogs/{css → deprecated/css}/structure.css RENAMED
File without changes
bp-blogs/{js → deprecated/js}/directory-blogs.js RENAMED
File without changes
bp-core.php CHANGED
@@ -1,10 +1,15 @@
1
  <?php
 
2
  /* Define the current version number for checking if DB tables are up to date. */
3
- define( 'BP_CORE_DB_VERSION', '1300' );
4
 
5
- /* Define the path and url of the BuddyPress plugins directory */
 
 
 
 
6
  define( 'BP_PLUGIN_DIR', WP_PLUGIN_DIR . '/buddypress' );
7
- define( 'BP_PLUGIN_URL', WP_PLUGIN_URL . '/buddypress' );
8
 
9
  /* Place your custom code (actions/filters) in a file called /plugins/bp-custom.php and it will be loaded before anything else. */
10
  if ( file_exists( WP_PLUGIN_DIR . '/bp-custom.php' ) )
@@ -29,13 +34,18 @@ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-avatars.php' );
29
  require ( BP_PLUGIN_DIR . '/bp-core/bp-core-templatetags.php' );
30
  require ( BP_PLUGIN_DIR . '/bp-core/bp-core-settings.php' );
31
  require ( BP_PLUGIN_DIR . '/bp-core/bp-core-widgets.php' );
32
- require ( BP_PLUGIN_DIR . '/bp-core/bp-core-ajax.php' );
33
  require ( BP_PLUGIN_DIR . '/bp-core/bp-core-notifications.php' );
 
 
34
 
35
  /* If BP_DISABLE_ADMIN_BAR is defined, do not load the global admin bar */
36
- if ( !defined( 'BP_DISABLE_ADMIN_BAR') )
37
  require ( BP_PLUGIN_DIR . '/bp-core/bp-core-adminbar.php' );
38
 
 
 
 
 
39
  /* Define the slug for member pages and the members directory (e.g. domain.com/[members] ) */
40
  if ( !defined( 'BP_MEMBERS_SLUG' ) )
41
  define( 'BP_MEMBERS_SLUG', 'members' );
@@ -113,13 +123,13 @@ function bp_core_setup_globals() {
113
  $bp->is_single_item = false;
114
 
115
  /* The default component to use if none are set and someone visits: http://domain.com/members/andy */
116
- $bp->default_component = 'profile';
117
-
 
 
 
118
  /* Sets up the array container for the component navigation rendered by bp_get_nav() */
119
  $bp->bp_nav = array();
120
-
121
- /* Sets up the array container for the user navigation rendered by bp_get_user_nav() */
122
- $bp->bp_users_nav = array();
123
 
124
  /* Sets up the array container for the component options navigation rendered by bp_get_options_nav() */
125
  $bp->bp_options_nav = array();
@@ -130,8 +140,13 @@ function bp_core_setup_globals() {
130
  /* Sets up container used for the avatar of the current component being viewed. Rendered by bp_get_options_avatar() */
131
  $bp->bp_options_avatar = '';
132
 
133
- /* Fetches the default Gravatar image to use if the user has no avatar or gravatar */
134
- $bp->grav_default = get_site_option( 'user-avatar-default' );
 
 
 
 
 
135
 
136
  /* Fetch the full name for the logged in and current user */
137
  $bp->loggedin_user->fullname = bp_core_get_user_displayname( $bp->loggedin_user->id );
@@ -145,15 +160,16 @@ function bp_core_setup_globals() {
145
 
146
  /* Used to determine if the logged in user is a moderator for the current content. */
147
  $bp->is_item_mod = false;
148
-
149
- $bp->core->image_base = BP_PLUGIN_URL . '/bp-core/images';
150
  $bp->core->table_name_notifications = $wpdb->base_prefix . 'bp_notifications';
151
 
152
  if ( !$bp->current_component )
153
  $bp->current_component = $bp->default_component;
 
 
154
  }
155
- add_action( 'plugins_loaded', 'bp_core_setup_globals', 3 );
156
- add_action( '_admin_menu', 'bp_core_setup_globals', 3 ); // must be _admin_menu hook.
157
 
158
 
159
  /**
@@ -218,10 +234,6 @@ function bp_core_install() {
218
  /* Add names of root components to the banned blog list to avoid conflicts */
219
  bp_core_add_illegal_names();
220
 
221
- // dbDelta won't change character sets, so we need to do this seperately.
222
- // This will only be in here pre v1.0
223
- $wpdb->query( $wpdb->prepare( "ALTER TABLE {$bp->core->table_name_notifications} DEFAULT CHARACTER SET %s", $wpdb->charset ) );
224
-
225
  update_site_option( 'bp-core-db-version', BP_CORE_DB_VERSION );
226
  }
227
 
@@ -252,38 +264,6 @@ function bp_core_check_installed() {
252
  }
253
  add_action( 'admin_menu', 'bp_core_check_installed' );
254
 
255
-
256
- /**
257
- * bp_core_setup_cookies()
258
- *
259
- * Checks if there is a feedback message in the WP cookie, if so, adds a "template_notices" action
260
- * so that the message can be parsed into the template and displayed to the user.
261
- *
262
- * After the message is displayed, it removes the message vars from the cookie so that the message
263
- * is not shown to the user multiple times.
264
- *
265
- * @package BuddyPress Core
266
- * @global $bp_message The message text
267
- * @global $bp_message_type The type of message (error/success)
268
- * @uses setcookie() Sets a cookie value for the user.
269
- */
270
- function bp_core_setup_cookies() {
271
- global $bp_message, $bp_message_type;
272
-
273
- // Render any error/success feedback on the template
274
- if ( $_COOKIE['bp-message'] == '' || !isset( $_COOKIE['bp-message'] ) )
275
- return false;
276
-
277
- $bp_message = $_COOKIE['bp-message'];
278
- $bp_message_type = $_COOKIE['bp-message-type'];
279
- add_action( 'template_notices', 'bp_core_render_notice' );
280
-
281
- setcookie( 'bp-message', false, time() - 1000, COOKIEPATH );
282
- setcookie( 'bp-message-type', false, time() - 1000, COOKIEPATH );
283
- }
284
- add_action( 'init', 'bp_core_setup_cookies' );
285
-
286
-
287
  /**
288
  * bp_core_add_admin_menu()
289
  *
@@ -296,15 +276,22 @@ add_action( 'init', 'bp_core_setup_cookies' );
296
  * @uses add_submenu_page() WP function to add a submenu item
297
  */
298
  function bp_core_add_admin_menu() {
299
- global $wpdb, $bp;
300
 
301
  if ( !is_site_admin() )
302
  return false;
303
 
304
  /* Add the administration tab under the "Site Admin" tab for site administrators */
305
- add_menu_page( __("BuddyPress", 'buddypress'), __("BuddyPress", 'buddypress'), 2, 'bp-core.php', "bp_core_admin_settings" );
306
- add_submenu_page( 'bp-core.php', __("General Settings", 'buddypress'), __("General Settings", 'buddypress'), 1, 'bp-core.php', "bp_core_admin_settings" );
307
- add_submenu_page( 'bp-core.php', __("Component Setup", 'buddypress'), __("Component Setup", 'buddypress'), 2, __FILE__, "bp_core_admin_component_setup" );
 
 
 
 
 
 
 
308
  }
309
  add_action( 'admin_menu', 'bp_core_add_admin_menu' );
310
 
@@ -330,37 +317,75 @@ function bp_core_is_root_component( $component_name ) {
330
  *
331
  * @package BuddyPress Core
332
  * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
333
- * @uses bp_core_add_nav_item() Adds a navigation item to the top level buddypress navigation
334
- * @uses bp_core_add_nav_default() Sets which sub navigation item is selected by default
335
- * @uses bp_core_add_subnav_item() Adds a sub navigation item to a nav item
336
  * @uses bp_is_home() Returns true if the current user being viewed is equal the logged in user
337
- * @uses bp_core_get_avatar() Returns the either the thumb (1) or full (2) avatar URL for the user_id passed
338
  */
339
  function bp_core_setup_nav() {
340
  global $bp;
341
 
342
- if ( !function_exists('xprofile_install') ) {
 
 
 
 
 
 
 
 
343
  /* Add 'Profile' to the main navigation */
344
- bp_core_add_nav_item( __('Profile', 'buddypress'), 'profile' );
345
- bp_core_add_nav_default( 'profile', 'bp_core_catch_profile_uri', 'public' );
 
 
 
 
 
346
 
347
  $profile_link = $bp->loggedin_user->domain . '/profile/';
348
-
349
  /* Add the subnav items to the profile */
350
- bp_core_add_subnav_item( 'profile', 'public', __('Public', 'buddypress'), $profile_link, 'xprofile_screen_display_profile' );
 
 
 
 
 
 
 
351
 
352
  if ( 'profile' == $bp->current_component ) {
353
  if ( bp_is_home() ) {
354
  $bp->bp_options_title = __('My Profile', 'buddypress');
355
  } else {
356
- $bp->bp_options_avatar = bp_core_get_avatar( $bp->displayed_user->id, 1 );
357
  $bp->bp_options_title = $bp->displayed_user->fullname;
358
  }
359
  }
360
  }
361
  }
362
- add_action( 'wp', 'bp_core_setup_nav', 2 );
363
- add_action( 'admin_menu', 'bp_core_setup_nav', 2 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
 
365
  /**
366
  * bp_core_action_directory_members()
@@ -375,17 +400,121 @@ add_action( 'admin_menu', 'bp_core_setup_nav', 2 );
375
  */
376
  function bp_core_action_directory_members() {
377
  global $bp;
378
-
379
- if ( !is_home() && is_null( $bp->displayed_user->id ) && $bp->current_component == $bp->default_component ) {
380
  $bp->is_directory = true;
381
- $bp->current_component = false;
382
 
383
- wp_enqueue_script( 'bp-core-directory-members', BP_PLUGIN_URL . '/bp-core/js/directory-members.js', array( 'jquery', 'jquery-livequery-pack' ) );
384
  bp_core_load_template( apply_filters( 'bp_core_template_directory_members', 'directories/members/index' ) );
385
  }
386
  }
387
  add_action( 'wp', 'bp_core_action_directory_members', 2 );
388
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
  /**
390
  * bp_core_get_user_domain()
391
  *
@@ -404,7 +533,11 @@ function bp_core_get_user_domain( $user_id ) {
404
 
405
  $ud = get_userdata($user_id);
406
 
407
- return apply_filters( 'bp_core_get_user_domain', $bp->root_domain . '/' . BP_MEMBERS_SLUG . '/' . $ud->user_login . '/' );
 
 
 
 
408
  }
409
 
410
  /**
@@ -418,7 +551,14 @@ function bp_core_get_user_domain( $user_id ) {
418
  * @return $domain The domain URL for the blog.
419
  */
420
  function bp_core_get_root_domain() {
421
- return apply_filters( 'bp_core_get_root_domain', get_blog_option( BP_ROOT_BLOG, 'siteurl' ) );
 
 
 
 
 
 
 
422
  }
423
 
424
  /**
@@ -433,106 +573,231 @@ function bp_core_get_root_domain() {
433
  * @return The user id for the user that is currently being displayed, return zero if this is not a user home and just a normal blog.
434
  */
435
  function bp_core_get_displayed_userid( $user_login ) {
436
- return apply_filters( 'bp_core_get_displayed_userid', bp_core_get_userid_from_user_login( $user_login ) );
437
  }
438
 
439
  /**
440
- * bp_core_add_nav_item()
441
  *
442
  * Adds a navigation item to the main navigation array used in BuddyPress themes.
443
  *
444
  * @package BuddyPress Core
445
- * @param $id A unique id for the navigation item.
446
- * @param $name The display name for the navigation item, e.g. 'Profile' or 'Messages'
447
- * @param $slug The slug for the navigation item, e.g. 'profile' or 'messages'
448
- * @param $function The function to run when this sub nav item is selected.
449
- * @param $css_id The id to give the nav item in the HTML (for css highlighting)
450
- * @param $add_to_usernav Should this navigation item show up on the users home when not logged in? Or when another user views the user's page?
451
  * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
452
  */
453
- function bp_core_add_nav_item( $name, $slug, $css_id = false, $add_to_usernav = true ) {
454
  global $bp;
455
-
456
- $nav_key = count($bp->bp_nav) + 1;
457
- $user_nav_key = count($bp->bp_users_nav) + 1;
458
-
459
- if ( !$css_id )
460
- $css_id = $slug;
461
 
462
- $bp->bp_nav[$nav_key] = array(
463
- 'name' => $name,
464
- 'link' => $bp->loggedin_user->domain . $slug,
465
- 'css_id' => $css_id
 
 
 
 
 
466
  );
 
 
 
 
 
 
 
 
 
 
 
467
 
468
- if ( $add_to_usernav ) {
469
- $bp->bp_users_nav[$user_nav_key] = array(
470
- 'name' => $name,
471
- 'link' => $bp->displayed_user->domain . $slug,
472
- 'css_id' => $css_id
473
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
474
  }
475
  }
476
 
477
  /**
478
- * bp_core_remove_nav_item()
479
  *
480
- * Removes a navigation item from the navigation array used in BuddyPress themes.
481
  *
482
  * @package BuddyPress Core
483
- * @param $parent_id The id of the parent navigation item.
484
- * @param $slug The slug of the sub navigation item.
485
  */
486
- function bp_core_remove_nav_item( $name ) {
487
  global $bp;
 
 
 
 
 
 
488
 
489
- foreach( (array) $bp->bp_nav as $item_key => $item_value ) {
490
- if ( $item_value['name'] == $name ) {
491
- unset( $bp->bp_nav[$item_key] );
492
- }
 
 
 
 
 
 
 
493
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
494
 
495
- foreach( (array) $bp->bp_users_nav as $item_key => $item_value ) {
496
- if ( $item_value['name'] == $name ) {
497
- unset( $bp->bp_nav[$item_key] );
 
 
 
 
 
 
 
498
  }
499
  }
 
 
 
500
  }
 
501
 
502
  /**
503
- * bp_core_add_subnav_item()
504
  *
505
- * Adds a navigation item to the sub navigation array used in BuddyPress themes.
506
  *
507
  * @package BuddyPress Core
508
- * @param $parent_id The id of the parent navigation item.
509
  * @param $slug The slug of the sub navigation item.
510
- * @param $name The display name for the sub navigation item, e.g. 'Public' or 'Change Avatar'
511
- * @param $link The url for the sub navigation item.
512
- * @param $function The function to run when this sub nav item is selected.
513
- * @param $css_id The id to give the nav item in the HTML (for css highlighting)
514
- * @param $user_has_access Should the logged in user be able to access this page?
515
- * @param $admin_only Should this sub nav item only be visible/accessible to the site admin?
 
 
 
 
 
 
 
516
  * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
517
  */
518
- function bp_core_add_subnav_item( $parent_id, $slug, $name, $link, $function, $css_id = false, $user_has_access = true, $admin_only = false ) {
519
  global $bp;
520
 
521
- if ( $admin_only && !is_site_admin() )
522
- return false;
 
 
 
 
 
 
 
 
 
523
 
524
- if ( !$css_id )
525
- $css_id = $slug;
526
 
527
- $bp->bp_options_nav[$parent_id][$slug] = array(
 
 
 
 
 
 
 
 
 
 
 
528
  'name' => $name,
529
- 'link' => $link . $slug,
530
- 'css_id' => $css_id
 
 
 
531
  );
 
 
 
 
 
 
 
 
532
 
533
- if ( function_exists($function) && $user_has_access && $bp->current_action == $slug && $bp->current_component == $parent_id )
534
- add_action( 'wp', $function, 3 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
535
  }
 
536
 
537
  /**
538
  * bp_core_remove_subnav_item()
@@ -558,42 +823,10 @@ function bp_core_remove_subnav_item( $parent_id, $slug ) {
558
  * @param $parent_id The id of the parent navigation item.
559
  * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
560
  */
561
- function bp_core_reset_subnav_items($parent_id) {
562
  global $bp;
563
 
564
- unset($bp->bp_options_nav[$parent_id]);
565
- }
566
-
567
- /**
568
- * bp_core_add_nav_default()
569
- *
570
- * Set a default action for a nav item, when a sub nav item has not yet been selected.
571
- *
572
- * @package BuddyPress Core
573
- * @param $parent_id The id of the parent navigation item.
574
- * @param $function The function to run when this sub nav item is selected.
575
- * @param $slug The slug of the sub nav item to highlight.
576
- * @uses is_site_admin() returns true if the current user is a site admin, false if not
577
- * @uses bp_is_home() Returns true if the current user being viewed is equal the logged in user
578
- * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
579
- */
580
- function bp_core_add_nav_default( $parent_id, $function, $slug = false, $user_has_access = true, $admin_only = false ) {
581
- global $bp;
582
-
583
- if ( !$user_has_access && !bp_is_home() )
584
- return false;
585
-
586
- if ( $admin_only && !is_site_admin() )
587
- return false;
588
-
589
- if ( $bp->current_component == $parent_id && !$bp->current_action ) {
590
- if ( function_exists($function) ) {
591
- add_action( 'wp', $function, 3 );
592
- }
593
-
594
- if ( $slug )
595
- $bp->current_action = $slug;
596
- }
597
  }
598
 
599
  /**
@@ -657,11 +890,12 @@ function bp_core_add_root_component( $slug ) {
657
  function bp_core_get_random_member() {
658
  global $bp, $wpdb;
659
 
660
- if ( !$bp->current_component && isset( $_GET['random-member'] ) ) {
661
  $user = BP_Core_User::get_random_users(1);
662
 
663
  $ud = get_userdata( $user['users'][0]->user_id );
664
- bp_core_redirect( $bp->root_domain . '/' . BP_MEMBERS_SLUG . '/' . $ud->user_login );
 
665
  }
666
  }
667
  add_action( 'wp', 'bp_core_get_random_member' );
@@ -683,9 +917,6 @@ function bp_core_get_userid( $username ) {
683
  if ( !empty( $username ) )
684
  return apply_filters( 'bp_core_get_userid', $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM " . CUSTOM_USER_TABLE . " WHERE user_login = %s", $username ) ) );
685
  }
686
- function bp_core_get_userid_from_user_login( $deprecated ) {
687
- return bp_core_get_userid( $deprecated );
688
- }
689
 
690
  /**
691
  * bp_core_get_username()
@@ -730,10 +961,8 @@ function bp_core_get_userurl( $uid ) {
730
 
731
  if ( !is_numeric($uid) )
732
  return false;
733
-
734
- $ud = get_userdata($uid);
735
-
736
- return apply_filters( 'bp_core_get_userurl', $bp->root_domain . '/' . BP_MEMBERS_SLUG . '/' . $ud->user_login . '/' );
737
  }
738
 
739
  /**
@@ -827,30 +1056,35 @@ function bp_core_get_user_displayname( $user_id ) {
827
 
828
  if ( !$fullname = wp_cache_get( 'bp_user_fullname_' . $user_id, 'bp' ) ) {
829
  if ( function_exists('xprofile_install') ) {
830
- $fullname = xprofile_get_field_data( BP_XPROFILE_FULLNAME_FIELD_NAME, $user_id );
831
 
832
  if ( empty($fullname) || !$fullname ) {
833
  $ud = get_userdata($user_id);
834
 
835
- if ( empty( $ud->display_name ) )
836
- $fullname = $ud->user_nicename;
837
- else
838
  $fullname = $ud->display_name;
 
 
839
 
840
- xprofile_set_field_data( BP_XPROFILE_FULLNAME_FIELD_NAME, $user_id, $fullname );
841
  }
842
  } else {
843
  $ud = get_userdata($user_id);
844
- $fullname = $ud->display_name;
 
 
 
 
845
  }
846
-
847
  wp_cache_set( 'bp_user_fullname_' . $user_id, $fullname, 'bp' );
848
  }
849
 
850
- return apply_filters( 'bp_core_get_user_displayname', stripslashes( strip_tags( trim( $fullname ) ) ) );
851
  }
852
- /* DEPRECATED Use: bp_core_get_user_displayname */
853
- function bp_core_global_user_fullname( $user_id ) { return bp_core_get_user_displayname( $user_id ); }
 
854
 
855
 
856
  /**
@@ -869,7 +1103,6 @@ function bp_core_get_userlink_by_email( $email ) {
869
  return apply_filters( 'bp_core_get_userlink_by_email', bp_core_get_userlink( $user->ID, false, false, true ) );
870
  }
871
 
872
-
873
  /**
874
  * bp_core_get_userlink_by_username()
875
  *
@@ -887,19 +1120,43 @@ function bp_core_get_userlink_by_username( $username ) {
887
  return apply_filters( 'bp_core_get_userlink_by_username', bp_core_get_userlink( $user_id, false, false, true ) );
888
  }
889
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
890
 
891
  /**
892
- * bp_core_get_user_email()
 
 
893
  *
894
- * Returns the email address for the user based on user ID
895
- *
896
  * @package BuddyPress Core
897
- * @param $uid int User ID to check.
898
- * @uses get_userdata() WordPress function to fetch the userdata for a user ID
899
- * @return false on no match
900
- * @return str The email for the matched user.
 
 
 
 
 
 
 
901
  */
902
  function bp_core_format_time( $time, $just_date = false ) {
 
 
 
903
  $date = date( "F j, Y ", $time );
904
 
905
  if ( !$just_date ) {
@@ -918,36 +1175,76 @@ function bp_core_format_time( $time, $just_date = false ) {
918
  * @package BuddyPress Core
919
  */
920
  function bp_core_add_message( $message, $type = false ) {
 
 
921
  if ( !$type )
922
  $type = 'success';
923
-
924
- setcookie( 'bp-message', $message, time()+60*60*24, COOKIEPATH );
925
- setcookie( 'bp-message-type', $type, time()+60*60*24, COOKIEPATH );
 
 
 
 
 
 
 
 
926
  }
927
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
928
 
929
  /**
930
- * bp_core_render_notice()
931
  *
932
- * Renders a feedback notice (either error or success message) to the theme template.
933
  * The hook action 'template_notices' is used to call this function, it is not called directly.
934
  *
935
  * @package BuddyPress Core
936
  * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
937
  */
938
- function bp_core_render_notice() {
939
- if ( $_COOKIE['bp-message'] ) {
940
- $type = ( 'success' == $_COOKIE['bp-message-type'] ) ? 'updated' : 'error';
 
 
941
  ?>
942
  <div id="message" class="<?php echo $type; ?>">
943
- <p><?php echo stripslashes( $_COOKIE['bp-message'] ); ?></p>
944
  </div>
945
  <?php
946
- do_action( 'bp_core_render_notice' );
947
- }
948
  }
949
 
950
-
951
  /**
952
  * bp_core_time_since()
953
  *
@@ -976,16 +1273,18 @@ function bp_core_time_since( $older_date, $newer_date = false ) {
976
  array( 60 , __( 'minute', 'buddypress' ), __( 'minutes', 'buddypress' ) ),
977
  array( 1, __( 'second', 'buddypress' ), __( 'seconds', 'buddypress' ) )
978
  );
 
 
979
 
980
  /* $newer_date will equal false if we want to know the time elapsed between a date and the current time */
981
  /* $newer_date will have a value if we want to work out time elapsed between two known dates */
982
- $newer_date = ( !$newer_date ) ? ( time() + ( 60*60*0 ) ) : $newer_date;
983
-
984
  /* Difference in seconds */
985
  $since = $newer_date - $older_date;
986
 
987
  if ( 0 > $since )
988
- return __( '[Adjust Time Zone]', 'buddypress' );
989
 
990
  /**
991
  * We only want to output two chunks of time here, eg:
@@ -1135,69 +1434,6 @@ function bp_core_redirect( $location, $status = 302 ) {
1135
  die;
1136
  }
1137
 
1138
- /**
1139
- * bp_core_sort_nav_items()
1140
- *
1141
- * Reorder the core component navigation array items into the desired order.
1142
- * This is done this way because we cannot assume that any one component is present.
1143
- *
1144
- * @package BuddyPress Core
1145
- * @param $nav_array the navigation array variable
1146
- * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
1147
- * @uses ksort() Sort an array by key
1148
- * @return $new_nav array reordered navigation array
1149
- */
1150
- function bp_core_sort_nav_items( $nav_array ) {
1151
- global $bp;
1152
-
1153
- foreach ( (array)$nav_array as $key => $value ) {
1154
- switch ( $nav_array[$key]['css_id'] ) {
1155
- case $bp->activity->slug:
1156
- $new_nav[0] = $nav_array[$key];
1157
- unset($nav_array[$key]);
1158
- break;
1159
- case $bp->profile->slug:
1160
- $new_nav[1] = $nav_array[$key];
1161
- unset($nav_array[$key]);
1162
- break;
1163
- case 'profile': // For profiles without bp-xprofile installed
1164
- $new_nav[1] = $nav_array[$key];
1165
- unset($nav_array[$key]);
1166
- break;
1167
- case $bp->blogs->slug:
1168
- $new_nav[2] = $nav_array[$key];
1169
- unset($nav_array[$key]);
1170
- break;
1171
- case $bp->wire->slug:
1172
- $new_nav[3] = $nav_array[$key];
1173
- unset($nav_array[$key]);
1174
- break;
1175
- case $bp->messages->slug:
1176
- $new_nav[4] = $nav_array[$key];
1177
- unset($nav_array[$key]);
1178
- break;
1179
- case $bp->friends->slug:
1180
- $new_nav[5] = $nav_array[$key];
1181
- unset($nav_array[$key]);
1182
- break;
1183
- case $bp->groups->slug:
1184
- $new_nav[6] = $nav_array[$key];
1185
- unset($nav_array[$key]);
1186
- break;
1187
- }
1188
- }
1189
-
1190
- if ( is_array( $new_nav ) ) {
1191
- /* Sort the navigation array by key */
1192
- ksort($new_nav);
1193
-
1194
- /* Merge the remaining nav items, so they can be appended on the end */
1195
- $new_nav = array_merge( $new_nav, $nav_array );
1196
- }
1197
-
1198
- return apply_filters( 'bp_core_sort_nav_items', $new_nav );
1199
- }
1200
-
1201
  /**
1202
  * bp_core_referrer()
1203
  *
@@ -1212,94 +1448,6 @@ function bp_core_referrer() {
1212
  return implode( '/', $referer );
1213
  }
1214
 
1215
- /**
1216
- * bp_core_get_buddypress_themes()
1217
- *
1218
- * Gets an array of all the BuddyPress themes in the /bp-themes/ directory.
1219
- *
1220
- * @package BuddyPress Core
1221
- * @uses get_themes()
1222
- * @return An array containing all of the themes.
1223
- */
1224
- function bp_core_get_buddypress_themes() {
1225
- global $wp_themes;
1226
-
1227
- /* Remove the cached WP themes first */
1228
- $wp_existing_themes = &$wp_themes;
1229
- $wp_themes = null;
1230
-
1231
- add_filter( 'theme_root', 'bp_core_filter_buddypress_theme_root' );
1232
- $themes = get_themes();
1233
-
1234
- if ( $themes ) {
1235
- foreach ( $themes as $name => $values ) {
1236
- if ( $name == 'BuddyPress Default Home Theme' )
1237
- continue;
1238
-
1239
- $member_themes[] = array(
1240
- 'name' => $name,
1241
- 'template' => $values['Template'],
1242
- 'version' => $values['Version']
1243
- );
1244
- }
1245
- }
1246
-
1247
- /* Restore the cached WP themes */
1248
- $wp_themes = $wp_existing_themes;
1249
-
1250
- return $member_themes;
1251
- }
1252
- function bp_core_get_member_themes() { return bp_core_get_buddypress_themes(); } // DEPRECATED
1253
-
1254
-
1255
- /**
1256
- * bp_get_buddypress_theme_uri()
1257
- *
1258
- * Get the url of the selected BuddyPress theme.
1259
- *
1260
- * @package BuddyPress Core
1261
- */
1262
- function bp_get_buddypress_theme_uri() {
1263
- return apply_filters( 'bp_get_buddypress_theme_uri', WP_CONTENT_URL . '/bp-themes/' . get_site_option( 'active-member-theme' ) );
1264
- }
1265
-
1266
-
1267
- /**
1268
- * bp_get_buddypress_theme_path()
1269
- *
1270
- * Get the path of the selected BuddyPress theme.
1271
- *
1272
- * @package BuddyPress Core
1273
- */
1274
- function bp_get_buddypress_theme_path() {
1275
- return apply_filters( 'bp_get_buddypress_theme_path', WP_CONTENT_DIR . '/bp-themes/' . get_site_option( 'active-member-theme' ) );
1276
- }
1277
-
1278
-
1279
- /**
1280
- * bp_core_filter_buddypress_theme_root()
1281
- *
1282
- * Adds a filter that changes the root path of the theme directory to the bp-themes directory.
1283
- *
1284
- * @package BuddyPress Core
1285
- */
1286
- function bp_core_filter_buddypress_theme_root() {
1287
- return apply_filters( 'bp_core_filter_buddypress_theme_root', WP_CONTENT_DIR . "/bp-themes" );
1288
- }
1289
-
1290
-
1291
- /**
1292
- * bp_core_filter_buddypress_theme_root_uri()
1293
- *
1294
- * Adds a filter that changes the root URI of the theme directory to the bp-themes directory.
1295
- *
1296
- * @package BuddyPress Core
1297
- */
1298
- function bp_core_filter_buddypress_theme_root_uri() {
1299
- return apply_filters( 'bp_core_filter_buddypress_theme_root_uri', WP_CONTENT_URL . '/bp-themes' );
1300
- }
1301
-
1302
-
1303
  /**
1304
  * bp_core_add_illegal_names()
1305
  *
@@ -1331,7 +1479,6 @@ function bp_core_add_illegal_names() {
1331
  update_site_option( 'illegal_names', $new );
1332
  }
1333
 
1334
-
1335
  /**
1336
  * bp_core_email_from_name_filter()
1337
  *
@@ -1342,7 +1489,7 @@ function bp_core_add_illegal_names() {
1342
  * @return The blog name for the root blog
1343
  */
1344
  function bp_core_email_from_name_filter() {
1345
- return get_blog_option( 1, 'blogname' );
1346
  }
1347
  add_filter( 'wp_mail_from_name', 'bp_core_email_from_name_filter' );
1348
 
@@ -1374,19 +1521,24 @@ add_filter( 'wp_mail_from', 'bp_core_email_from_address_filter' );
1374
  * @uses is_site_admin() Checks to see if the user is a site administrator.
1375
  * @uses wpmu_delete_user() Deletes a user from the system.
1376
  */
1377
- function bp_core_delete_account() {
1378
  global $bp;
1379
 
1380
- // Be careful with this function!
1381
-
1382
- /* Site admins should not be allowed to delete their accounts */
1383
- if ( is_site_admin() )
 
1384
  return false;
1385
-
 
 
 
 
1386
  require_once( ABSPATH . '/wp-admin/includes/mu.php' );
1387
  require_once( ABSPATH . '/wp-admin/includes/user.php' );
1388
 
1389
- return wpmu_delete_user( $bp->loggedin_user->id );
1390
  }
1391
 
1392
 
@@ -1410,17 +1562,24 @@ function bp_core_action_search_site( $slug = false ) {
1410
  switch ( $search_which ) {
1411
  case 'members': default:
1412
  $slug = BP_MEMBERS_SLUG;
 
1413
  break;
1414
  case 'groups':
1415
  $slug = BP_GROUPS_SLUG;
 
 
 
 
 
1416
  break;
1417
  case 'blogs':
1418
  $slug = BP_BLOGS_SLUG;
 
1419
  break;
1420
  }
1421
  }
1422
-
1423
- $search_url = apply_filters( 'bp_core_search_site', site_url( $slug . '/?s=' . urlencode($search_terms) ), $search_terms );
1424
 
1425
  bp_core_redirect( $search_url );
1426
  }
@@ -1492,6 +1651,53 @@ function bp_core_print_generation_time() {
1492
  }
1493
  add_action( 'wp_footer', 'bp_core_print_generation_time' );
1494
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1495
 
1496
  /**
1497
  * bp_core_remove_data()
@@ -1511,7 +1717,7 @@ function bp_core_remove_data( $user_id ) {
1511
  }
1512
  add_action( 'wpmu_delete_user', 'bp_core_remove_data', 1 );
1513
  add_action( 'delete_user', 'bp_core_remove_data', 1 );
1514
-
1515
 
1516
  /**
1517
  * bp_load_buddypress_textdomain()
@@ -1529,6 +1735,24 @@ function bp_core_load_buddypress_textdomain() {
1529
  }
1530
  add_action ( 'plugins_loaded', 'bp_core_load_buddypress_textdomain', 9 );
1531
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1532
 
1533
  /**
1534
  * bp_core_clear_user_object_cache()
1
  <?php
2
+
3
  /* Define the current version number for checking if DB tables are up to date. */
4
+ define( 'BP_CORE_DB_VERSION', '1800' );
5
 
6
+ /***
7
+ * Define the path and url of the BuddyPress plugins directory.
8
+ * It is important to use plugins_url() core function to obtain
9
+ * the correct scheme used (http or https).
10
+ */
11
  define( 'BP_PLUGIN_DIR', WP_PLUGIN_DIR . '/buddypress' );
12
+ define( 'BP_PLUGIN_URL', plugins_url( $path = '/buddypress' ) );
13
 
14
  /* Place your custom code (actions/filters) in a file called /plugins/bp-custom.php and it will be loaded before anything else. */
15
  if ( file_exists( WP_PLUGIN_DIR . '/bp-custom.php' ) )
34
  require ( BP_PLUGIN_DIR . '/bp-core/bp-core-templatetags.php' );
35
  require ( BP_PLUGIN_DIR . '/bp-core/bp-core-settings.php' );
36
  require ( BP_PLUGIN_DIR . '/bp-core/bp-core-widgets.php' );
 
37
  require ( BP_PLUGIN_DIR . '/bp-core/bp-core-notifications.php' );
38
+ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-signup.php' );
39
+ require ( BP_PLUGIN_DIR . '/bp-core/bp-core-activation.php' );
40
 
41
  /* If BP_DISABLE_ADMIN_BAR is defined, do not load the global admin bar */
42
+ if ( !defined( 'BP_DISABLE_ADMIN_BAR' ) )
43
  require ( BP_PLUGIN_DIR . '/bp-core/bp-core-adminbar.php' );
44
 
45
+ /* If BP_IGNORE_DEPRECATED is defined, do not load any deprecated functions for backwards support */
46
+ if ( !defined( 'BP_IGNORE_DEPRECATED' ) )
47
+ require ( BP_PLUGIN_DIR . '/bp-core/deprecated/bp-core-deprecated.php' );
48
+
49
  /* Define the slug for member pages and the members directory (e.g. domain.com/[members] ) */
50
  if ( !defined( 'BP_MEMBERS_SLUG' ) )
51
  define( 'BP_MEMBERS_SLUG', 'members' );
123
  $bp->is_single_item = false;
124
 
125
  /* The default component to use if none are set and someone visits: http://domain.com/members/andy */
126
+ if ( defined( 'BP_XPROFILE_SLUG' ) )
127
+ $bp->default_component = BP_XPROFILE_SLUG;
128
+ else
129
+ $bp->default_component = 'profile';
130
+
131
  /* Sets up the array container for the component navigation rendered by bp_get_nav() */
132
  $bp->bp_nav = array();
 
 
 
133
 
134
  /* Sets up the array container for the component options navigation rendered by bp_get_options_nav() */
135
  $bp->bp_options_nav = array();
140
  /* Sets up container used for the avatar of the current component being viewed. Rendered by bp_get_options_avatar() */
141
  $bp->bp_options_avatar = '';
142
 
143
+ /* Contains an array of all the active components. The key is the slug, value the internal ID of the component */
144
+ $bp->active_components = array();
145
+
146
+ /* Fetches the default Gravatar image to use if the user/group/blog has no avatar or gravatar */
147
+ $bp->grav_default->user = apply_filters( 'bp_user_gravatar_default', get_site_option( 'user-avatar-default' ) );
148
+ $bp->grav_default->group = apply_filters( 'bp_group_gravatar_default', 'identicon' );
149
+ $bp->grav_default->blog = apply_filters( 'bp_blog_gravatar_default', 'identicon' );
150
 
151
  /* Fetch the full name for the logged in and current user */
152
  $bp->loggedin_user->fullname = bp_core_get_user_displayname( $bp->loggedin_user->id );
160
 
161
  /* Used to determine if the logged in user is a moderator for the current content. */
162
  $bp->is_item_mod = false;
163
+
 
164
  $bp->core->table_name_notifications = $wpdb->base_prefix . 'bp_notifications';
165
 
166
  if ( !$bp->current_component )
167
  $bp->current_component = $bp->default_component;
168
+
169
+ do_action( 'bp_core_setup_globals' );
170
  }
171
+ add_action( 'plugins_loaded', 'bp_core_setup_globals', 5 );
172
+ add_action( '_admin_menu', 'bp_core_setup_globals', 2 ); // must be _admin_menu hook.
173
 
174
 
175
  /**
234
  /* Add names of root components to the banned blog list to avoid conflicts */
235
  bp_core_add_illegal_names();
236
 
 
 
 
 
237
  update_site_option( 'bp-core-db-version', BP_CORE_DB_VERSION );
238
  }
239
 
264
  }
265
  add_action( 'admin_menu', 'bp_core_check_installed' );
266
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  /**
268
  * bp_core_add_admin_menu()
269
  *
276
  * @uses add_submenu_page() WP function to add a submenu item
277
  */
278
  function bp_core_add_admin_menu() {
279
+ global $wpdb, $bp, $menu;
280
 
281
  if ( !is_site_admin() )
282
  return false;
283
 
284
  /* Add the administration tab under the "Site Admin" tab for site administrators */
285
+ bp_core_add_admin_menu_page( array(
286
+ 'menu_title' => __( 'BuddyPress', 'buddypress' ),
287
+ 'page_title' => __( 'BuddyPress', 'buddypress' ),
288
+ 'access_level' => 10, 'file' => 'bp-general-settings',
289
+ 'function' => 'bp_core_admin_settings',
290
+ 'position' => 2
291
+ ) );
292
+
293
+ add_submenu_page( 'bp-general-settings', __( 'General Settings', 'buddypress'), __( 'General Settings', 'buddypress' ), 'manage_options', 'bp-general-settings', 'bp_core_admin_settings' );
294
+ add_submenu_page( 'bp-general-settings', __( 'Component Setup', 'buddypress'), __( 'Component Setup', 'buddypress' ), 'manage_options', 'bp-component-setup', 'bp_core_admin_component_setup' );
295
  }
296
  add_action( 'admin_menu', 'bp_core_add_admin_menu' );
297
 
317
  *
318
  * @package BuddyPress Core
319
  * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
320
+ * @uses bp_core_new_nav_item() Adds a navigation item to the top level buddypress navigation
321
+ * @uses bp_core_new_subnav_item() Adds a sub navigation item to a nav item
 
322
  * @uses bp_is_home() Returns true if the current user being viewed is equal the logged in user
323
+ * @uses bp_core_fetch_avatar() Returns the either the thumb or full avatar URL for the user_id passed
324
  */
325
  function bp_core_setup_nav() {
326
  global $bp;
327
 
328
+ /***
329
+ * If the extended profiles component is disabled, we need to revert to using the
330
+ * built in WordPress profile information
331
+ */
332
+ if ( !function_exists( 'xprofile_install' ) ) {
333
+ /* Fallback wire values if xprofile is disabled */
334
+ $bp->core->profile->slug = 'profile';
335
+ $bp->active_components[$bp->core->profile->slug] = $bp->core->profile->slug;
336
+
337
  /* Add 'Profile' to the main navigation */
338
+ bp_core_new_nav_item( array(
339
+ 'name' => __('Profile', 'buddypress'),
340
+ 'slug' => $bp->core->profile->slug,
341
+ 'position' => 20,
342
+ 'screen_function' => 'bp_core_catch_profile_uri',
343
+ 'default_subnav_slug' => 'public'
344
+ ) );
345
 
346
  $profile_link = $bp->loggedin_user->domain . '/profile/';
347
+
348
  /* Add the subnav items to the profile */
349
+ bp_core_new_subnav_item( array(
350
+ 'name' => __( 'Public', 'buddypress' ),
351
+ 'slug' => 'public',
352
+ 'parent_url' => $profile_link,
353
+ 'parent_slug' => $bp->core->profile->slug,
354
+ 'screen_function' => 'bp_core_catch_profile_uri'
355
+ ) );
356
+
357
 
358
  if ( 'profile' == $bp->current_component ) {
359
  if ( bp_is_home() ) {
360
  $bp->bp_options_title = __('My Profile', 'buddypress');
361
  } else {
362
+ $bp->bp_options_avatar = bp_core_fetch_avatar( array( 'item_id' => $bp->displayed_user->id, 'type' => 'thumb' ) );
363
  $bp->bp_options_title = $bp->displayed_user->fullname;
364
  }
365
  }
366
  }
367
  }
368
+ add_action( 'plugins_loaded', 'bp_core_setup_nav' );
369
+ add_action( 'admin_menu', 'bp_core_setup_nav' );
370
+
371
+
372
+ /********************************************************************************
373
+ * Screen Functions
374
+ *
375
+ * Screen functions are the controllers of BuddyPress. They will execute when their
376
+ * specific URL is caught. They will first save or manipulate data using business
377
+ * functions, then pass on the user to a template file.
378
+ */
379
+
380
+
381
+ /********************************************************************************
382
+ * Action Functions
383
+ *
384
+ * Action functions are exactly the same as screen functions, however they do not
385
+ * have a template screen associated with them. Usually they will send the user
386
+ * back to the default screen after execution.
387
+ */
388
+
389
 
390
  /**
391
  * bp_core_action_directory_members()
400
  */
401
  function bp_core_action_directory_members() {
402
  global $bp;
403
+
404
+ if ( is_null( $bp->displayed_user->id ) && $bp->current_component == BP_MEMBERS_SLUG ) {
405
  $bp->is_directory = true;
 
406
 
407
+ do_action( 'bp_core_action_directory_members' );
408
  bp_core_load_template( apply_filters( 'bp_core_template_directory_members', 'directories/members/index' ) );
409
  }
410
  }
411
  add_action( 'wp', 'bp_core_action_directory_members', 2 );
412
 
413
+ /**
414
+ * bp_core_action_set_spammer_status()
415
+ *
416
+ * When a site admin selects "Mark as Spammer/Not Spammer" from the admin menu
417
+ * this action will fire and mark or unmark the user and their blogs as spam.
418
+ * Must be a site admin for this function to run.
419
+ *
420
+ * @package BuddyPress Core
421
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
422
+ */
423
+ function bp_core_action_set_spammer_status() {
424
+ global $bp;
425
+
426
+ if ( !is_site_admin() || bp_is_home() || !$bp->displayed_user->id )
427
+ return false;
428
+
429
+ if ( 'admin' == $bp->current_component && ( 'mark-spammer' == $bp->current_action || 'unmark-spammer' == $bp->current_action ) ) {
430
+ /* Check the nonce */
431
+ check_admin_referer( 'mark-unmark-spammer' );
432
+
433
+ /* Get the functions file */
434
+ require( ABSPATH . 'wp-admin/includes/mu.php' );
435
+
436
+ if ( 'mark-spammer' == $bp->current_action )
437
+ $is_spam = 1;
438
+ else
439
+ $is_spam = 0;
440
+
441
+ /* Get the blogs for the user */
442
+ $blogs = get_blogs_of_user( $bp->displayed_user->id, true );
443
+
444
+ foreach ( (array) $blogs as $key => $details ) {
445
+ /* Do not mark the main or current root blog as spam */
446
+ if ( 1 == $details->userblog_id || BP_ROOT_BLOG == $details->userblog_id )
447
+ continue;
448
+
449
+ /* Update the blog status */
450
+ update_blog_status( $details->userblog_id, 'spam', $is_spam );
451
+
452
+ /* Fire the standard WPMU hook */
453
+ do_action( 'make_spam_blog', $details->userblog_id );
454
+ }
455
+
456
+ /* Finally, mark this user as a spammer */
457
+ update_user_status( $bp->displayed_user->id, 'spam', $is_spam, 1 );
458
+
459
+ if ( $is_spam )
460
+ bp_core_add_message( __( 'User marked as spammer. Spam users are visible only to site admins.', 'buddypress' ) );
461
+ else
462
+ bp_core_add_message( __( 'User removed as spammer.', 'buddypress' ) );
463
+
464
+ do_action( 'bp_core_action_set_spammer_status' );
465
+
466
+ bp_core_redirect( wp_get_referer() );
467
+ }
468
+ }
469
+ add_action( 'wp', 'bp_core_action_set_spammer_status', 3 );
470
+
471
+ /**
472
+ * bp_core_action_delete_user()
473
+ *
474
+ * Allows a site admin to delete a user from the adminbar menu.
475
+ *
476
+ * @package BuddyPress Core
477
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
478
+ */
479
+ function bp_core_action_delete_user() {
480
+ global $bp;
481
+
482
+ if ( !is_site_admin() || bp_is_home() || !$bp->displayed_user->id )
483
+ return false;
484
+
485
+ if ( 'admin' == $bp->current_component && 'delete-user' == $bp->current_action ) {
486
+ /* Check the nonce */
487
+ check_admin_referer( 'delete-user' );
488
+
489
+ $errors = false;
490
+
491
+ if ( bp_core_delete_account( $bp->displayed_user->id ) ) {
492
+ bp_core_add_message( sprintf( __( '%s has been deleted from the system.', 'buddypress' ), $bp->displayed_user->fullname ) );
493
+ } else {
494
+ bp_core_add_message( sprintf( __( 'There was an error deleting %s from the system. Please try again.', 'buddypress' ), $bp->displayed_user->fullname ), 'error' );
495
+ $errors = true;
496
+ }
497
+
498
+ do_action( 'bp_core_action_set_spammer_status', $errors );
499
+
500
+ if ( $errors )
501
+ bp_core_redirect( $bp->displayed_user->domain );
502
+ else
503
+ bp_core_redirect( $bp->loggedin_user->domain );
504
+ }
505
+ }
506
+ add_action( 'wp', 'bp_core_action_delete_user', 3 );
507
+
508
+
509
+ /********************************************************************************
510
+ * Business Functions
511
+ *
512
+ * Business functions are where all the magic happens in BuddyPress. They will
513
+ * handle the actual saving or manipulation of information. Usually they will
514
+ * hand off to a database class for data access, then return
515
+ * true or false on success or failure.
516
+ */
517
+
518
  /**
519
  * bp_core_get_user_domain()
520
  *
533
 
534
  $ud = get_userdata($user_id);
535
 
536
+ /* If we are using a members slug, include it. */
537
+ if ( !defined( 'BP_ENABLE_ROOT_PROFILES' ) )
538
+ return apply_filters( 'bp_core_get_user_domain', $bp->root_domain . '/' . BP_MEMBERS_SLUG . '/' . $ud->user_nicename . '/' );
539
+ else
540
+ return apply_filters( 'bp_core_get_user_domain', $bp->root_domain . '/' . $ud->user_nicename . '/' );
541
  }
542
 
543
  /**
551
  * @return $domain The domain URL for the blog.
552
  */
553
  function bp_core_get_root_domain() {
554
+ global $current_blog;
555
+
556
+ if ( defined( 'BP_ENABLE_MULTIBLOG' ) )
557
+ $domain = get_blog_option( $current_blog->blog_id, 'siteurl' );
558
+ else
559
+ $domain = get_blog_option( BP_ROOT_BLOG, 'siteurl' );
560
+
561
+ return apply_filters( 'bp_core_get_root_domain', $domain );
562
  }
563
 
564
  /**
573
  * @return The user id for the user that is currently being displayed, return zero if this is not a user home and just a normal blog.
574
  */
575
  function bp_core_get_displayed_userid( $user_login ) {
576
+ return apply_filters( 'bp_core_get_displayed_userid', bp_core_get_userid( $user_login ) );
577
  }
578
 
579
  /**
580
+ * bp_core_new_nav_item()
581
  *
582
  * Adds a navigation item to the main navigation array used in BuddyPress themes.
583
  *
584
  * @package BuddyPress Core
 
 
 
 
 
 
585
  * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
586
  */
587
+ function bp_core_new_nav_item( $args = '' ) {
588
  global $bp;
 
 
 
 
 
 
589
 
590
+ $defaults = array(
591
+ 'name' => false, // Display name for the nav item
592
+ 'slug' => false, // URL slug for the nav item
593
+ 'item_css_id' => false, // The CSS ID to apply to the HTML of the nav item
594
+ 'show_for_displayed_user' => true, // When viewing another user does this nav item show up?
595
+ 'site_admin_only' => false, // Can only site admins see this nav item?
596
+ 'position' => 99, // Index of where this nav item should be positioned
597
+ 'screen_function' => false, // The name of the function to run when clicked
598
+ 'default_subnav_slug' => false // The slug of the default subnav item to select when clicked
599
  );
600
+
601
+ $r = wp_parse_args( $args, $defaults );
602
+ extract( $r, EXTR_SKIP );
603
+
604
+ /* If we don't have the required info we need, don't create this subnav item */
605
+ if ( empty($name) || empty($slug) )
606
+ return false;
607
+
608
+ /* If this is for site admins only and the user is not one, don't create the subnav item */
609
+ if ( $site_admin_only && !is_site_admin() )
610
+ return false;
611
 
612
+ if ( empty( $item_css_id ) )
613
+ $item_css_id = $slug;
614
+
615
+ $bp->bp_nav[$slug] = array(
616
+ 'name' => $name,
617
+ 'link' => $bp->loggedin_user->domain . $slug . '/',
618
+ 'css_id' => $item_css_id,
619
+ 'show_for_displayed_user' => $show_for_displayed_user,
620
+ 'position' => $position
621
+ );
622
+
623
+ /***
624
+ * If we are not viewing a user, and this is a root component, don't attach the
625
+ * default subnav function so we can display a directory or something else.
626
+ */
627
+ if ( bp_core_is_root_component( $slug ) && !$bp->displayed_user->id )
628
+ return;
629
+
630
+ if ( $bp->current_component == $slug && !$bp->current_action ) {
631
+ if ( !is_object( $screen_function[0] ) )
632
+ add_action( 'wp', $screen_function, 3 );
633
+ else
634
+ add_action( 'wp', array( &$screen_function[0], $screen_function[1] ), 3 );
635
+
636
+ if ( $default_subnav_slug )
637
+ $bp->current_action = $default_subnav_slug;
638
  }
639
  }
640
 
641
  /**
642
+ * bp_core_new_nav_default()
643
  *
644
+ * Modify the default subnav item to load when a top level nav item is clicked.
645
  *
646
  * @package BuddyPress Core
647
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
 
648
  */
649
+ function bp_core_new_nav_default( $args = '' ) {
650
  global $bp;
651
+
652
+ $defaults = array(
653
+ 'parent_slug' => false, // Slug of the parent
654
+ 'screen_function' => false, // The name of the function to run when clicked
655
+ 'subnav_slug' => false // The slug of the subnav item to select when clicked
656
+ );
657
 
658
+ $r = wp_parse_args( $args, $defaults );
659
+ extract( $r, EXTR_SKIP );
660
+
661
+ if ( $bp->current_component == $parent_slug && !$bp->current_action ) {
662
+ if ( !is_object( $screen_function[0] ) )
663
+ add_action( 'wp', $screen_function, 3 );
664
+ else
665
+ add_action( 'wp', array( &$screen_function[0], $screen_function[1] ), 3 );
666
+
667
+ if ( $subnav_slug )
668
+ $bp->current_action = $subnav_slug;
669
  }
670
+ }
671
+
672
+ /**
673
+ * bp_core_sort_nav_items()
674
+ *
675
+ * We can only sort nav items by their position integer at a later point in time, once all
676
+ * plugins have registered their navigation items.
677
+ *
678
+ * @package BuddyPress Core
679
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
680
+ */
681
+ function bp_core_sort_nav_items() {
682
+ global $bp;
683
+
684
+ if ( empty( $bp->bp_nav ) || !is_array( $bp->bp_nav ) )
685
+ return false;
686
 
687
+ foreach ( $bp->bp_nav as $slug => $nav_item ) {
688
+ if ( empty( $temp[$nav_item['position']]) )
689
+ $temp[$nav_item['position']] = $nav_item;
690
+ else {
691
+ // increase numbers here to fit new items in.
692
+ do {
693
+ $nav_item['position']++;
694
+ } while ( !empty( $temp[$nav_item['position']] ) );
695
+
696
+ $temp[$nav_item['position']] = $nav_item;
697
  }
698
  }
699
+
700
+ ksort( $temp );
701
+ $bp->bp_nav = &$temp;
702
  }
703
+ add_action( 'wp_head', 'bp_core_sort_nav_items' );
704
 
705
  /**
706
+ * bp_core_remove_nav_item()
707
  *
708
+ * Removes a navigation item from the main navigation array.
709
  *
710
  * @package BuddyPress Core
 
711
  * @param $slug The slug of the sub navigation item.
712
+ */
713
+ function bp_core_remove_nav_item( $slug ) {
714
+ global $bp;
715
+
716
+ unset( $bp->bp_nav[$slug] );
717
+ }
718
+
719
+ /**
720
+ * bp_core_new_subnav_item()
721
+ *
722
+ * Adds a navigation item to the sub navigation array used in BuddyPress themes.
723
+ *
724
+ * @package BuddyPress Core
725
  * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
726
  */
727
+ function bp_core_new_subnav_item( $args = '' ) {
728
  global $bp;
729
 
730
+ $defaults = array(
731
+ 'name' => false, // Display name for the nav item
732
+ 'slug' => false, // URL slug for the nav item
733
+ 'parent_slug' => false, // URL slug of the parent nav item
734
+ 'parent_url' => false, // URL of the parent item
735
+ 'item_css_id' => false, // The CSS ID to apply to the HTML of the nav item
736
+ 'user_has_access' => true, // Can the logged in user see this nav item?
737
+ 'site_admin_only' => false, // Can only site admins see this nav item?
738
+ 'position' => 90, // Index of where this nav item should be positioned
739
+ 'screen_function' => false // The name of the function to run when clicked
740
+ );
741
 
742
+ $r = wp_parse_args( $args, $defaults );
743
+ extract( $r, EXTR_SKIP );
744
 
745
+ /* If we don't have the required info we need, don't create this subnav item */
746
+ if ( empty($name) || empty($slug) || empty($parent_slug) || empty($parent_url) || empty($screen_function) )
747
+ return false;
748
+
749
+ /* If this is for site admins only and the user is not one, don't create the subnav item */
750
+ if ( $site_admin_only && !is_site_admin() )
751
+ return false;
752
+
753
+ if ( empty( $item_css_id ) )
754
+ $item_css_id = $slug;
755
+
756
+ $bp->bp_options_nav[$parent_slug][$slug] = array(
757
  'name' => $name,
758
+ 'link' => $parent_url . $slug . '/',
759
+ 'slug' => $slug,
760
+ 'css_id' => $item_css_id,
761
+ 'position' => $position,
762
+ 'user_has_access' => $user_has_access
763
  );
764
+
765
+ if ( ( $bp->current_action == $slug && $bp->current_component == $parent_slug ) && $user_has_access ) {
766
+ if ( !is_object( $screen_function[0] ) )
767
+ add_action( 'wp', $screen_function, 3 );
768
+ else
769
+ add_action( 'wp', array( &$screen_function[0], $screen_function[1] ), 3 );
770
+ }
771
+ }
772
 
773
+ function bp_core_sort_subnav_items() {
774
+ global $bp;
775
+
776
+ if ( empty( $bp->bp_options_nav ) || !is_array( $bp->bp_options_nav ) )
777
+ return false;
778
+
779
+ foreach ( $bp->bp_options_nav as $parent_slug => $subnav_items ) {
780
+ if ( !is_array( $subnav_items ) )
781
+ continue;
782
+
783
+ foreach ( $subnav_items as $subnav_item ) {
784
+ if ( empty( $temp[$subnav_item['position']]) )
785
+ $temp[$subnav_item['position']] = $subnav_item;
786
+ else {
787
+ // increase numbers here to fit new items in.
788
+ do {
789
+ $subnav_item['position']++;
790
+ } while ( !empty( $temp[$subnav_item['position']] ) );
791
+
792
+ $temp[$subnav_item['position']] = $subnav_item;
793
+ }
794
+ }
795
+ ksort( $temp );
796
+ $bp->bp_options_nav[$parent_slug] = &$temp;
797
+ unset($temp);
798
+ }
799
  }
800
+ add_action( 'wp_head', 'bp_core_sort_subnav_items' );
801
 
802
  /**
803
  * bp_core_remove_subnav_item()
823
  * @param $parent_id The id of the parent navigation item.
824
  * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
825
  */
826
+ function bp_core_reset_subnav_items($parent_slug) {
827
  global $bp;
828
 
829
+ unset($bp->bp_options_nav[$parent_slug]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
830
  }
831
 
832
  /**
890
  function bp_core_get_random_member() {
891
  global $bp, $wpdb;
892
 
893
+ if ( isset( $_GET['random-member'] ) ) {
894
  $user = BP_Core_User::get_random_users(1);
895
 
896
  $ud = get_userdata( $user['users'][0]->user_id );
897
+
898
+ bp_core_redirect( bp_core_get_user_domain( $user['users'][0]->user_id ) );
899
  }
900
  }
901
  add_action( 'wp', 'bp_core_get_random_member' );
917
  if ( !empty( $username ) )
918
  return apply_filters( 'bp_core_get_userid', $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM " . CUSTOM_USER_TABLE . " WHERE user_login = %s", $username ) ) );
919
  }
 
 
 
920
 
921
  /**
922
  * bp_core_get_username()
961
 
962
  if ( !is_numeric($uid) )
963
  return false;
964
+
965
+ return apply_filters( 'bp_core_get_userurl', bp_core_get_user_domain( $uid ) );
 
 
966
  }
967
 
968
  /**
1056
 
1057
  if ( !$fullname = wp_cache_get( 'bp_user_fullname_' . $user_id, 'bp' ) ) {
1058
  if ( function_exists('xprofile_install') ) {
1059
+ $fullname = xprofile_get_field_data( 1, $user_id );
1060
 
1061
  if ( empty($fullname) || !$fullname ) {
1062
  $ud = get_userdata($user_id);
1063
 
1064
+ if ( !empty( $ud->display_name ) )
 
 
1065
  $fullname = $ud->display_name;
1066
+ else
1067
+ $fullname = $ud->user_nicename;
1068
 
1069
+ xprofile_set_field_data( 1, $user_id, $fullname );
1070
  }
1071
  } else {
1072
  $ud = get_userdata($user_id);
1073
+
1074
+ if ( !empty( $ud->display_name ) )
1075
+ $fullname = $ud->display_name;
1076
+ else
1077
+ $fullname = $ud->user_nicename;
1078
  }
1079
+
1080
  wp_cache_set( 'bp_user_fullname_' . $user_id, $fullname, 'bp' );
1081
  }
1082
 
1083
+ return apply_filters( 'bp_core_get_user_displayname', $fullname );
1084
  }
1085
+ add_filter( 'bp_core_get_user_displayname', 'strip_tags', 1 );
1086
+ add_filter( 'bp_core_get_user_displayname', 'trim' );
1087
+ add_filter( 'bp_core_get_user_displayname', 'stripslashes' );
1088
 
1089
 
1090
  /**
1103
  return apply_filters( 'bp_core_get_userlink_by_email', bp_core_get_userlink( $user->ID, false, false, true ) );
1104
  }
1105
 
 
1106
  /**
1107
  * bp_core_get_userlink_by_username()
1108
  *
1120
  return apply_filters( 'bp_core_get_userlink_by_username', bp_core_get_userlink( $user_id, false, false, true ) );
1121
  }
1122
 
1123
+ /**
1124
+ * bp_core_is_user_spammer()
1125
+ *
1126
+ * Checks if the user has been marked as a spammer.
1127
+ *
1128
+ * @package BuddyPress Core
1129
+ * @param $user_id int The id for the user.
1130
+ * @return int 1 if spammer, 0 if not.
1131
+ */
1132
+ function bp_core_is_user_spammer( $user_id ) {
1133
+ global $wpdb;
1134
+
1135
+ return apply_filters( 'bp_core_is_user_spammer', (int) $wpdb->get_var( $wpdb->prepare( "SELECT spam FROM " . CUSTOM_USER_TABLE . " WHERE ID = %d", $user_id ) ) );
1136
+ }
1137
 
1138
  /**
1139
+ * bp_core_is_user_deleted()
1140
+ *
1141
+ * Checks if the user has been marked as deleted.
1142
  *
 
 
1143
  * @package BuddyPress Core
1144
+ * @param $user_id int The id for the user.
1145
+ * @return int 1 if deleted, 0 if not.
1146
+ */
1147
+ function bp_core_is_user_deleted( $user_id ) {
1148
+ global $wpdb;
1149
+
1150
+ return apply_filters( 'bp_core_is_user_spammer', (int) $wpdb->get_var( $wpdb->prepare( "SELECT deleted FROM " . CUSTOM_USER_TABLE . " WHERE ID = %d", $user_id ) ) );
1151
+ }
1152
+
1153
+ /**
1154
+ * bp_core_format_time()
1155
  */
1156
  function bp_core_format_time( $time, $just_date = false ) {
1157
+ if ( !$time )
1158
+ return false;
1159
+
1160
  $date = date( "F j, Y ", $time );
1161
 
1162
  if ( !$just_date ) {
1175
  * @package BuddyPress Core
1176
  */
1177
  function bp_core_add_message( $message, $type = false ) {
1178
+ global $bp;
1179
+
1180
  if ( !$type )
1181
  $type = 'success';
1182
+
1183
+ /* Send the values to the cookie for page reload display */
1184
+ @setcookie( 'bp-message', $message, time()+60*60*24, COOKIEPATH );
1185
+ @setcookie( 'bp-message-type', $type, time()+60*60*24, COOKIEPATH );
1186
+
1187
+ /***
1188
+ * Send the values to the $bp global so we can still output messages
1189
+ * without a page reload
1190
+ */
1191
+ $bp->template_message = $message;
1192
+ $bp->template_message_type = $type;
1193
  }
1194
 
1195
+ /**
1196
+ * bp_core_setup_message()
1197
+ *
1198
+ * Checks if there is a feedback message in the WP cookie, if so, adds a "template_notices" action
1199
+ * so that the message can be parsed into the template and displayed to the user.
1200
+ *
1201
+ * After the message is displayed, it removes the message vars from the cookie so that the message
1202
+ * is not shown to the user multiple times.
1203
+ *
1204
+ * @package BuddyPress Core
1205
+ * @global $bp_message The message text
1206
+ * @global $bp_message_type The type of message (error/success)
1207
+ * @uses setcookie() Sets a cookie value for the user.
1208
+ */
1209
+ function bp_core_setup_message() {
1210
+ global $bp;
1211
+
1212
+ if ( empty( $bp->template_message ) )
1213
+ $bp->template_message = $_COOKIE['bp-message'];
1214
+
1215
+ if ( empty( $bp->template_message_type ) )
1216
+ $bp->template_message_type = $_COOKIE['bp-message-type'];
1217
+
1218
+ add_action( 'template_notices', 'bp_core_render_message' );
1219
+
1220
+ @setcookie( 'bp-message', false, time() - 1000, COOKIEPATH );
1221
+ @setcookie( 'bp-message-type', false, time() - 1000, COOKIEPATH );
1222
+ }
1223
+ add_action( 'wp', 'bp_core_setup_message' );
1224
 
1225
  /**
1226
+ * bp_core_render_message()
1227
  *
1228
+ * Renders a feedback message (either error or success message) to the theme template.
1229
  * The hook action 'template_notices' is used to call this function, it is not called directly.
1230
  *
1231
  * @package BuddyPress Core
1232
  * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
1233
  */
1234
+ function bp_core_render_message() {
1235
+ global $bp;
1236
+
1237
+ if ( $bp->template_message ) {
1238
+ $type = ( 'success' == $bp->template_message_type ) ? 'updated' : 'error';
1239
  ?>
1240
  <div id="message" class="<?php echo $type; ?>">
1241
+ <p><?php echo stripslashes( attribute_escape( $bp->template_message ) ); ?></p>
1242
  </div>
1243
  <?php
1244
+ do_action( 'bp_core_render_message' );
1245
+ }
1246
  }
1247
 
 
1248
  /**
1249
  * bp_core_time_since()
1250
  *
1273
  array( 60 , __( 'minute', 'buddypress' ), __( 'minutes', 'buddypress' ) ),
1274
  array( 1, __( 'second', 'buddypress' ), __( 'seconds', 'buddypress' ) )
1275
  );
1276
+
1277
+ $older_date = strtotime( gmdate( 'Y-m-d H:i:s', $older_date ) );
1278
 
1279
  /* $newer_date will equal false if we want to know the time elapsed between a date and the current time */
1280
  /* $newer_date will have a value if we want to work out time elapsed between two known dates */
1281
+ $newer_date = ( !$newer_date ) ? ( strtotime( gmdate( 'Y-m-d H:i:s' ) ) + ( 60*60*0 ) ) : $newer_date;
1282
+
1283
  /* Difference in seconds */
1284
  $since = $newer_date - $older_date;
1285
 
1286
  if ( 0 > $since )
1287
+ return __( '[Use GMT Timezone]', 'buddypress' );
1288
 
1289
  /**
1290
  * We only want to output two chunks of time here, eg:
1434
  die;
1435
  }
1436
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1437
  /**
1438
  * bp_core_referrer()
1439
  *
1448
  return implode( '/', $referer );
1449
  }
1450
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1451
  /**
1452
  * bp_core_add_illegal_names()
1453
  *
1479
  update_site_option( 'illegal_names', $new );
1480
  }
1481
 
 
1482
  /**
1483
  * bp_core_email_from_name_filter()
1484
  *
1489
  * @return The blog name for the root blog
1490
  */
1491
  function bp_core_email_from_name_filter() {
1492
+ return get_blog_option( BP_ROOT_BLOG, 'blogname' );
1493
  }
1494
  add_filter( 'wp_mail_from_name', 'bp_core_email_from_name_filter' );
1495
 
1521
  * @uses is_site_admin() Checks to see if the user is a site administrator.
1522
  * @uses wpmu_delete_user() Deletes a user from the system.
1523
  */
1524
+ function bp_core_delete_account( $user_id = false ) {
1525
  global $bp;
1526
 
1527
+ if ( !$user_id )
1528
+ $user_id = $bp->loggedin_user->id;
1529
+
1530
+ /* Make sure account deletion is not disabled */
1531
+ if ( ( !(int) get_site_option( 'bp-disable-account-deletion' ) && !is_site_admin() ) )
1532
  return false;
1533
+
1534
+ /* Site admins should not be allowed to be deleted */
1535
+ if ( is_site_admin( bp_core_get_username( $user_id ) ) )
1536
+ return false;
1537
+
1538
  require_once( ABSPATH . '/wp-admin/includes/mu.php' );
1539
  require_once( ABSPATH . '/wp-admin/includes/user.php' );
1540
 
1541
+ return wpmu_delete_user( $user_id );
1542
  }
1543
 
1544
 
1562
  switch ( $search_which ) {
1563
  case 'members': default:
1564
  $slug = BP_MEMBERS_SLUG;
1565
+ $var = '/?s=';
1566
  break;
1567
  case 'groups':
1568
  $slug = BP_GROUPS_SLUG;
1569
+ $var = '/?s=';
1570
+ break;
1571
+ case 'forums':
1572
+ $slug = BP_FORUMS_SLUG;
1573
+ $var = '/?fs=';
1574
  break;
1575
  case 'blogs':
1576
  $slug = BP_BLOGS_SLUG;
1577
+ $var = '/?s=';
1578
  break;
1579
  }
1580
  }
1581
+
1582
+ $search_url = apply_filters( 'bp_core_search_site', site_url( $slug . $var . urlencode($search_terms) ), $search_terms );
1583
 
1584
  bp_core_redirect( $search_url );
1585
  }
1651
  }
1652
  add_action( 'wp_footer', 'bp_core_print_generation_time' );
1653
 
1654
+ /**
1655
+ * bp_core_add_admin_menu_page()
1656
+ *
1657
+ * A better version of add_admin_menu_page() that allows positioning of menus.
1658
+ *
1659
+ * @package BuddyPress Core
1660
+ */
1661
+ function bp_core_add_admin_menu_page( $args = '' ) {
1662
+ global $menu, $admin_page_hooks, $_registered_pages;
1663
+
1664
+ $defaults = array(
1665
+ 'page_title' => '',
1666
+ 'menu_title' => '',
1667
+ 'access_level' => 2,
1668
+ 'file' => false,
1669
+ 'function' => false,
1670
+ 'icon_url' => false,
1671
+ 'position' => 100
1672
+ );
1673
+
1674
+ $r = wp_parse_args( $args, $defaults );
1675
+ extract( $r, EXTR_SKIP );
1676
+
1677
+ $file = plugin_basename( $file );
1678
+
1679
+ $admin_page_hooks[$file] = sanitize_title( $menu_title );
1680
+
1681
+ $hookname = get_plugin_page_hookname( $file, '' );
1682
+ if (!empty ( $function ) && !empty ( $hookname ))
1683
+ add_action( $hookname, $function );
1684
+
1685
+ if ( empty($icon_url) )
1686
+ $icon_url = 'images/generic.png';
1687
+ elseif ( is_ssl() && 0 === strpos($icon_url, 'http://') )
1688
+ $icon_url = 'https://' . substr($icon_url, 7);
1689
+
1690
+ do {
1691
+ $position++;
1692
+ } while ( !empty( $menu[$position] ) );
1693
+
1694
+ $menu[$position] = array ( $menu_title, $access_level, $file, $page_title, 'menu-top ' . $hookname, $hookname, $icon_url );
1695
+
1696
+ $_registered_pages[$hookname] = true;
1697
+
1698
+ return $hookname;
1699
+ }
1700
+
1701
 
1702
  /**
1703
  * bp_core_remove_data()
1717
  }
1718
  add_action( 'wpmu_delete_user', 'bp_core_remove_data', 1 );
1719
  add_action( 'delete_user', 'bp_core_remove_data', 1 );
1720
+ add_action( 'make_spam_user', 'bp_core_remove_data', 1 );
1721
 
1722
  /**
1723
  * bp_load_buddypress_textdomain()
1735
  }
1736
  add_action ( 'plugins_loaded', 'bp_core_load_buddypress_textdomain', 9 );
1737
 
1738
+ function bp_core_add_ajax_hook() {
1739
+ /* Theme only, we already have the wp_ajax_ hook firing in wp-admin */
1740
+ if ( !defined( 'WP_ADMIN' ) )
1741
+ do_action( 'wp_ajax_' . $_REQUEST['action'] );
1742
+ }
1743
+ add_action( 'init', 'bp_core_add_ajax_hook' );
1744
+
1745
+ /**
1746
+ * bp_core_update_message()
1747
+ *
1748
+ * Add an extra update message to the update plugin notification.
1749
+ *
1750
+ * @package BuddyPress Core
1751
+ */
1752
+ function bp_core_update_message() {
1753
+ echo '<p style="color: red; margin: 3px 0 0 0; border-top: 1px solid #ddd; padding-top: 3px">' . __( 'IMPORTANT: <a href="http://codex.buddypress.org/getting-started/upgrading-from-10x/">Read this before attempting to update BuddyPress</a>', 'buddypress' ) . '</p>';
1754
+ }
1755
+ add_action( 'in_plugin_update_message-buddypress/bp-loader.php', 'bp_core_update_message' );
1756
 
1757
  /**
1758
  * bp_core_clear_user_object_cache()
bp-core/bp-core-activation.php CHANGED
@@ -1,128 +1,106 @@
1
  <?php
2
 
3
- function bp_core_activation_set_headers() {
4
- global $wp_object_cache;
5
 
6
- define( "WP_INSTALLING", true );
7
-
8
- require_once( ABSPATH . WPINC . '/registration.php');
9
-
10
- if( is_object( $wp_object_cache ) )
11
- $wp_object_cache->cache_enabled = false;
12
 
13
- do_action("activate_header");
14
- }
15
-
16
- function bp_core_activation_do_activation() {
17
- global $current_site, $blog_id, $user_id; ?>
18
-
19
- <?php if ( empty( $_GET['key'] ) && empty( $_POST['key'] ) ) { ?>
20
-
21
- <h3><?php _e( 'Activation Key Required', 'buddypress' ) ?></h3>
22
 
23
- <p id="intro-text"><?php _e( 'This is the key contained in the email you were sent after registering for this site.', 'buddypress' ) ?></p>
24
-
25
- <div class="field-box">
26
- <form name="activateform" id="activateform" method="post" action="<?php echo 'http://' . $current_site->domain . $current_site->path ?>wp-activate.php">
27
- <p>
28
- <label for="key"><?php _e('Activation Key:', 'buddypress' ) ?></label>
29
- <br /><input type="text" name="key" id="key" value="" size="50" />
30
- </p>
31
- <p class="submit">
32
- <input id="submit" type="submit" name="Submit" class="submit" value="<?php _e('Activate &raquo;', 'buddypress' ) ?>"/>
33
- </p>
34
- </form>
35
- </div>
36
 
37
- <?php } else {
38
-
39
- $key = !empty($_GET['key']) ? $_GET['key'] : $_POST['key'];
40
- $result = wpmu_activate_signup($key);
41
-
42
- if ( is_wp_error($result) ) {
43
- if ( 'already_active' == $result->get_error_code() || 'blog_taken' == $result->get_error_code() ) {
44
- $signup = $result->get_error_data();
45
- ?>
46
-
47
- <h3><?php _e('Your account is now active!', 'buddypress' ); ?></h3>
48
-
49
- <?php
50
- _e( 'Your account has already been activated. You can now log in with the account details that were emailed to you.' );
51
-
52
- } else {
53
- ?>
54
- <h2><?php _e('An error occurred during the activation', 'buddypress' ); ?></h2>
55
- <?php
56
- echo '<p>'.$result->get_error_message().'</p>';
57
- }
58
- } else {
59
- extract($result);
60
-
61
- $user = new WP_User( (int) $user_id);
62
-
63
- ?>
64
 
65
- <h3><?php _e('Your account is now active!', 'buddypress' ); ?></h3>
 
66
 
67
- <p class="view"><?php printf( __( 'Your account is now activated. <a href="%1$s">Login</a> or go back to the <a href="%2$s">homepage</a>.', 'buddypress' ), site_url( 'wp-login.php?redirect_to=' . site_url() ), site_url() ); ?></p>
 
 
 
 
 
 
68
 
69
- <div class="field-box" id="signup-welcome">
70
- <p><span class="label"><?php _e( 'Username:', 'buddypress' ); ?></span> <?php echo $user->user_login ?></p>
71
- <p><span class="label"><?php _e( 'Password:', 'buddypress' ); ?></span> <?php echo $password; ?></p>
72
- </div>
 
 
 
 
 
 
 
 
 
73
 
74
- <?php
75
- do_action( 'bp_activation_extras', $user_id, $meta );
 
 
 
 
 
76
  }
 
 
 
 
 
77
  }
 
 
78
  }
 
79
 
80
- // Notify user of signup success.
81
- function bp_core_activation_signup_blog_notification( $domain, $path, $title, $user, $user_email, $key, $meta ) {
82
- global $current_site;
83
 
84
- // Send email with activation link.
85
- if ( 'no' == constant( "VHOST" ) ) {
86
- $activate_url = bp_activation_page( false ) . "?key=$key";
87
- } else {
88
- $activate_url = bp_activation_page( false ) ."?key=$key";
89
- }
 
 
 
 
 
90
 
91
- $activate_url = clean_url($activate_url);
92
- $admin_email = get_site_option( "admin_email" );
93
-
94
- if ( empty( $admin_email ) )
95
- $admin_email = 'support@' . $_SERVER['SERVER_NAME'];
96
-
97
- $from_name = ( '' == get_site_option( "site_name" ) ) ? 'WordPress' : wp_specialchars( get_site_option( "site_name" ) );
98
- $message_headers = "MIME-Version: 1.0\n" . "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
99
- $message = sprintf(__("To activate your blog, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login.\n\nAfter you activate, you can visit your blog here:\n\n%s", 'buddypress' ), $activate_url, clean_url("http://{$domain}{$path}" ) );
100
- $subject = '[' . $from_name . '] ' . sprintf(__('Activate %s', 'buddypress' ), clean_url('http://' . $domain . $path));
101
-
102
- wp_mail($user_email, $subject, $message, $message_headers);
103
-
104
- // Return false to stop the original WPMU function from continuing
105
  return false;
106
  }
107
- add_filter( 'wpmu_signup_blog_notification', 'bp_core_activation_signup_blog_notification', 1, 7 );
108
-
109
- function bp_core_activation_signup_user_notification( $user, $user_email, $key, $meta ) {
110
- global $current_site;
111
 
112
- // Send email with activation link.
113
- $admin_email = get_site_option( "admin_email" );
114
-
115
- if ( empty( $admin_email ) )
116
- $admin_email = 'support@' . $_SERVER['SERVER_NAME'];
117
-
118
- $from_name = ( '' == get_site_option( "site_name" ) ) ? 'WordPress' : wp_specialchars( get_site_option( "site_name" ) );
119
- $message_headers = "MIME-Version: 1.0\n" . "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
120
- $message = apply_filters( 'wpmu_signup_user_notification_email', sprintf( __( "To activate your user, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login.\n\n", 'buddypress' ), clean_url( bp_activation_page( false ) . "?key=$key" ) ) );
121
- $subject = apply_filters( 'wpmu_signup_user_notification_subject', sprintf( __( 'Activate %s', 'buddypress' ), $user ) );
122
 
123
- wp_mail( $user_email, $subject, $message, $message_headers );
124
-
125
- // Return false to stop the original WPMU function from continuing
126
- return false;
127
  }
128
- add_filter( 'wpmu_signup_user_notification', 'bp_core_activation_signup_user_notification', 1, 4 );
 
 
 
1
  <?php
2
 
3
+ function bp_core_screen_activation() {
4
+ global $bp, $wpdb;
5
 
6
+ if ( BP_ACTIVATION_SLUG != $bp->current_component )
7
+ return false;
 
 
 
 
8
 
9
+ /* Check if an activation key has been passed */
10
+ if ( isset( $_GET['key'] ) ) {
 
 
 
 
 
 
 
11
 
12
+ require_once( ABSPATH . WPINC . '/registration.php' );
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
+ /* Activate the signup */
15
+ $signup = apply_filters( 'bp_core_activate_account', wpmu_activate_signup( $_GET['key'] ) );
16
+
17
+ /* If there was errors, add a message and redirect */
18
+ if ( $signup->errors ) {
19
+ bp_core_add_message( __( 'There was an error activating your account, please try again.', 'buddypress' ), 'error' );
20
+ bp_core_redirect( $bp->root_domain . '/' . BP_ACTIVATION_SLUG );
21
+ }
22
+
23
+ /* Set the password */
24
+ if ( !empty( $signup['meta']['password'] ) )
25
+ $wpdb->update( $wpdb->users, array( 'user_pass' => $signup['meta']['password'] ), array( 'ID' => $signup['user_id'] ), array( '%s' ), array( '%d' ) );
26
+
27
+ /* Set any profile data */
28
+ if ( function_exists( 'xprofile_set_field_data' ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
+ if ( !empty( $signup['meta']['profile_field_ids'] ) ) {
31
+ $profile_field_ids = explode( ',', $signup['meta']['profile_field_ids'] );
32
 
33
+ foreach( $profile_field_ids as $field_id ) {
34
+ $current_field = $signup['meta']["field_{$field_id}"];
35
+
36
+ if ( !empty( $current_field ) )
37
+ xprofile_set_field_data( $field_id, $signup['user_id'], $current_field );
38
+ }
39
+ }
40
 
41
+ }
42
+
43
+ /* Check for an uploaded avatar and move that to the correct user folder */
44
+ $hashed_key = wp_hash( $_GET['key'] );
45
+
46
+ /* Check if the avatar folder exists. If it does, move rename it, move it and delete the signup avatar dir */
47
+ if ( file_exists( WP_CONTENT_DIR . '/blogs.dir/' . BP_ROOT_BLOG . '/files/avatars/signups/' . $hashed_key ) ) {
48
+ @rename( WP_CONTENT_DIR . '/blogs.dir/' . BP_ROOT_BLOG . '/files/avatars/signups/' . $hashed_key, WP_CONTENT_DIR . '/blogs.dir/' . BP_ROOT_BLOG . '/files/avatars/' . $signup['user_id'] );
49
+ }
50
+
51
+ /* Record the new user in the activity streams */
52
+ if ( function_exists( 'bp_activity_add' ) ) {
53
+ $userlink = bp_core_get_userlink( $signup['user_id'] );
54
 
55
+ bp_activity_add( array(
56
+ 'user_id' => $signup['user_id'],
57
+ 'content' => apply_filters( 'bp_core_activity_registered_member', sprintf( __( '%s became a registered member', 'buddypress' ), $userlink ), $signup['user_id'] ),
58
+ 'primary_link' => apply_filters( 'bp_core_actiivty_registered_member_primary_link', $userlink ),
59
+ 'component_name' => 'profile',
60
+ 'component_action' => 'new_member'
61
+ ) );
62
  }
63
+
64
+ do_action( 'bp_core_account_activated', &$signup, $_GET['key'] );
65
+ bp_core_add_message( __( 'Your account is now active!', 'buddypress' ) );
66
+
67
+ $bp->activation_complete = true;
68
  }
69
+
70
+ bp_core_load_template( 'registration/activate' );
71
  }
72
+ add_action( 'wp', 'bp_core_screen_activation', 3 );
73
 
 
 
 
74
 
75
+ /***
76
+ * bp_core_disable_welcome_email()
77
+ *
78
+ * Since the user now chooses their password, sending it over clear-text to an
79
+ * email address is no longer necessary. It's also a terrible idea security wise.
80
+ *
81
+ * This will only disable the email if a custom registration template is being used.
82
+ */
83
+ function bp_core_disable_welcome_email() {
84
+ if ( '' == locate_template( array( 'registration/register.php' ), false ) && '' == locate_template( array( 'register.php' ), false ) )
85
+ return true;
86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  return false;
88
  }
89
+ add_filter( 'wpmu_welcome_user_notification', 'bp_core_disable_welcome_email' );
 
 
 
90
 
91
+ /***
92
+ * bp_core_filter_activation_email()
93
+ *
94
+ * Filter the activation email to remove the line stating that another email will be sent
95
+ * with the generated login details. This is not the case due to bp_core_disable_welcome_email()
96
+ */
97
+ function bp_core_filter_activation_email( $email ) {
98
+ if ( '' == locate_template( array( 'registration/register.php' ), false ) && '' == locate_template( array( 'register.php' ), false ) )
99
+ return $email;
 
100
 
101
+ return str_replace( __( 'After you activate, you will receive *another email* with your login.', 'buddypress' ), '', $email );
 
 
 
102
  }
103
+ add_filter( 'wpmu_signup_user_notification_email', 'bp_core_filter_activation_email' );
104
+ add_filter( 'wpmu_signup_blog_notification_email', 'bp_core_filter_activation_email' );
105
+
106
+ ?>
bp-core/bp-core-admin.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  function bp_core_admin_settings() {
4
- global $wpdb, $bp;
5
  ?>
6
 
7
  <?php
@@ -84,7 +84,25 @@ function bp_core_admin_settings() {
84
  <input type="radio" name="bp-admin[non-friend-wire-posting]"<?php if ( !(int)get_site_option( 'non-friend-wire-posting' ) ) : ?> checked="checked"<?php endif; ?> id="bp-admin-non-friend-wire-post" value="0" /> <?php _e( 'No', 'buddypress' ) ?>
85
  </td>
86
  </tr>
87
- <?php } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  <tr>
89
  <th scope="row"><?php _e('Select theme to use for BuddyPress generated pages', 'buddypress' ) ?>:</th>
90
  <td>
@@ -110,6 +128,7 @@ function bp_core_admin_settings() {
110
  <?php endif; ?>
111
  </td>
112
  </tr>
 
113
  <tr>
114
  <th scope="row"><?php _e( 'Default User Avatar', 'buddypress' ) ?></th>
115
  <td>
@@ -256,6 +275,15 @@ function bp_core_admin_component_setup() {
256
  </td>
257
  </tr>
258
  <?php endif; ?>
 
 
 
 
 
 
 
 
 
259
  </tbody>
260
  </table>
261
 
1
  <?php
2
 
3
  function bp_core_admin_settings() {
4
+ global $wpdb, $bp, $current_blog;
5
  ?>
6
 
7
  <?php
84
  <input type="radio" name="bp-admin[non-friend-wire-posting]"<?php if ( !(int)get_site_option( 'non-friend-wire-posting' ) ) : ?> checked="checked"<?php endif; ?> id="bp-admin-non-friend-wire-post" value="0" /> <?php _e( 'No', 'buddypress' ) ?>
85
  </td>
86
  </tr>
87
+ <?php } ?>
88
+ <tr>
89
+ <th scope="row"><?php _e( 'Disable user account deletion?', 'buddypress' ) ?>:</th>
90
+ <td>
91
+ <input type="radio" name="bp-admin[bp-disable-account-deletion]"<?php if ( (int)get_site_option( 'bp-disable-account-deletion' ) ) : ?> checked="checked"<?php endif; ?> id="bp-disable-account-deletion" value="1" /> <?php _e( 'Yes', 'buddypress' ) ?> &nbsp;
92
+ <input type="radio" name="bp-admin[bp-disable-account-deletion]"<?php if ( !(int)get_site_option( 'bp-disable-account-deletion' ) || '' == get_site_option( 'bp-disable-account-deletion' ) ) : ?> checked="checked"<?php endif; ?> id="bp-disable-account-deletion" value="0" /> <?php _e( 'No', 'buddypress' ) ?>
93
+ </td>
94
+ </tr>
95
+ <?php if ( function_exists( 'bp_forums_setup') ) : ?>
96
+ <tr>
97
+ <th scope="row"><?php _e( 'Disable global forum directory?', 'buddypress' ) ?>:</th>
98
+ <td>
99
+ <input type="radio" name="bp-admin[bp-disable-forum-directory]"<?php if ( (int)get_site_option( 'bp-disable-forum-directory' ) ) : ?> checked="checked"<?php endif; ?> id="bp-disable-forum-directory" value="1" /> <?php _e( 'Yes', 'buddypress' ) ?> &nbsp;
100
+ <input type="radio" name="bp-admin[bp-disable-forum-directory]"<?php if ( !(int)get_site_option( 'bp-disable-forum-directory' ) || '' == get_site_option( 'bp-disable-forum-directory' ) ) : ?> checked="checked"<?php endif; ?> id="bp-disable-forum-directory" value="0" /> <?php _e( 'No', 'buddypress' ) ?>
101
+ </td>
102
+ </tr>
103
+ <?php endif; ?>
104
+
105
+ <?php if ( '' == locate_template( array( 'registration/register.php' ), false ) && $current_blog->blog_id == BP_ROOT_BLOG ) : ?>
106
  <tr>
107
  <th scope="row"><?php _e('Select theme to use for BuddyPress generated pages', 'buddypress' ) ?>:</th>
108
  <td>
128
  <?php endif; ?>
129
  </td>
130
  </tr>
131
+ <?php endif; ?>
132
  <tr>
133
  <th scope="row"><?php _e( 'Default User Avatar', 'buddypress' ) ?></th>
134
  <td>
275
  </td>
276
  </tr>
277
  <?php endif; ?>
278
+ <?php if ( file_exists( BP_PLUGIN_DIR . '/bp-status.php') ) : ?>
279
+ <tr>
280
+ <td><h3><?php _e( 'Status Updates', 'buddypress' ) ?></h3><p><?php _e( 'Allow users to post status updates.', 'buddypress' ) ?></p></td>
281
+ <td width="45%">
282
+ <input type="radio" name="bp_components[bp-status.php]" value="1"<?php if ( !isset( $disabled_components['bp-status.php'] ) ) : ?> checked="checked" <?php endif; ?>/> <?php _e( 'Enabled', 'buddypress' ) ?> &nbsp;
283
+ <input type="radio" name="bp_components[bp-status.php]" value="0"<?php if ( isset( $disabled_components['bp-status.php'] ) ) : ?> checked="checked" <?php endif; ?>/> <?php _e( 'Disabled', 'buddypress' ) ?>
284
+ </td>
285
+ </tr>
286
+ <?php endif; ?>
287
  </tbody>
288
  </table>
289
 
bp-core/bp-core-adminbar.php CHANGED
@@ -3,6 +3,9 @@
3
  function bp_core_admin_bar() {
4
  global $bp, $wpdb, $current_blog, $doing_admin_bar;
5
 
 
 
 
6
  $doing_admin_bar = true;
7
 
8
  if ( (int)get_site_option( 'hide-loggedout-adminbar' ) && !is_user_logged_in() )
@@ -26,7 +29,7 @@ function bp_core_admin_bar() {
26
  function bp_adminbar_logo() {
27
  global $bp;
28
 
29
- echo '<a href="' . $bp->root_domain . '"><img id="admin-bar-logo" src="' . apply_filters( 'bp_admin_bar_logo_src', BP_PLUGIN_URL . '/bp-core/images/admin_bar_logo.gif' ) . '" alt="' . apply_filters( 'bp_admin_bar_logo_alt_text', __( 'BuddyPress', 'buddypress' ) ) . '" /></a>';
30
  }
31
 
32
  // **** "Log In" and "Sign Up" links (Visible when not logged in) ********
@@ -36,8 +39,8 @@ function bp_adminbar_login_menu() {
36
  if ( !is_user_logged_in() ) {
37
  echo '<li class="bp-login no-arrow"><a href="' . $bp->root_domain . '/wp-login.php?redirect_to=' . urlencode( $bp->root_domain ) . '">' . __( 'Log In', 'buddypress' ) . '</a></li>';
38
 
39
- // Show "Sign Up" link if registrations are allowed
40
- if ( get_site_option( 'registration' ) != 'none' ) {
41
  echo '<li class="bp-signup no-arrow"><a href="' . bp_signup_page(false) . '">' . __( 'Sign Up', 'buddypress' ) . '</a></li>';
42
  }
43
  }
@@ -50,12 +53,9 @@ function bp_adminbar_account_menu() {
50
  if ( !$bp->bp_nav )
51
  return false;
52
 
53
- /* Sort the nav by key as the array has been put together in different locations */
54
- $bp->bp_nav = bp_core_sort_nav_items( $bp->bp_nav );
55
-
56
  if ( is_user_logged_in() ) {
57
 
58
- echo '<li id="bp-adminbar-account-menu"><a href="">';
59
 
60
  echo __( 'My Account', 'buddypress' ) . '</a>';
61
  echo '<ul>';
@@ -67,10 +67,11 @@ function bp_adminbar_account_menu() {
67
 
68
  echo '<li' . $alt . '>';
69
  echo '<a id="bp-admin-' . $nav_item['css_id'] . '" href="' . $nav_item['link'] . '">' . $nav_item['name'] . '</a>';
70
-
71
  if ( is_array( $bp->bp_options_nav[$nav_item['css_id']] ) ) {
72
  echo '<ul>';
73
  $sub_counter = 0;
 
74
  foreach( $bp->bp_options_nav[$nav_item['css_id']] as $subnav_item ) {
75
  $alt = ( 0 == $sub_counter % 2 ) ? ' class="alt"' : '';
76
  echo '<li' . $alt . '><a id="bp-admin-' . $subnav_item['css_id'] . '" href="' . $subnav_item['link'] . '">' . $subnav_item['name'] . '</a></li>';
@@ -167,11 +168,13 @@ function bp_adminbar_blogs_menu() {
167
  }
168
 
169
  $alt = ( 0 == $counter % 2 ) ? ' class="alt"' : '';
170
-
171
- echo '<li' . $alt . '>';
172
- echo '<a href="' . $bp->loggedin_user->domain . $bp->blogs->slug . '/create-a-blog">' . __('Create a Blog!', 'buddypress') . '</a>';
173
- echo '</li>';
174
-
 
 
175
  echo '</ul>';
176
  echo '</li>';
177
  }
3
  function bp_core_admin_bar() {
4
  global $bp, $wpdb, $current_blog, $doing_admin_bar;
5
 
6
+ if ( defined( 'BP_DISABLE_ADMIN_BAR' ) )
7
+ return false;
8
+
9
  $doing_admin_bar = true;
10
 
11
  if ( (int)get_site_option( 'hide-loggedout-adminbar' ) && !is_user_logged_in() )
29
  function bp_adminbar_logo() {
30
  global $bp;
31
 
32
+ echo '<a href="' . $bp->root_domain . '" id="admin-bar-logo">' . get_blog_option( BP_ROOT_BLOG, 'blogname') . '</a>';
33
  }
34
 
35
  // **** "Log In" and "Sign Up" links (Visible when not logged in) ********
39
  if ( !is_user_logged_in() ) {
40
  echo '<li class="bp-login no-arrow"><a href="' . $bp->root_domain . '/wp-login.php?redirect_to=' . urlencode( $bp->root_domain ) . '">' . __( 'Log In', 'buddypress' ) . '</a></li>';
41
 
42
+ // Show "Sign Up" link if user registrations are allowed
43
+ if ( get_site_option( 'registration' ) != 'none' && get_site_option( 'registration' ) != 'blog' ) {
44
  echo '<li class="bp-signup no-arrow"><a href="' . bp_signup_page(false) . '">' . __( 'Sign Up', 'buddypress' ) . '</a></li>';
45
  }
46
  }
53
  if ( !$bp->bp_nav )
54
  return false;
55
 
 
 
 
56
  if ( is_user_logged_in() ) {
57
 
58
+ echo '<li id="bp-adminbar-account-menu"><a href="' . bp_loggedin_user_domain() . '">';
59
 
60
  echo __( 'My Account', 'buddypress' ) . '</a>';
61
  echo '<ul>';
67
 
68
  echo '<li' . $alt . '>';
69
  echo '<a id="bp-admin-' . $nav_item['css_id'] . '" href="' . $nav_item['link'] . '">' . $nav_item['name'] . '</a>';
70
+
71
  if ( is_array( $bp->bp_options_nav[$nav_item['css_id']] ) ) {
72
  echo '<ul>';
73
  $sub_counter = 0;
74
+
75
  foreach( $bp->bp_options_nav[$nav_item['css_id']] as $subnav_item ) {
76
  $alt = ( 0 == $sub_counter % 2 ) ? ' class="alt"' : '';
77
  echo '<li' . $alt . '><a id="bp-admin-' . $subnav_item['css_id'] . '" href="' . $subnav_item['link'] . '">' . $subnav_item['name'] . '</a></li>';
168
  }
169
 
170
  $alt = ( 0 == $counter % 2 ) ? ' class="alt"' : '';
171
+
172
+ if ( bp_blog_signup_enabled() ) {
173
+ echo '<li' . $alt . '>';
174
+ echo '<a href="' . $bp->loggedin_user->domain . $bp->blogs->slug . '/create-a-blog">' . __('Create a Blog!', 'buddypress') . '</a>';
175
+ echo '</li>';
176
+ }
177
+
178
  echo '</ul>';
179
  echo '</li>';
180
  }
bp-core/bp-core-ajax.php DELETED
@@ -1,81 +0,0 @@
1
- <?php
2
-
3
- function bp_core_add_ajax_hook() {
4
- do_action( 'wp_ajax_' . $_REQUEST['action'] );
5
- }
6
- add_action( 'init', 'bp_core_add_ajax_hook' );
7
-
8
- function bp_core_ajax_widget_members() {
9
- global $bp;
10
-
11
- check_ajax_referer('bp_core_widget_members');
12
-
13
- switch ( $_POST['filter'] ) {
14
- case 'newest-members':
15
- if ( !$users = wp_cache_get( 'newest_users', 'bp' ) ) {
16
- $users = BP_Core_User::get_newest_users( $_POST['max-members'], 1 );
17
- wp_cache_set( 'newest_users', $users, 'bp' );
18
- }
19
- break;
20
- case 'recently-active-members':
21
- if ( !$users = wp_cache_get( 'active_users', 'bp' ) ) {
22
- $users = BP_Core_User::get_active_users( $_POST['max-members'], 1 );
23
- wp_cache_set( 'active_users', $users, 'bp' );
24
- }
25
- break;
26
- case 'popular-members':
27
- if ( !$users = wp_cache_get( 'popular_users', 'bp' ) ) {
28
- $users = BP_Core_User::get_popular_users( $_POST['max-members'], 1 );
29
- wp_cache_set( 'popular_users', $users, 'bp' );
30
- }
31
- break;
32
- }
33
-
34
- if ( $users['users'] ) {
35
- echo '0[[SPLIT]]'; // return valid result.
36
-
37
- foreach ( (array) $users['users'] as $user ) {
38
- ?>
39
- <li class="vcard">
40
- <div class="item-avatar">
41
- <a href="<?php echo bp_core_get_userlink( $user->user_id, false, true ) ?>"><?php echo bp_core_get_avatar( $user->user_id, 1 ) ?></a>
42
- </div>
43
-
44
- <div class="item">
45
- <div class="item-title"><?php echo bp_core_get_userlink( $user->user_id ) ?></div>
46
- <div class="item-meta">
47
- <span class="activity">
48
- <?php
49
- if ( 'newest-members' == $_POST['filter'] ) {
50
- echo bp_core_get_last_activity( $user->user_registered, __( 'registered %s ago', 'buddypress' ) );
51
- } else if ( 'recently-active-members' == $_POST['filter'] ) {
52
- echo bp_core_get_last_activity( get_usermeta( $user->user_id, 'last_activity' ), __( 'active %s ago', 'buddypress' ) );
53
- } else if ( 'popular-members' == $_POST['filter'] ) {
54
- if ( 1 == get_usermeta( $user->user_id, 'total_friend_count' ) )
55
- echo get_usermeta( $user->user_id, 'total_friend_count' ) . __(' friend', 'buddypress');
56
- else
57
- echo get_usermeta( $user->user_id, 'total_friend_count' ) . __(' friends', 'buddypress');
58
- }
59
- ?>
60
- </span>
61
- </div>
62
- </div>
63
- </li>
64
- <?php
65
- }
66
- } else {
67
- echo "-1[[SPLIT]]<li>" . __("No members matched the current filter.", 'buddypress');
68
- }
69
- }
70
- add_action( 'wp_ajax_widget_members', 'bp_core_ajax_widget_members' );
71
-
72
-
73
- function bp_core_ajax_directory_members() {
74
- check_ajax_referer('directory_members');
75
-
76
- load_template( TEMPLATEPATH . '/directories/members/members-loop.php' );
77
- }
78
- add_action( 'wp_ajax_directory_members', 'bp_core_ajax_directory_members' );
79
-
80
-
81
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-core/bp-core-avatars.php CHANGED
@@ -1,498 +1,359 @@
1
  <?php
2
  /*
3
- Based on contributions from: Beau Lebens - http://www.dentedreality.com.au/
4
- Modified for BuddyPress by: Andy Peatling - http://apeatling.wordpress.com/
5
  */
6
 
7
- /* Make sure we have the core WordPress files we need */
8
- require_once( ABSPATH . '/wp-admin/includes/image.php' );
9
- require_once( ABSPATH . '/wp-admin/includes/file.php' );
10
-
11
- /* Define settings for avatars. [TODO] This will eventually end up as admin configurable settings */
12
- define( 'CORE_AVATAR_V1_W', apply_filters( 'bp_core_avatar_v1_w', 50 ) );
13
- define( 'CORE_AVATAR_V1_H', apply_filters( 'bp_core_avatar_v1_h', 50 ) );
14
- define( 'CORE_AVATAR_V2_W', apply_filters( 'bp_core_avatar_v2_w', 150 ) );
15
- define( 'CORE_AVATAR_V2_H', apply_filters( 'bp_core_avatar_v2_h', 150 ) );
16
- define( 'CORE_CROPPING_CANVAS_MAX', apply_filters( 'bp_core_avatar_cropping_canvas_max', 450 ) );
17
- define( 'CORE_MAX_FILE_SIZE', get_site_option('fileupload_maxk') * 1024 );
18
- define( 'CORE_DEFAULT_AVATAR', apply_filters( 'bp_core_avatar_default_src', BP_PLUGIN_URL . '/bp-xprofile/images/none.gif' ) );
19
- define( 'CORE_DEFAULT_AVATAR_THUMB', apply_filters( 'bp_core_avatar_default_thumb_src', BP_PLUGIN_URL . '/bp-xprofile/images/none-thumbnail.gif' ) );
20
-
21
- function bp_core_get_avatar( $user, $version = 1, $width = null, $height = null, $no_tag = false ) {
22
- global $bp, $current_blog;
23
 
24
- if ( !is_int($version) )
25
- $version = (int) $version;
26
-
27
- if ( CORE_AVATAR_V2_W == false && CORE_AVATAR_V2_H == false )
28
- $version = 1;
29
-
30
- if ( !$width )
31
- $width = constant('CORE_AVATAR_V' . $version . '_W');
32
-
33
- if ( !$height )
34
- $height = constant('CORE_AVATAR_V' . $version . '_H');
35
-
36
- $avatar_file = wp_cache_get( 'bp_core_avatar_v' . $version . '_u' . $user, 'bp' );
37
- if ( false === $avatar_file ) {
38
- $avatar_file = get_usermeta( $user, 'bp_core_avatar_v' . $version );
39
- wp_cache_set( 'bp_core_avatar_v' . $version . '_u' . $user, $avatar_file, 'bp' );
40
- }
41
-
42
- $url = $bp->root_domain . '/' . $avatar_file;
43
-
44
- if ( strlen($avatar_file) ) {
45
- if ( $no_tag )
46
- return $url;
47
- else
48
- return apply_filters( 'bp_core_get_avatar', '<img src="' . attribute_escape( $url ) . '" alt="" class="avatar photo" width="' . attribute_escape( $width ) . '" height="' . attribute_escape( $height ) . '" />', $user, $version, $width, $height, $no_tag );
49
- } else {
50
- $ud = get_userdata($user);
51
-
52
- if ( empty( $bp->grav_default ) ) {
53
- $default_grav = 'wavatar';
54
- } else if ( 'mystery' == $bp->grav_default ) {
55
- $default_grav = BP_PLUGIN_URL . '/bp-core/images/mystery-man.jpg';
56
- } else {
57
- $default_grav = $bp->grav_default;
58
- }
59
-
60
- $gravatar = 'http://www.gravatar.com/avatar/' . md5( $ud->user_email ) . '?d=' . $default_grav . '&amp;s=';
61
- if ( $no_tag )
62
- return apply_filters( 'bp_core_get_avatar', $gravatar . constant('CORE_AVATAR_V' . $version . '_W'), $user, $version, $width, $height, $no_tag );
63
- else
64
- return apply_filters( 'bp_core_get_avatar', '<img src="' . attribute_escape( $gravatar ) . constant('CORE_AVATAR_V' . $version . '_W') . '" alt="" class="avatar" width="' . attribute_escape( $width ) . '" height="' . attribute_escape( $height ) . '" />', $user, $version, $width, $height, $no_tag );
65
- }
66
- }
67
 
68
- // Override internal "get_avatar()" function to use our own where possible
69
- // WARNING: Does NOT apply size restrictions
70
- function bp_core_get_avatar_filter( $avatar, $id_or_email, $size, $default ) {
71
- $str = '';
72
- $ver = ( 1 == $size || 2 == $size ) ? $size : 1;
73
-
74
- if ( !CORE_AVATAR_V2_W && !CORE_AVATAR_V2_H )
75
- $ver = 1;
76
-
77
- if ( is_numeric($id_or_email) ) {
78
- $str = bp_core_get_avatar( $id_or_email, $ver );
79
- } elseif ( is_object($id_or_email) ) {
80
- if ( !empty($id_or_email->user_id) ) {
81
- $str = bp_core_get_avatar( $id_or_email->user_id, $ver );
82
- }
83
- }
84
 
85
- return empty($str) ? $avatar : $str;
86
- }
87
- add_filter( 'get_avatar', 'bp_core_get_avatar_filter', 10, 4 );
88
-
89
-
90
- // Main UI Rendering
91
- function bp_core_avatar_admin( $message = null, $action, $delete_action) {
92
- global $wp_upload_error;
93
- ?>
94
- <?php if ( !isset($_POST['slick_avatars_action']) && !isset($_GET['slick_avatars_action']) ) { ?>
95
- <?php if ( $message ) { ?>
96
- <br />
97
- <div id="message" class="updated fade">
98
- <p><?php echo $message; ?></p>
99
- </div>
100
- <?php } ?>
101
-
102
- <p><?php _e('Your avatar will be used on your profile and throughout the site.', 'buddypress') ?></p>
103
- <p><?php _e('Click below to select a JPG, GIF or PNG format photo from your computer and then click \'Upload Photo\' to proceed.', 'buddypress') ?></p>
104
-
105
- <?php
106
 
107
- bp_core_render_avatar_upload_form($action);
 
108
 
109
- $str = bp_core_get_avatar( get_current_user_id(), 1 );
110
- if ( strlen($str) ) {
111
- echo '<h3>' . __('This is your current avatar', 'buddypress') . '</h3>';
112
- echo '<span class="crop-img avatar">' . bp_core_get_avatar(get_current_user_id(), 1) . '</span>';
113
- echo '<span class="crop-img avatar">' . bp_core_get_avatar(get_current_user_id(), 2) . '</span>';
114
- echo '<a href="' . wp_nonce_url( $delete_action, 'bp_delete_avatar_link' ) . '">' . __( 'Delete', 'buddypress' ) . '</a>';
115
- }
116
 
117
- } else if ( isset($_POST['slick_avatars_action']) && 'upload' == $_POST['slick_avatars_action'] ) {
118
-
119
- // Confirm that the nonce is valid
120
- if ( !isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'slick_avatars') )
121
- bp_core_ap_die( 'Security error.' );
122
-
123
- // Set friendly error feedback.
124
- $uploadErrors = array(
125
- 0 => __("There is no error, the file uploaded with success", 'buddypress'),
126
- 1 => __("Your image was bigger than the maximum allowed file size of: ", 'buddypress') . size_format(CORE_MAX_FILE_SIZE),
127
- 2 => __("Your image was bigger than the maximum allowed file size of: ", 'buddypress') . size_format(CORE_MAX_FILE_SIZE),
128
- 3 => __("The uploaded file was only partially uploaded", 'buddypress'),
129
- 4 => __("No file was uploaded", 'buddypress'),
130
- 6 => __("Missing a temporary folder", 'buddypress')
131
- );
132
-
133
- if ( !bp_core_check_avatar_upload($_FILES) )
134
- bp_core_ap_die( sprintf( __( 'Your upload failed, please try again. Error was: %s', 'buddypress' ), $uploadErrors[$_FILES['file']['error']] ) );
135
-
136
- if ( !bp_core_check_avatar_size($_FILES) )
137
- bp_core_ap_die( sprintf( __( 'The file you uploaded is too big. Please upload a file under %s', 'buddypress'), size_format(CORE_MAX_FILE_SIZE) ) );
138
 
139
- if ( !bp_core_check_avatar_type($_FILES) )
140
- bp_core_ap_die( __( 'Please upload only JPG, GIF or PNG photos.', 'buddypress' ) );
141
-
142
- // "Handle" upload into temporary location
143
- if ( !$original = bp_core_handle_avatar_upload($_FILES) )
144
- bp_core_ap_die( sprintf( __( 'Upload Failed! Error was: %s', 'buddypress' ), $wp_upload_error ) );
145
-
146
- // Resize down to something we can display on the page or use original if its small enough already.
147
- if ( !$canvas = bp_core_resize_avatar($original) )
148
- $canvas = $original;
149
-
150
- // Render the cropper UI
151
- bp_core_render_avatar_cropper($original, $canvas, $action);
152
 
153
- } else if ( isset($_POST['slick_avatars_action']) && 'crop' == $_POST['slick_avatars_action'] ) {
154
- // Crop, save, store
155
-
156
- // Confirm that the nonce is valid
157
- if ( !isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'slick_avatars') )
158
- bp_core_ap_die( __( 'Security error.', 'buddypress' ) );
159
-
160
- if ( !bp_core_check_crop( $_POST['orig'], $_POST['canvas'] ) )
161
- bp_core_ap_die( __( 'Error when cropping, please go back and try again', 'buddypress' ) );
162
-
163
- if ( !$result = bp_core_avatar_cropstore( stripslashes($_POST['orig']), $_POST['canvas'], $_POST['v1_x1'], $_POST['v1_y1'], $_POST['v1_w'], $_POST['v1_h'], $_POST['v2_x1'], $_POST['v2_y1'], $_POST['v2_w'], $_POST['v2_h'] ) )
164
- bp_core_ap_die( __( 'Error when saving avatars, please go back and try again.', 'buddypress' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
 
166
- // Store details to the DB and we're done
167
- echo '<p>' . __('Your new avatar was successfully created!', 'buddypress') . '</p>';
 
 
 
 
 
 
 
168
 
169
- bp_core_avatar_save($result);
 
 
 
 
 
 
 
 
 
170
 
171
- echo '<span class="crop-img">' . bp_core_get_avatar( get_current_user_id(), 1 ) . '</span>';
 
 
 
 
 
 
 
 
 
172
 
173
- if ( CORE_AVATAR_V2_W && CORE_AVATAR_V2_H ) {
174
- echo '<span class="crop-img">' . bp_core_get_avatar( get_current_user_id(), 2 ) . '</span>';
175
- }
176
-
177
- } else if ( isset($_GET['slick_avatars_action']) && 'delete' == $_GET['slick_avatars_action'] ) {
178
- // Delete an avatar
179
 
180
- bp_core_delete_avatar();
 
 
181
 
182
- unset($_GET['slick_avatars_action']);
183
- $message = __('Avatar successfully removed.', 'buddypress');
184
- bp_core_avatar_admin($message);
 
 
 
 
 
 
185
 
186
- }
187
- ?>
188
- <?php
189
- }
190
-
191
- function bp_core_check_avatar_upload($file) {
192
- if ( $file['error'] )
193
- return false;
194
 
195
- return true;
196
- }
197
-
198
- function bp_core_check_avatar_size($file) {
199
- if ( $file['file']['size'] > CORE_MAX_FILE_SIZE )
200
  return false;
201
 
202
- return true;
203
- }
204
-
205
- function bp_core_check_avatar_type($file) {
206
- if ( ( strlen($file['file']['type']) && !preg_match('/(jpe?g|gif|png)$/', $file['file']['type'] ) ) && !preg_match( '/(jpe?g|gif|png)$/', $file['file']['name'] ) )
207
- return false;
208
 
209
- return true;
 
 
 
 
 
 
 
 
210
  }
211
 
212
- function bp_core_handle_avatar_upload($file) {
213
- global $wp_upload_error;
214
-
215
- // Change the upload file location to /avatars/user_id
216
- add_filter( 'upload_dir', 'bp_core_avatar_upload_dir' );
217
 
218
- $res = wp_handle_upload( $file['file'], array('action'=>'slick_avatars') );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
 
220
- if ( !in_array('error', array_keys($res) ) ) {
221
- return $res['file'];
222
- } else {
223
- $wp_upload_error = $res['error'];
224
- return false;
 
 
 
 
 
 
225
  }
226
- }
227
-
228
- function bp_core_avatar_upload_dir( $upload, $user_id = false ) {
229
- global $bp;
230
 
231
- if ( !$user_id )
232
- $user_id = $bp->loggedin_user->id;
 
 
 
 
 
233
 
234
- $path = get_blog_option( 1, 'upload_path' );
235
- $newdir = path_join( ABSPATH, $path );
236
- $newdir .= '/avatars/' . $user_id;
237
 
238
- $newbdir = $newdir;
239
-
240
- @wp_mkdir_p( $newdir );
241
 
242
- $newurl = trailingslashit( get_blog_option( 1, 'siteurl' ) ) . '/avatars/' . $user_id;
243
- $newburl = $newurl;
244
- $newsubdir = '/avatars/' . $user_id;
 
 
 
 
245
 
246
- return apply_filters( 'bp_core_avatar_upload_dir', array( 'path' => $newdir, 'url' => $newurl, 'subdir' => $newsubdir, 'basedir' => $newbdir, 'baseurl' => $newburl, 'error' => false ) );
247
- }
248
 
249
- function bp_core_check_avatar_dimensions($file) {
250
- $size = getimagesize($file);
251
 
252
- if ( $size[0] < (int)CORE_AVATAR_V2_W || $size[1] < (int)CORE_CROPPING_CANVAS_MAX )
253
- return false;
254
-
255
  return true;
256
  }
257
 
258
- function bp_core_resize_avatar( $file, $size = false ) {
259
-
260
- if ( !$size )
261
- $size = CORE_CROPPING_CANVAS_MAX;
262
-
263
- $canvas = wp_create_thumbnail( $file, $size );
264
-
265
- if ( $canvas->errors )
266
- return false;
267
-
268
- return $canvas = str_replace( '//', '/', $canvas );
269
- }
270
-
271
- function bp_core_render_avatar_cropper( $original, $new, $action, $user_id = null, $no_form_tag = false, $url = false ) {
272
  global $bp;
273
 
274
- $size = getimagesize($new);
 
275
 
276
- if ( !$user_id )
277
- $user_id = $bp->loggedin_user->id;
278
-
279
- $src = str_replace( array(ABSPATH), array(site_url() . '/'), $new );
 
 
 
 
280
 
281
- // Load cropper details
 
 
 
282
 
283
- // V1 UI
284
- if ( !$no_form_tag )
285
- echo '<form action="' . $action . '" method="post" id="avatar-cropper">';
286
-
287
- echo '<input type="hidden" name="slick_avatars_action" value="crop" />';
288
- echo '<input type="hidden" name="action" value="slick_avatars" />';
289
- echo '<input type="hidden" name="nonce" value="' . wp_create_nonce('slick_avatars') . '" />';
290
- echo '<input type="hidden" name="orig" value="' . $original . '" />';
291
- echo '<input type="hidden" name="canvas" value="' . $new . '" />';
292
 
293
- echo '<div id="avatar_v1">';
294
- echo '<h3>' . __( 'Please Crop Your Avatar!', 'buddypress' ) . '</h3>';
295
- echo '<h4>' . __('Thumbnail Avatar', 'buddypress') . '</h4>';
296
- echo '<p>' . __('Please crop a small version of your avatar to use for thumbnails.', 'buddypress') . '</p>';
297
 
298
- // Canvas
299
- echo '<div id="crop-v1" class="crop-img"><img src="' . $src . '" ' . $size[3] . ' border="0" alt="' . __( 'Select the area to crop', 'buddypress' ) . '" id="crop-v1-img" /></div>';
300
 
301
- // Preview
302
- echo '<p class="crop-preview"><strong>' . __('Crop Preview', 'buddypress') . '</strong></p>';
303
- echo '<div id="crop-preview-v1" class="crop-preview"></div>';
 
 
 
 
 
 
 
 
 
304
 
305
- // Hidden form fields
306
- echo '<input type="hidden" id="v1_x1" name="v1_x1" value="" />';
307
- echo '<input type="hidden" id="v1_y1" name="v1_y1" value="" />';
308
- echo '<input type="hidden" id="v1_x2" name="v1_x2" value="" />';
309
- echo '<input type="hidden" id="v1_y2" name="v1_y2" value="" />';
310
- echo '<input type="hidden" id="v1_w" name="v1_w" value="" />';
311
- echo '<input type="hidden" id="v1_h" name="v1_h" value="" />';
312
 
313
- // V2 UI (optional)
314
- if (CORE_AVATAR_V2_W !== false && CORE_AVATAR_V2_H !== false) {
315
- // Continue button (v1 => v2)
316
- echo '<p class="submit"><input type="button" name="avatar_continue" id="avatar_continue" value="' . __('Crop Thumbnail &amp; Continue', 'buddypress') . '" onclick="cropAndContinue();" /></p>';
317
- echo '</div>';
318
-
319
- echo '<div id="avatar_v2" style="display: none">';
320
- echo '<h4>' . __('Full Size Avatar', 'buddypress') . '</h4>';
321
- echo '<p>' . __('Please crop a full size version of your avatar.', 'buddypress') . '</p>';
322
-
323
- // Canvas
324
- echo '<div id="crop-v2" class="crop-img"><img src="' . $src . '" ' . $size[3] . ' border="0" alt="' . __('Select the area to crop', 'buddypress' ) . '" id="crop-v2-img" /></div>';
325
-
326
- // Preview
327
- echo '<p class="crop-preview"><strong>' . __('Crop Preview', 'buddypress') . '</strong></p>';
328
- echo '<div id="crop-preview-v2" class="crop-preview"></div>';
329
-
330
- // Hidden form fields
331
- echo '<input type="hidden" id="v2_x1" name="v2_x1" value="" />';
332
- echo '<input type="hidden" id="v2_y1" name="v2_y1" value="" />';
333
- echo '<input type="hidden" id="v2_x2"name="v2_x2" value="" />';
334
- echo '<input type="hidden" id="v2_y2"name="v2_y2" value="" />';
335
- echo '<input type="hidden" id="v2_w" name="v2_w" value="" />';
336
- echo '<input type="hidden" id="v2_h" name="v2_h" value="" />';
337
-
338
- // Final button to process everything
339
- echo '<p class="submit"><input type="submit" id="crop-complete" name="save" value="' . __('Crop Full Size &amp; Save', 'buddypress') . '" /></p>';
340
- echo '</div>';
341
- } else {
342
- // Close out v1 DIV
343
- echo '</div>';
344
-
345
- // Final button to process everything
346
- echo '<p class="submit"><input type="submit" name="save" value="' . __('Crop Full Size &amp; Save', 'buddypress') . '" /></p>';
347
  }
348
 
349
- do_action( 'bp_core_render_avatar_cropper', $original, $new, $action );
350
-
351
- if ( !$no_form_tag )
352
- echo '</form>';
353
- ?>
354
- <script type="text/javascript" charset="utf-8">
355
- jQuery(document).ready(function(){
356
- v1Cropper();
357
- });
358
- </script>
359
- <?php
360
  }
361
 
362
- function bp_core_check_crop( $original, $canvas ) {
363
- if ( is_file($original) && is_readable($original) && is_file($canvas) && is_readable($canvas) )
364
- return true;
365
 
366
- return false;
367
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
368
 
369
- function bp_core_avatar_cropstore( $source, $canvas, $v1_x1, $v1_y1, $v1_w, $v1_h, $v2_x1, $v2_y1, $v2_w, $v2_h, $from_signup = false, $filename = 'avatar', $item_id = null ) {
370
- $size = getimagesize($source);
371
- $dims = getimagesize($canvas);
 
 
 
 
372
 
373
- // Figure out multiplier for scaling
374
- $multi = $size[0] / $dims[0];
375
-
376
- if ( $item_id )
377
- $filename_item_id = $item_id . '-';
378
-
379
- if ( $filename != 'avatar' ) {
380
- $v1_filename = '-' . md5( $filename_item_id . $filename . time() ) . '-thumb';
381
- $v2_filename = '-' . md5( $filename_item_id . $filename . time() ) . '-full';
382
- } else {
383
- $v1_filename = md5( $source . time() ) . '-avatar1';
384
- $v2_filename = md5( $source . time() ) . '-avatar2';
385
- }
386
 
387
- $v1_filename = apply_filters( 'bp_avatar_v1_filename', $v1_filename );
388
- $v2_filename = apply_filters( 'bp_avatar_v2_filename', $v2_filename );
 
 
 
389
 
390
- // Perform v1 crop
391
- $v1_dest = apply_filters( 'bp_avatar_v1_dest', dirname($source) . '/' . preg_replace('!(\.[^.]+)?$!', $v1_filename . '$1', basename($source), 1), $source );
 
392
 
393
- if ( $from_signup )
394
- $v1_out = wp_crop_image( $source, $v1_x1, $v1_y1, $v1_w, $v1_h, CORE_AVATAR_V1_W, CORE_AVATAR_V1_H, false, $v1_dest );
395
- else
396
- $v1_out = wp_crop_image( $source, ($v1_x1 * $multi), ($v1_y1 * $multi), ($v1_w * $multi), ($v1_h * $multi), CORE_AVATAR_V1_W, CORE_AVATAR_V1_H, false, $v1_dest );
397
-
398
- // Perform v2 crop
399
- if ( CORE_AVATAR_V2_W !== false && CORE_AVATAR_V2_H !== false ) {
400
- $v2_dest = apply_filters( 'bp_avatar_v2_dest', dirname($source) . '/' . preg_replace('!(\.[^.]+)?$!', $v2_filename . '$1', basename($source), 1), $source );
401
-
402
- if ( $from_signup )
403
- $v2_out = wp_crop_image( $source, $v2_x1, $v2_y1, $v2_w, $v2_h, CORE_AVATAR_V2_W, CORE_AVATAR_V2_H, false, $v2_dest );
404
- else
405
- $v2_out = wp_crop_image( $source, ($v2_x1 * $multi), ($v2_y1 * $multi), ($v2_w * $multi), ($v2_h * $multi), CORE_AVATAR_V2_W, CORE_AVATAR_V2_H, false, $v2_dest );
406
- }
407
 
408
- // Clean up canvas and original images used during cropping
409
- foreach ( array( str_replace( '..', '', $source ), str_replace( '..', '', $canvas) ) as $f ) {
410
- @unlink($f);
411
- }
 
 
 
412
 
413
- $dir = $source;
 
414
 
415
- do {
416
- $dir = dirname($dir);
417
- @rmdir($dir); // will fail on non-empty directories
418
- } while ( substr_count($dir, '/') >= 2 && stristr($dir, ABSPATH) );
419
-
420
- return apply_filters( 'bp_core_avatar_cropstore', array('v1_out' => $v1_out, 'v2_out' => $v2_out) );
421
  }
422
 
423
- function bp_core_avatar_save( $vars, $user_id = false ) {
424
- if ( !$user_id )
425
- $user_id = get_current_user_id();
426
-
427
- $old = get_usermeta( $user_id, 'bp_core_avatar_v1_path' );
428
- $v1_href = apply_filters( 'bp_avatar_v1_href', str_replace( array(ABSPATH), array($src), $vars['v1_out'] ), $src, $vars['v1_out'] );
429
- update_usermeta( $user_id, 'bp_core_avatar_v1', $v1_href );
430
- update_usermeta( $user_id, 'bp_core_avatar_v1_path', $vars['v1_out'] );
431
- @unlink($old); // Removing old avatar
432
-
433
- if ( CORE_AVATAR_V2_W !== false && CORE_AVATAR_V2_H !== false ) {
434
- $old = get_usermeta( $user_id, 'bp_core_avatar_v2_path' );
435
- $v2_href = apply_filters( 'bp_avatar_v2_href', str_replace( array(ABSPATH), array($src), $vars['v2_out'] ), $src, $vars['v2_out'] );
436
- update_usermeta( $user_id, 'bp_core_avatar_v2', $v2_href );
437
- update_usermeta( $user_id, 'bp_core_avatar_v2_path', $vars['v2_out'] );
438
- @unlink($old); // Removing old avatar
439
- }
440
 
441
- do_action( 'bp_core_avatar_save', $user_id, $old, $v1_href, $vars['v1_out'] );
442
- }
443
 
444
- function bp_core_render_avatar_upload_form($action, $no_form_tag = false) {
445
- if ( !$no_form_tag ) { ?>
446
- <form method="post" action="<?php echo $action ?>" enctype="multipart/form-data" id="avatar-upload">
447
- <?php } ?>
448
- <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo CORE_MAX_FILE_SIZE; ?>" />
449
- <input type="hidden" name="slick_avatars_action" value="upload" />
450
- <input type="hidden" name="action" value="slick_avatars" />
451
- <input type="hidden" name="nonce" value="<?php echo wp_create_nonce('slick_avatars'); ?>" />
452
- <input type="file" name="file" id="file" />
453
- <input type="submit" name="upload" id="upload" value="<?php _e( 'Upload Photo', 'buddypress' ) ?>"/>
454
-
455
- <?php do_action( 'bp_core_render_avatar_upload_form' ) ?>
456
-
457
- <?php if ( !$no_form_tag ) { ?>
458
- </form>
459
- <?php
460
- }
461
  }
 
462
 
463
- function bp_core_delete_avatar() {
464
- $user_id = get_current_user_id();
465
-
466
- $old_v1 = get_usermeta( $user_id, 'bp_core_avatar_v1_path' );
467
- $old_v2 = get_usermeta( $user_id, 'bp_core_avatar_v2_path' );
468
-
469
- delete_usermeta( $user_id, 'bp_core_avatar_v1_path' );
470
- delete_usermeta( $user_id, 'bp_core_avatar_v2_path' );
471
-
472
- delete_usermeta( $user_id, 'bp_core_avatar_v1' );
473
- delete_usermeta( $user_id, 'bp_core_avatar_v2' );
474
-
475
- // Remove the actual images
476
- @unlink($old_v1);
477
- @unlink($old_v2);
478
 
479
- do_action( 'bp_core_delete_avatar', $user_id, $old_v1, $old_v2 );
480
  }
481
 
482
- function bp_core_ap_die( $msg ) {
483
- global $bp;
484
- echo '<p><strong>' . $msg . '</strong></p>';
485
- echo '<p><a href="' . $bp->loggedin_user->domain . $bp->profile->slug . '/change-avatar">' . __('Try Again', 'buddypress') . '</a></p>';
486
- echo '</div>';
487
- exit;
488
  }
489
 
490
- function bp_core_thumb_error( $str ) {
491
- if ( !is_string($str) ) {
492
  return false;
493
- } else {
494
- return preg_match( '/(filetype|invalid|not found)/is', $str );
495
- }
496
  }
497
 
498
  ?>
1
  <?php
2
  /*
3
+ Based on contributions from: Beau Lebens - http://www.dentedreality.com.au/
4
+ Modified for BuddyPress by: Andy Peatling - http://apeatling.wordpress.com/
5
  */
6
 
7
+ /***
8
+ * Set up the constants we need for avatar support
9
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ if ( !defined( 'BP_AVATAR_THUMB_WIDTH' ) )
12
+ define( 'BP_AVATAR_THUMB_WIDTH', 50 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
+ if ( !defined( 'BP_AVATAR_THUMB_HEIGHT' ) )
15
+ define( 'BP_AVATAR_THUMB_HEIGHT', 50 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
+ if ( !defined( 'BP_AVATAR_FULL_WIDTH' ) )
18
+ define( 'BP_AVATAR_FULL_WIDTH', 150 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ if ( !defined( 'BP_AVATAR_FULL_HEIGHT' ) )
21
+ define( 'BP_AVATAR_FULL_HEIGHT', 150 );
22
 
23
+ if ( !defined( 'BP_AVATAR_ORIGINAL_MAX_WIDTH' ) )
24
+ define( 'BP_AVATAR_ORIGINAL_MAX_WIDTH', 450 );
 
 
 
 
 
25
 
26
+ if ( !defined( 'BP_AVATAR_ORIGINAL_MAX_FILESIZE' ) )
27
+ define( 'BP_AVATAR_ORIGINAL_MAX_FILESIZE', get_site_option( 'fileupload_maxk' ) * 1024 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ if ( !defined( 'BP_AVATAR_DEFAULT' ) )
30
+ define( 'BP_AVATAR_DEFAULT', BP_PLUGIN_URL . '/bp-xprofile/images/none.gif' );
 
 
 
 
 
 
 
 
 
 
 
31
 
32
+ if ( !defined( 'BP_AVATAR_DEFAULT_THUMB' ) )
33
+ define( 'BP_AVATAR_DEFAULT_THUMB', BP_PLUGIN_URL . '/bp-xprofile/images/none-thumbnail.gif' );
34
+
35
+ function bp_core_fetch_avatar( $args = '' ) {
36
+ global $bp, $current_blog;
37
+
38
+ $defaults = array(
39
+ 'item_id' => false,
40
+ 'object' => 'user', // user OR group OR blog OR custom type (if you use filters)
41
+ 'type' => 'thumb',
42
+ 'avatar_dir' => false,
43
+ 'width' => false,
44
+ 'height' => false,
45
+ 'class' => 'avatar',
46
+ 'css_id' => false,
47
+ 'alt' => __( 'Avatar Image', 'buddypress' ),
48
+ 'no_grav' => false // If there is no avatar found, return false instead of a grav?
49
+ );
50
+
51
+ $params = wp_parse_args( $args, $defaults );
52
+ extract( $params, EXTR_SKIP );
53
+
54
+ if ( !$item_id ) {
55
+ if ( 'user' == $object )
56
+ $item_id = $bp->displayed_user->id;
57
+ else if ( 'group' == $object )
58
+ $item_id = $bp->groups->current_group->id;
59
+ else if ( 'blog' == $object )
60
+ $item_id = $current_blog->id;
61
+
62
+ $item_id = apply_filters( 'bp_core_avatar_item_id', $item_id, $object );
63
+
64
+ if ( !$item_id ) return false;
65
+ }
66
 
67
+ if ( !$avatar_dir ) {
68
+ if ( 'user' == $object )
69
+ $avatar_dir = 'avatars';
70
+ else if ( 'group' == $object )
71
+ $avatar_dir = 'group-avatars';
72
+ else if ( 'blog' == $object )
73
+ $avatar_dir = 'blog-avatars';
74
+
75
+ $avatar_dir = apply_filters( 'bp_core_avatar_dir', $avatar_dir, $object );
76
 
77
+ if ( !$avatar_dir ) return false;
78
+ }
79
+
80
+ if ( !$css_id )
81
+ $css_id = $object . '-' . $item_id . '-avatar';
82
+
83
+ if ( $width )
84
+ $html_width = " width='{$width}'";
85
+ else
86
+ $html_width = ( 'thumb' == $type ) ? ' width="' . BP_AVATAR_THUMB_WIDTH . '"' : ' width="' . BP_AVATAR_FULL_WIDTH . '"';
87
 
88
+ if ( $height )
89
+ $html_height = " height='{$height}'";
90
+ else
91
+ $html_height = ( 'thumb' == $type ) ? ' height="' . BP_AVATAR_THUMB_HEIGHT . '"' : ' height="' . BP_AVATAR_FULL_HEIGHT . '"';
92
+
93
+ $avatar_folder_url = apply_filters( 'bp_core_avatar_folder_url', get_blog_option( BP_ROOT_BLOG, 'siteurl' ) . '/' . basename( WP_CONTENT_DIR ) . '/blogs.dir/' . BP_ROOT_BLOG . '/files/' . $avatar_dir . '/' . $item_id, $item_id, $object, $avatar_dir );
94
+ $avatar_folder_dir = apply_filters( 'bp_core_avatar_folder_dir', WP_CONTENT_DIR . '/blogs.dir/' . BP_ROOT_BLOG . '/files/' . $avatar_dir . '/' . $item_id, $item_id, $object, $avatar_dir );
95
+
96
+ /* If no avatars have been uploaded for this item, display a gravatar */
97
+ if ( !file_exists( $avatar_folder_dir ) && !$no_grav ) {
98
 
99
+ if ( empty( $bp->grav_default->{$object} ) )
100
+ $default_grav = 'wavatar';
101
+ else if ( 'mystery' == $bp->grav_default->{$object} )
102
+ $default_grav = BP_PLUGIN_URL . '/bp-core/images/mystery-man.jpg';
103
+ else
104
+ $default_grav = $bp->grav_default->{$object};
105
 
106
+ if ( $width ) $grav_size = $width;
107
+ else if ( 'full' == $type ) $grav_size = BP_AVATAR_FULL_WIDTH;
108
+ else if ( 'thumb' == $type ) $grav_size = BP_AVATAR_THUMB_WIDTH;
109
 
110
+ if ( 'user' == $object ) {
111
+ $ud = get_userdata( $item_id );
112
+ $grav_email = $ud->user_email;
113
+ } else if ( 'group' == $object || 'blog' == $object ) {
114
+ $grav_email = "{$item_id}-{$object}@{$bp->root_domain}";
115
+ }
116
+
117
+ $grav_email = apply_filters( 'bp_core_gravatar_email', $grav_email, $item_id, $object );
118
+ $gravatar = apply_filters( 'bp_gravatar_url', 'http://www.gravatar.com/avatar/' ) . md5( $grav_email ) . '?d=' . $default_grav . '&amp;s=' . $grav_size;
119
 
120
+ return apply_filters( 'bp_core_fetch_avatar', "<img src='{$gravatar}' alt='{$alt}' id='{$css_id}' class='{$class}'{$html_width}{$html_height} />", $params );
 
 
 
 
 
 
 
121
 
122
+ } else if ( !file_exists( $avatar_folder_dir ) && $no_grav )
 
 
 
 
123
  return false;
124
 
125
+ /* Set the file names to search for to select the full size or thumbnail image. */
126
+ $avatar_name = ( 'full' == $type ) ? '-bpfull' : '-bpthumb';
127
+ $legacy_user_avatar_name = ( 'full' == $type ) ? '-avatar2' : '-avatar1';
128
+ $legacy_group_avatar_name = ( 'full' == $type ) ? '-groupavatar-full' : '-groupavatar-thumb';
 
 
129
 
130
+ if ( $av_dir = opendir( $avatar_folder_dir ) ) {
131
+ while ( false !== ( $avatar_file = readdir($av_dir) ) ) {
132
+ if ( preg_match( "/{$avatar_name}/", $avatar_file ) || preg_match( "/{$legacy_user_avatar_name}/", $avatar_file ) || preg_match( "/{$legacy_group_avatar_name}/", $avatar_file ) )
133
+ $avatar_url = $avatar_folder_url . '/' . $avatar_file;
134
+ }
135
+ }
136
+ closedir($av_dir);
137
+
138
+ return apply_filters( 'bp_core_fetch_avatar', "<img src='{$avatar_url}' alt='{$alt}' id='{$css_id}' class='{$class}'{$html_width}{$html_height} />", $params );
139
  }
140
 
141
+ function bp_core_delete_existing_avatar( $args = '' ) {
142
+ global $bp;
 
 
 
143
 
144
+ $defaults = array(
145
+ 'item_id' => false,
146
+ 'object' => 'user', // user OR group OR blog OR custom type (if you use filters)
147
+ 'avatar_dir' => false
148
+ );
149
+
150
+ $args = wp_parse_args( $args, $defaults );
151
+ extract( $args, EXTR_SKIP );
152
+
153
+ if ( !$item_id ) {
154
+ if ( 'user' == $object )
155
+ $item_id = $bp->displayed_user->id;
156
+ else if ( 'group' == $object )
157
+ $item_id = $bp->groups->current_group->id;
158
+ else if ( 'blog' == $object )
159
+ $item_id = $current_blog->id;
160
+
161
+ $item_id = apply_filters( 'bp_core_avatar_item_id', $item_id, $object );
162
+
163
+ if ( !$item_id ) return false;
164
+ }
165
 
166
+ if ( !$avatar_dir ) {
167
+ if ( 'user' == $object )
168
+ $avatar_dir = 'avatars';
169
+ else if ( 'group' == $object )
170
+ $avatar_dir = 'group-avatars';
171
+ else if ( 'blog' == $object )
172
+ $avatar_dir = 'blog-avatars';
173
+
174
+ $avatar_dir = apply_filters( 'bp_core_avatar_dir', $avatar_dir, $object );
175
+
176
+ if ( !$avatar_dir ) return false;
177
  }
 
 
 
 
178
 
179
+ if ( 'user' == $object ) {
180
+ /* Delete any legacy meta entries if this is a user avatar */
181
+ delete_usermeta( $item_id, 'bp_core_avatar_v1_path' );
182
+ delete_usermeta( $item_id, 'bp_core_avatar_v1' );
183
+ delete_usermeta( $item_id, 'bp_core_avatar_v2_path' );
184
+ delete_usermeta( $item_id, 'bp_core_avatar_v2' );
185
+ }
186
 
187
+ $avatar_folder_dir = apply_filters( 'bp_core_avatar_folder_dir', WP_CONTENT_DIR . '/blogs.dir/' . BP_ROOT_BLOG . '/files/' . $avatar_dir . '/' . $item_id, $item_id, $object, $avatar_dir );
 
 
188
 
189
+ if ( !file_exists( $avatar_folder_dir ) )
190
+ return false;
 
191
 
192
+ if ( $av_dir = opendir( $avatar_folder_dir ) ) {
193
+ while ( false !== ( $avatar_file = readdir($av_dir) ) ) {
194
+ if ( ( preg_match( "/-bpfull/", $avatar_file ) || preg_match( "/-bpthumb/", $avatar_file ) ) && '.' != $avatar_file && '..' != $avatar_file )
195
+ @unlink( $avatar_folder_dir . '/' . $avatar_file );
196
+ }
197
+ }
198
+ closedir($av_dir);
199
 
200
+ @rmdir( $avatar_folder_dir );
 
201
 
202
+ do_action( 'bp_core_delete_existing_avatar', $args );
 
203
 
 
 
 
204
  return true;
205
  }
206
 
207
+ function bp_core_avatar_handle_upload( $file, $upload_dir_filter ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  global $bp;
209
 
210
+ require_once( ABSPATH . '/wp-admin/includes/image.php' );
211
+ require_once( ABSPATH . '/wp-admin/includes/file.php' );
212
 
213
+ $uploadErrors = array(
214
+ 0 => __("There is no error, the file uploaded with success", 'buddypress'),
215
+ 1 => __("Your image was bigger than the maximum allowed file size of: ", 'buddypress') . size_format(BP_AVATAR_ORIGINAL_MAX_FILESIZE),
216
+ 2 => __("Your image was bigger than the maximum allowed file size of: ", 'buddypress') . size_format(BP_AVATAR_ORIGINAL_MAX_FILESIZE),
217
+ 3 => __("The uploaded file was only partially uploaded", 'buddypress'),
218
+ 4 => __("No file was uploaded", 'buddypress'),
219
+ 6 => __("Missing a temporary folder", 'buddypress')
220
+ );
221
 
222
+ if ( !bp_core_check_avatar_upload( $file ) ) {
223
+ bp_core_add_message( sprintf( __( 'Your upload failed, please try again. Error was: %s', 'buddypress' ), $uploadErrors[$file['file']['error']] ), 'error' );
224
+ return false;
225
+ }
226
 
227
+ if ( !bp_core_check_avatar_size( $file ) ) {
228
+ bp_core_add_message( sprintf( __( 'The file you uploaded is too big. Please upload a file under %s', 'buddypress'), size_format(BP_AVATAR_ORIGINAL_MAX_FILESIZE) ), 'error' );
229
+ return false;
230
+ }
 
 
 
 
 
231
 
232
+ if ( !bp_core_check_avatar_type( $file ) ) {
233
+ bp_core_add_message( __( 'Please upload only JPG, GIF or PNG photos.', 'buddypress' ), 'error' );
234
+ return false;
235
+ }
236
 
237
+ // Filter the upload location
238
+ add_filter( 'upload_dir', $upload_dir_filter, 10, 0 );
239
 
240
+ $bp->avatar_admin->original = wp_handle_upload( $file['file'], array( 'action'=> 'bp_avatar_upload' ) );
241
+
242
+ // Move the file to the correct upload location.
243
+ if ( !empty( $bp->avatar_admin->original['error'] ) ) {
244
+ bp_core_add_message( sprintf( __( 'Upload Failed! Error was: %s', 'buddypress' ), $bp->avatar_admin->original['error'] ), 'error' );
245
+ return false;
246
+ }
247
+
248
+ // Resize the image down to something manageable and then delete the original
249
+ if ( getimagesize( $bp->avatar_admin->original['file'] ) > BP_AVATAR_ORIGINAL_MAX_WIDTH ) {
250
+ $bp->avatar_admin->resized = wp_create_thumbnail( $bp->avatar_admin->original['file'], BP_AVATAR_ORIGINAL_MAX_WIDTH );
251
+ }
252
 
253
+ $bp->avatar_admin->image = new stdClass;
 
 
 
 
 
 
254
 
255
+ // We only want to handle one image after resize.
256
+ if ( empty( $bp->avatar_admin->resized ) )
257
+ $bp->avatar_admin->image->dir = $bp->avatar_admin->original['file'];
258
+ else {
259
+ $bp->avatar_admin->image->dir = $bp->avatar_admin->resized;
260
+ @unlink( $bp->avatar_admin->original['file'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  }
262
 
263
+ /* Set the url value for the image */
264
+ $bp->avatar_admin->image->url = str_replace( WP_CONTENT_DIR, WP_CONTENT_URL, $bp->avatar_admin->image->dir );
265
+
266
+ return true;
 
 
 
 
 
 
 
267
  }
268
 
269
+ function bp_core_avatar_handle_crop( $args = '' ) {
270
+ global $bp;
 
271
 
272
+ $defaults = array(
273
+ 'object' => 'user',
274
+ 'avatar_dir' => 'avatars',
275
+ 'item_id' => false,
276
+ 'original_file' => false,
277
+ 'crop_w' => BP_AVATAR_FULL_WIDTH,
278
+ 'crop_h' => BP_AVATAR_FULL_HEIGHT,
279
+ 'crop_x' => 0,
280
+ 'crop_y' => 0
281
+ );
282
+
283
+ $r = wp_parse_args( $args, $defaults );
284
+ extract( $r, EXTR_SKIP );
285
+
286
+ if ( !$original_file )
287
+ return false;
288
 
289
+ if ( !file_exists( WP_CONTENT_DIR . '/' . $original_file ) )
290
+ return false;
291
+
292
+ if ( !$item_id )
293
+ $avatar_folder_dir = apply_filters( 'bp_core_avatar_folder_dir', WP_CONTENT_DIR . dirname( $original_file ), $item_id, $object, $avatar_dir );
294
+ else
295
+ $avatar_folder_dir = apply_filters( 'bp_core_avatar_folder_dir', WP_CONTENT_DIR . '/blogs.dir/' . BP_ROOT_BLOG . '/files/' . $avatar_dir . '/' . $item_id, $item_id, $object, $avatar_dir );
296
 
297
+ if ( !file_exists( $avatar_folder_dir ) )
298
+ return false;
 
 
 
 
 
 
 
 
 
 
 
299
 
300
+ require_once( ABSPATH . '/wp-admin/includes/image.php' );
301
+ require_once( ABSPATH . '/wp-admin/includes/file.php' );
302
+
303
+ /* Delete the existing avatar files for the object */
304
+ bp_core_delete_existing_avatar( array( 'object' => $object, 'avatar_path' => $avatar_folder_dir ) );
305
 
306
+ /* Make sure we at least have a width and height for cropping */
307
+ if ( !(int)$crop_w )
308
+ $crop_w = BP_AVATAR_FULL_WIDTH;
309
 
310
+ if ( !(int)$crop_h )
311
+ $crop_h = BP_AVATAR_FULL_HEIGHT;
 
 
 
 
 
 
 
 
 
 
 
 
312
 
313
+ /* Set the full and thumb filenames */
314
+ $full_filename = wp_hash( $original_file . time() ) . '-bpfull.jpg';
315
+ $thumb_filename = wp_hash( $original_file . time() ) . '-bpthumb.jpg';
316
+
317
+ /* Crop the image */
318
+ $full_cropped = wp_crop_image( WP_CONTENT_DIR . $original_file, (int)$crop_x, (int)$crop_y, (int)$crop_w, (int)$crop_h, BP_AVATAR_FULL_WIDTH, BP_AVATAR_FULL_HEIGHT, false, $avatar_folder_dir . '/' . $full_filename );
319
+ $thumb_cropped = wp_crop_image( WP_CONTENT_DIR . $original_file, (int)$crop_x, (int)$crop_y, (int)$crop_w, (int)$crop_h, BP_AVATAR_THUMB_WIDTH, BP_AVATAR_THUMB_HEIGHT, false, $avatar_folder_dir . '/' . $thumb_filename );
320
 
321
+ /* Remove the original */
322
+ @unlink( WP_CONTENT_DIR . $original_file );
323
 
324
+ return true;
 
 
 
 
 
325
  }
326
 
327
+ // Override internal "get_avatar()" function to use our own where possible
328
+ function bp_core_fetch_avatar_filter( $avatar, $id_or_email, $size, $default, $alt ) {
329
+ if ( is_object ( $id_or_email ) )
330
+ $id_or_email = $id_or_email->user_id;
 
 
 
 
 
 
 
 
 
 
 
 
 
331
 
332
+ $bp_avatar = bp_core_fetch_avatar( array( 'no_grav' => true, 'item_id' => $id_or_email, 'width' => $size, 'height' => $size, 'alt' => $alt ) );
 
333
 
334
+ return ( !$bp_avatar ) ? $avatar : $bp_avatar;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
  }
336
+ add_filter( 'get_avatar', 'bp_core_fetch_avatar_filter', 10, 5 );
337
 
338
+ function bp_core_check_avatar_upload($file) {
339
+ if ( $file['error'] )
340
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
341
 
342
+ return true;
343
  }
344
 
345
+ function bp_core_check_avatar_size($file) {
346
+ if ( $file['file']['size'] > BP_AVATAR_ORIGINAL_MAX_FILESIZE )
347
+ return false;
348
+
349
+ return true;
 
350
  }
351
 
352
+ function bp_core_check_avatar_type($file) {
353
+ if ( ( strlen($file['file']['type']) && !preg_match('/(jpe?g|gif|png)$/', $file['file']['type'] ) ) && !preg_match( '/(jpe?g|gif|png)$/', $file['file']['name'] ) )
354
  return false;
355
+
356
+ return true;
 
357
  }
358
 
359
  ?>
bp-core/bp-core-catchuri.php CHANGED
@@ -19,16 +19,16 @@ Modified for BuddyPress by: Andy Peatling - http://apeatling.wordpress.com/
19
  *
20
  * Example:
21
  * - http://domain.com/members/andy/profile/edit/group/5/
22
- * - $current_component: string 'profile'
23
- * - $current_action: string 'edit'
24
- * - $action_variables: array ['group', 5]
25
  *
26
  * @package BuddyPress Core
27
  */
28
  function bp_core_set_uri_globals() {
29
  global $current_component, $current_action, $action_variables;
30
  global $displayed_user_id;
31
- global $is_member_page, $is_new_friend;
32
  global $bp_unfiltered_uri;
33
  global $bp, $current_blog;
34
 
@@ -37,7 +37,7 @@ function bp_core_set_uri_globals() {
37
  if ( BP_ROOT_BLOG != (int) $current_blog->blog_id )
38
  return false;
39
  }
40
-
41
  if ( strpos( $_SERVER['REQUEST_URI'], 'wp-load.php' ) )
42
  $path = bp_core_referrer();
43
  else
@@ -49,29 +49,21 @@ function bp_core_set_uri_globals() {
49
  // they are still registered in the global $_GET variable */
50
  $noget = substr( $path, 0, strpos( $path, '?' ) );
51
  if ( $noget != '' ) $path = $noget;
52
-
53
- /* Fetch the current URI and explode each part seperated by '/' into an array */
54
  $bp_uri = explode( "/", $path );
55
-
56
- if ( defined( 'BP_ENABLE_MULTIBLOG' ) ) {
 
 
 
 
57
  /* If we are running BuddyPress on any blog, not just a root blog, we need to first
58
  shift off the blog name if we are running a subdirectory install of WPMU. */
59
  if ( $current_blog->path != '/' )
60
  array_shift( $bp_uri );
61
  }
62
 
63
- /* Take empties off the end of complete URI */
64
- if ( empty( $bp_uri[count($bp_uri) - 1] ) )
65
- array_pop( $bp_uri );
66
-
67
- /* Take empties off the start of complete URI */
68
- if ( empty( $bp_uri[0] ) )
69
- array_shift( $bp_uri );
70
-
71
- /* Get total URI segment count */
72
- $bp_uri_count = count( $bp_uri ) - 1;
73
- $is_member_page = false;
74
-
75
  /* Set the indexes, these are incresed by one if we are not on a VHOST install */
76
  $component_index = 0;
77
  $action_index = $component_index + 1;
@@ -91,9 +83,9 @@ function bp_core_set_uri_globals() {
91
  if ( empty( $paths[0] ) )
92
  array_shift( $paths );
93
 
94
- for ( $i = 0; $i < $bp_uri_count; $i++ ) {
95
- if ( in_array( $bp_uri[$i], $paths )) {
96
- unset( $bp_uri[$i] );
97
  }
98
  }
99
 
@@ -101,28 +93,39 @@ function bp_core_set_uri_globals() {
101
  $bp_uri = array_merge( array(), $bp_uri );
102
  $bp_unfiltered_uri = $bp_uri;
103
 
104
- /* Catch a member page and set the current member ID */
105
- if ( $bp_uri[0] == BP_MEMBERS_SLUG || in_array( 'wp-load.php', $bp_uri ) ) {
106
  $is_member_page = true;
107
- $is_root_component = true;
108
-
109
- // We are within a member page, set up user id globals
110
- $displayed_user_id = bp_core_get_displayed_userid( $bp_uri[1] );
111
-
112
- unset($bp_uri[0]);
113
- unset($bp_uri[1]);
 
 
 
 
114
 
115
- // if the get variable 'new' is set this the first visit to a new friends profile.
116
- // this means we need to delete friend acceptance notifications, so we set a flag of is_new_friend.
117
- if ( isset($_GET['new']) ) {
118
- $is_new_friend = 1;
119
- unset($bp_uri[2]);
120
  }
 
 
 
 
121
 
122
- /* Reset the keys by merging with an empty array */
123
- $bp_uri = array_merge( array(), $bp_uri );
124
- }
 
125
 
 
 
 
 
 
126
  if ( !isset($is_root_component) )
127
  $is_root_component = in_array( $bp_uri[0], $bp->root_components );
128
 
@@ -151,7 +154,7 @@ function bp_core_set_uri_globals() {
151
  /* Reset the keys by merging with an empty array */
152
  $action_variables = array_merge( array(), $action_variables );
153
 
154
- //var_dump($current_component, $current_action, $action_variables);
155
  }
156
  add_action( 'plugins_loaded', 'bp_core_set_uri_globals', 3 );
157
 
@@ -195,14 +198,16 @@ function bp_core_do_catch_uri() {
195
  global $bp_no_status_set;
196
  global $wp_query;
197
 
198
- $pages = $bp_path;
199
-
200
  /* Don't hijack any URLs on blog pages */
201
- if ( !$bp_skip_blog_check ) {
202
- if ( bp_is_blog_page() )
203
  return false;
 
 
204
  }
205
-
206
  /* Make sure this is not reported as a 404 */
207
  if ( !$bp_no_status_set ) {
208
  status_header( 200 );
@@ -211,24 +216,15 @@ function bp_core_do_catch_uri() {
211
  if ( $bp->current_component != BP_HOME_BLOG_SLUG )
212
  $wp_query->is_page = true;
213
  }
214
-
215
- if ( is_array( $pages ) ) {
216
- foreach( $pages as $page ) {
217
- if ( file_exists( TEMPLATEPATH . "/" . $page . ".php" ) ) {
218
- load_template( TEMPLATEPATH . "/" . $page . ".php" );
219
- }
220
- }
221
  } else {
222
- if ( file_exists( TEMPLATEPATH . "/" . $pages . ".php" ) ) {
223
- load_template( TEMPLATEPATH . "/" . $pages . ".php" );
224
- } else {
225
- if ( file_exists( TEMPLATEPATH . "/404.php" ) ) {
226
- status_header( 404 );
227
- load_template( TEMPLATEPATH . "/404.php" );
228
- } else {
229
- wp_die( __( '<strong>You do not have any BuddyPress themes installed.</strong><br />Please move "/wp-content/plugins/buddypress/bp-themes/" to "/wp-content/bp-themes/" and refresh this page. You can <a href="http://buddypress.org/extend/themes/">download more themes here</a>.', 'buddypress' ) );
230
- }
231
- }
232
  }
233
  die;
234
  }
@@ -240,20 +236,28 @@ function bp_core_catch_no_access() {
240
  // we are redirecting to an accessable page, so skip this check.
241
  if ( $bp_no_status_set )
242
  return false;
243
-
 
 
 
 
 
 
 
 
244
  // If this user does not exist, redirect to the root domain.
245
  if ( !$bp->displayed_user->id && $bp_unfiltered_uri[0] == BP_MEMBERS_SLUG && isset($bp_unfiltered_uri[1]) )
246
  bp_core_redirect( $bp->root_domain );
247
 
248
  if ( !$bp_path && !bp_is_blog_page() ) {
249
  if ( is_user_logged_in() ) {
250
- wp_redirect( $bp->loggedin_user->domain );
251
  } else {
252
  wp_redirect( site_url( 'wp-login.php?redirect_to=' . site_url() . $_SERVER['REQUEST_URI'] ) );
253
  }
254
  }
255
  }
256
- add_action( 'wp', 'bp_core_catch_no_access', 10 );
257
 
258
  /**
259
  * bp_core_catch_profile_uri()
@@ -269,43 +273,4 @@ function bp_core_catch_profile_uri() {
269
  bp_core_load_template( apply_filters( 'bp_core_template_display_profile', 'profile/index' ) );
270
  }
271
 
272
- function bp_core_force_buddypress_theme( $template ) {
273
- global $is_member_page, $bp;
274
-
275
- $member_theme = get_site_option( 'active-member-theme' );
276
-
277
- if ( empty( $member_theme ) )
278
- $member_theme = 'bpmember';
279
-
280
- if ( $is_member_page ) {
281
-
282
- add_filter( 'theme_root', 'bp_core_filter_buddypress_theme_root' );
283
- add_filter( 'theme_root_uri', 'bp_core_filter_buddypress_theme_root_uri' );
284
-
285
- return $member_theme;
286
- } else {
287
- return $template;
288
- }
289
- }
290
- add_filter( 'template', 'bp_core_force_buddypress_theme', 1, 1 );
291
-
292
- function bp_core_force_buddypress_stylesheet( $stylesheet ) {
293
- global $is_member_page;
294
-
295
- $member_theme = get_site_option( 'active-member-theme' );
296
-
297
- if ( empty( $member_theme ) )
298
- $member_theme = 'bpmember';
299
-
300
- if ( $is_member_page ) {
301
- add_filter( 'theme_root', 'bp_core_filter_buddypress_theme_root' );
302
- add_filter( 'theme_root_uri', 'bp_core_filter_buddypress_theme_root_uri' );
303
-
304
- return $member_theme;
305
- } else {
306
- return $stylesheet;
307
- }
308
- }
309
- add_filter( 'stylesheet', 'bp_core_force_buddypress_stylesheet', 1, 1 );
310
-
311
  ?>
19
  *
20
  * Example:
21
  * - http://domain.com/members/andy/profile/edit/group/5/
22
+ * - $bp->current_component: string 'profile'
23
+ * - $bp->current_action: string 'edit'
24
+ * - $bp->action_variables: array ['group', 5]
25
  *
26
  * @package BuddyPress Core
27
  */
28
  function bp_core_set_uri_globals() {
29
  global $current_component, $current_action, $action_variables;
30
  global $displayed_user_id;
31
+ global $is_member_page;
32
  global $bp_unfiltered_uri;
33
  global $bp, $current_blog;
34
 
37
  if ( BP_ROOT_BLOG != (int) $current_blog->blog_id )
38
  return false;
39
  }
40
+
41
  if ( strpos( $_SERVER['REQUEST_URI'], 'wp-load.php' ) )
42
  $path = bp_core_referrer();
43
  else
49
  // they are still registered in the global $_GET variable */
50
  $noget = substr( $path, 0, strpos( $path, '?' ) );
51
  if ( $noget != '' ) $path = $noget;
52
+
53
+ /* Fetch the current URI and explode each part separated by '/' into an array */
54
  $bp_uri = explode( "/", $path );
55
+
56
+ /* Loop and remove empties */
57
+ foreach ( (array)$bp_uri as $key => $uri_chunk )
58
+ if ( empty( $bp_uri[$key] ) ) unset( $bp_uri[$key] );
59
+
60
+ if ( defined( 'BP_ENABLE_MULTIBLOG' ) || 1 != BP_ROOT_BLOG ) {
61
  /* If we are running BuddyPress on any blog, not just a root blog, we need to first
62
  shift off the blog name if we are running a subdirectory install of WPMU. */
63
  if ( $current_blog->path != '/' )
64
  array_shift( $bp_uri );
65
  }
66
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  /* Set the indexes, these are incresed by one if we are not on a VHOST install */
68
  $component_index = 0;
69
  $action_index = $component_index + 1;
83
  if ( empty( $paths[0] ) )
84
  array_shift( $paths );
85
 
86
+ foreach ( (array)$bp_uri as $key => $uri_chunk ) {
87
+ if ( in_array( $uri_chunk, $paths )) {
88
+ unset( $bp_uri[$key] );
89
  }
90
  }
91
 
93
  $bp_uri = array_merge( array(), $bp_uri );
94
  $bp_unfiltered_uri = $bp_uri;
95
 
96
+ /* If we are under anything with a members slug, set the correct globals */
97
+ if ( $bp_uri[0] == BP_MEMBERS_SLUG ) {
98
  $is_member_page = true;
99
+ $is_root_component = true;
100
+ }
101
+
102
+ /* Catch a member page and set the current member ID */
103
+ if ( !defined( 'BP_ENABLE_ROOT_PROFILES' ) ) {
104
+ if ( ( $bp_uri[0] == BP_MEMBERS_SLUG && !empty( $bp_uri[1] ) ) || in_array( 'wp-load.php', $bp_uri ) ) {
105
+ // We are within a member page, set up user id globals
106
+ $displayed_user_id = bp_core_get_displayed_userid( $bp_uri[1] );
107
+
108
+ unset($bp_uri[0]);
109
+ unset($bp_uri[1]);
110
 
111
+ /* Reset the keys by merging with an empty array */
112
+ $bp_uri = array_merge( array(), $bp_uri );
 
 
 
113
  }
114
+ } else {
115
+ if ( get_userdatabylogin( $bp_uri[0] ) || in_array( 'wp-load.php', $bp_uri ) ) {
116
+ $is_member_page = true;
117
+ $is_root_component = true;
118
 
119
+ // We are within a member page, set up user id globals
120
+ $displayed_user_id = bp_core_get_displayed_userid( $bp_uri[0] );
121
+
122
+ unset($bp_uri[0]);
123
 
124
+ /* Reset the keys by merging with an empty array */
125
+ $bp_uri = array_merge( array(), $bp_uri );
126
+ }
127
+ }
128
+
129
  if ( !isset($is_root_component) )
130
  $is_root_component = in_array( $bp_uri[0], $bp->root_components );
131
 
154
  /* Reset the keys by merging with an empty array */
155
  $action_variables = array_merge( array(), $action_variables );
156
 
157
+ //var_dump($current_component, $current_action, $action_variables); die;
158
  }
159
  add_action( 'plugins_loaded', 'bp_core_set_uri_globals', 3 );
160
 
198
  global $bp_no_status_set;
199
  global $wp_query;
200
 
201
+ $page = $bp_path;
202
+
203
  /* Don't hijack any URLs on blog pages */
204
+ if ( bp_is_blog_page() ) {
205
+ if ( !$bp_skip_blog_check )
206
  return false;
207
+ } else {
208
+ $wp_query->is_home = false;
209
  }
210
+
211
  /* Make sure this is not reported as a 404 */
212
  if ( !$bp_no_status_set ) {
213
  status_header( 200 );
216
  if ( $bp->current_component != BP_HOME_BLOG_SLUG )
217
  $wp_query->is_page = true;
218
  }
219
+
220
+ if ( $located_template = apply_filters( 'bp_located_template', locate_template( array( $page . '.php' ), $page ) ) ) {
221
+ load_template( apply_filters( 'bp_load_template', $located_template ) );
 
 
 
 
222
  } else {
223
+ if ( $located_template = locate_template( array( '404.php' ) ) ) {
224
+ status_header( 404 );
225
+ load_template( $located_template );
226
+ } else
227
+ bp_core_redirect( $bp->root_domain );
 
 
 
 
 
228
  }
229
  die;
230
  }
236
  // we are redirecting to an accessable page, so skip this check.
237
  if ( $bp_no_status_set )
238
  return false;
239
+
240
+ /* If this user has been marked as a spammer and the logged in user is not a site admin, redirect. */
241
+ if ( isset( $bp->displayed_user->id ) && bp_core_is_user_spammer( $bp->displayed_user->id ) ) {
242
+ if ( !is_site_admin() )
243
+ bp_core_redirect( $bp->root_domain );
244
+ else
245
+ bp_core_add_message( __( 'This user has been marked as a spammer. Only site admins can view this profile.', 'buddypress' ), 'error' );
246
+ }
247
+
248
  // If this user does not exist, redirect to the root domain.
249
  if ( !$bp->displayed_user->id && $bp_unfiltered_uri[0] == BP_MEMBERS_SLUG && isset($bp_unfiltered_uri[1]) )
250
  bp_core_redirect( $bp->root_domain );
251
 
252
  if ( !$bp_path && !bp_is_blog_page() ) {
253
  if ( is_user_logged_in() ) {
254
+ wp_redirect( $bp->root_domain );
255
  } else {
256
  wp_redirect( site_url( 'wp-login.php?redirect_to=' . site_url() . $_SERVER['REQUEST_URI'] ) );
257
  }
258
  }
259
  }
260
+ add_action( 'wp', 'bp_core_catch_no_access' );
261
 
262
  /**
263
  * bp_core_catch_profile_uri()
273
  bp_core_load_template( apply_filters( 'bp_core_template_display_profile', 'profile/index' ) );
274
  }
275
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
  ?>
bp-core/bp-core-classes.php CHANGED
@@ -25,10 +25,7 @@ class BP_Core_User {
25
 
26
  var $last_active;
27
  var $profile_last_updated;
28
-
29
- var $status;
30
- var $status_last_updated;
31
-
32
  /* Extras */
33
  var $total_friends;
34
  var $total_blogs;
@@ -42,7 +39,7 @@ class BP_Core_User {
42
  if ( $populate_extras )
43
  $this->populate_extras();
44
  }
45
- }
46
 
47
  /**
48
  * populate()
@@ -55,20 +52,20 @@ class BP_Core_User {
55
  * @uses bp_core_get_userlink() Returns a HTML formatted link for a user with the user's full name as the link text
56
  * @uses bp_core_get_user_email() Returns the email address for the user based on user ID
57
  * @uses get_usermeta() WordPress function returns the value of passed usermeta name from usermeta table
58
- * @uses bp_core_get_avatar() Returns HTML formatted avatar for a user
59
  * @uses bp_profile_last_updated_date() Returns the last updated date for a user.
60
  */
61
  function populate() {
62
  $this->user_url = bp_core_get_userurl( $this->id );
63
  $this->user_link = bp_core_get_userlink( $this->id );
64
 
65
- $this->fullname = bp_core_get_user_displayname( $this->id );
66
- $this->email = bp_core_get_user_email( $this->id );
67
- $this->last_active = bp_core_get_last_activity( get_usermeta( $this->id, 'last_activity' ), __( 'active %s ago', 'buddypress' ) );
68
 
69
- $this->avatar = bp_core_get_avatar( $this->id, 2 );
70
- $this->avatar_thumb = bp_core_get_avatar( $this->id, 1 );
71
- $this->avatar_mini = bp_core_get_avatar( $this->id, 1, 25, 25, false );
72
  }
73
 
74
  function populate_extras() {
@@ -244,8 +241,8 @@ class BP_Core_User {
244
 
245
  like_escape($search_terms);
246
 
247
- $total_users_sql = apply_filters( 'bp_core_search_users_count_sql', "SELECT DISTINCT count(u.ID) as user_id FROM " . CUSTOM_USER_TABLE . " u LEFT JOIN {$bp->profile->table_name_data} pd ON u.ID = pd.user_id WHERE pd.value LIKE '%%$search_terms%%' ORDER BY pd.value ASC", $search_terms );
248
- $paged_users_sql = apply_filters( 'bp_core_search_users_sql', "SELECT DISTINCT u.ID as user_id FROM " . CUSTOM_USER_TABLE . " u LEFT JOIN {$bp->profile->table_name_data} pd ON u.ID = pd.user_id WHERE pd.value LIKE '%%$search_terms%%' ORDER BY pd.value ASC{$pag_sql}", $search_terms, $pag_sql );
249
 
250
  $total_users = $wpdb->get_var( $total_users_sql );
251
  $paged_users = $wpdb->get_results( $paged_users_sql );
@@ -350,7 +347,7 @@ class BP_Core_Notification {
350
  global $wpdb, $bp;
351
 
352
  if ( $component_action )
353
- $component_action_sql = $wpdb->prepare( "AND component_action = %s", $compoennt_action );
354
 
355
  if ( $secondary_item_id )
356
  $secondary_item_sql = $wpdb->prepare( "AND secondary_item_id = %d", $secondary_item_id );
25
 
26
  var $last_active;
27
  var $profile_last_updated;
28
+
 
 
 
29
  /* Extras */
30
  var $total_friends;
31
  var $total_blogs;
39
  if ( $populate_extras )
40
  $this->populate_extras();
41
  }
42
+ }
43
 
44
  /**
45
  * populate()
52
  * @uses bp_core_get_userlink() Returns a HTML formatted link for a user with the user's full name as the link text
53
  * @uses bp_core_get_user_email() Returns the email address for the user based on user ID
54
  * @uses get_usermeta() WordPress function returns the value of passed usermeta name from usermeta table
55
+ * @uses bp_core_fetch_avatar() Returns HTML formatted avatar for a user
56
  * @uses bp_profile_last_updated_date() Returns the last updated date for a user.
57
  */
58
  function populate() {
59
  $this->user_url = bp_core_get_userurl( $this->id );
60
  $this->user_link = bp_core_get_userlink( $this->id );
61
 
62
+ $this->fullname = attribute_escape( bp_core_get_user_displayname( $this->id ) );
63
+ $this->email = attribute_escape( bp_core_get_user_email( $this->id ) );
64
+ $this->last_active = attribute_escape( bp_core_get_last_activity( get_usermeta( $this->id, 'last_activity' ), __( 'active %s ago', 'buddypress' ) ) );
65
 
66
+ $this->avatar = bp_core_fetch_avatar( array( 'item_id' => $this->id, 'type' => 'full' ) );
67
+ $this->avatar_thumb = bp_core_fetch_avatar( array( 'item_id' => $this->id, 'type' => 'thumb' ) );
68
+ $this->avatar_mini = bp_core_fetch_avatar( array( 'item_id' => $this->id, 'type' => 'thumb', 'width' => 30, 'height' => 30 ) );
69
  }
70
 
71
  function populate_extras() {
241
 
242
  like_escape($search_terms);
243
 
244
+ $total_users_sql = apply_filters( 'bp_core_search_users_count_sql', "SELECT DISTINCT count(u.ID) as user_id FROM " . CUSTOM_USER_TABLE . " u LEFT JOIN {$bp->profile->table_name_data} pd ON u.ID = pd.user_id WHERE u.spam = 0 AND u.deleted = 0 AND u.user_status = 0 AND pd.value LIKE '%%$search_terms%%' ORDER BY pd.value ASC", $search_terms );
245
+ $paged_users_sql = apply_filters( 'bp_core_search_users_sql', "SELECT DISTINCT u.ID as user_id FROM " . CUSTOM_USER_TABLE . " u LEFT JOIN {$bp->profile->table_name_data} pd ON u.ID = pd.user_id WHERE u.spam = 0 AND u.deleted = 0 AND u.user_status = 0 AND pd.value LIKE '%%$search_terms%%' ORDER BY pd.value ASC{$pag_sql}", $search_terms, $pag_sql );
246
 
247
  $total_users = $wpdb->get_var( $total_users_sql );
248
  $paged_users = $wpdb->get_results( $paged_users_sql );
347
  global $wpdb, $bp;
348
 
349
  if ( $component_action )
350
+ $component_action_sql = $wpdb->prepare( "AND component_action = %s", $component_action );
351
 
352
  if ( $secondary_item_id )
353
  $secondary_item_sql = $wpdb->prepare( "AND secondary_item_id = %d", $secondary_item_id );
bp-core/bp-core-cssjs.php CHANGED
@@ -1,192 +1,192 @@
1
  <?php
 
2
  /**
3
- * bp_core_add_js()
4
  *
5
- * Add the JS required by the core, as well as shared JS used by other components.
6
- * [TODO] This needs to use wp_enqueue_script()
7
  *
8
  * @package BuddyPress Core
9
  * @uses get_option() Selects a site setting from the DB.
10
  */
11
- function bp_core_add_js() {
12
- wp_enqueue_script( 'jquery' );
13
- wp_enqueue_script( 'jquery-livequery-pack', BP_PLUGIN_URL . '/bp-core/js/jquery/jquery.livequery.pack.js', 'jquery' );
14
- wp_enqueue_script( 'bp-general-js', BP_PLUGIN_URL . '/bp-core/js/general.js' );
 
 
 
 
 
 
 
 
 
 
 
15
  }
16
- add_action( 'wp', 'bp_core_add_js' );
17
- add_action( 'admin_menu', 'bp_core_add_js' );
18
 
19
  /**
20
- * bp_core_add_ajax_js()
21
  *
22
- * Add the reference to ajaxurl used by all ajax functionality in BuddyPress.
23
  *
24
  * @package BuddyPress Core
25
  * @uses get_option() Selects a site setting from the DB.
26
  */
27
- function bp_core_add_ajax_js() {
28
- global $bp;
29
-
30
- echo
31
- '<script type="text/javascript">var ajaxurl = "' . $bp->root_domain . str_replace( 'index.php', 'wp-load.php', $_SERVER['SCRIPT_NAME'] ) . '";</script>
32
- ';
33
  }
34
- add_action( 'wp_head', 'bp_core_add_ajax_js' );
 
35
 
36
  /**
37
- * bp_core_add_css()
38
  *
39
- * Add the CSS required by all BP components, regardless of the current theme.
40
  *
41
  * @package BuddyPress Core
42
- * @uses get_option() Selects a site setting from the DB.
43
  */
44
- function bp_core_add_css() {
45
- // Enable a sitewide CSS file that will apply styles to both the home blog theme
46
- // and the member theme.
47
- if ( file_exists( WP_CONTENT_DIR . '/themes/' . get_blog_option( 1, 'stylesheet' ) . '/css/site-wide.css' ) )
48
- wp_enqueue_style( 'site-wide-styles', WP_CONTENT_URL . '/themes/' . get_blog_option( 1, 'stylesheet' ) . '/css/site-wide.css' );
 
 
 
 
 
 
49
 
50
- wp_print_styles();
 
 
 
51
  }
52
- add_action( 'wp_head', 'bp_core_add_css', 2 );
53
 
54
  /**
55
- * bp_core_admin_bar_css()
56
  *
57
- * Add the CSS required for the global admin bar.
58
  *
59
  * @package BuddyPress Core
60
  */
61
- function bp_core_admin_bar_css() {
62
- if ( defined( 'BP_DISABLE_ADMIN_BAR') )
63
- return false;
64
-
65
- if ( is_user_logged_in() || ( !(int)get_site_option( 'hide-loggedout-adminbar' ) && !is_user_logged_in() ) ) {
66
- wp_enqueue_style( 'bp-admin-bar', BP_PLUGIN_URL . '/bp-core/css/admin-bar.css' );
67
-
68
- if ( 'rtl' == get_bloginfo('text_direction') && file_exists( BP_PLUGIN_DIR . '/bp-core/css/admin-bar-rtl.css' ) )
69
- wp_enqueue_style( 'bp-admin-bar-rtl', BP_PLUGIN_URL . '/bp-core/css/admin-bar-rtl.css' );
70
- }
71
- wp_print_styles();
72
  }
73
- add_action( 'wp_head', 'bp_core_admin_bar_css', 1 );
74
 
75
  /**
76
- * bp_core_add_structure_css()
77
  *
78
- * Add the CSS to add layout structure to BP pages in any WordPress theme.
79
  *
80
  * @package BuddyPress Core
81
- * @uses get_option() Selects a site setting from the DB.
82
  */
83
- function bp_core_add_structure_css() {
84
- /* Enqueue the structure CSS file to give basic positional formatting for components */
85
- wp_enqueue_style( 'bp-core-structure', BP_PLUGIN_URL . '/bp-core/css/structure.css' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  }
87
- add_action( 'bp_styles', 'bp_core_add_structure_css' );
88
 
89
  /**
90
- * bp_core_add_admin_js()
91
  *
92
- * Add the JS needed for all components in the admin area.
93
  *
94
  * @package BuddyPress Core
95
- * @uses get_option() Selects a site setting from the DB.
96
  */
97
- function bp_core_add_admin_js() {
98
- if ( false !== strpos( $_GET['page'], 'bp-core' ) ) {
99
- wp_enqueue_script( 'bp-account-admin-js', BP_PLUGIN_URL . '/bp-core/js/account-admin.js' );
100
- }
101
-
102
- if ( false !== strpos( $_GET['page'], 'bp-core/admin-mods' ) ) {
103
- wp_enqueue_script('password-strength-meter');
104
- }
 
 
 
 
 
 
 
 
 
105
  }
106
- add_action( 'admin_menu', 'bp_core_add_admin_js' );
107
 
108
  /**
109
- * bp_core_add_admin_css()
110
  *
111
- * Add the CSS needed for all components in the admin area.
112
  *
113
  * @package BuddyPress Core
114
- * @uses get_option() Selects a site setting from the DB.
115
  */
116
- function bp_core_add_admin_css() {
117
- if ( defined( 'BP_DISABLE_ADMIN_BAR') )
118
- return false;
119
-
120
- wp_enqueue_style( 'bp-admin-bar', BP_PLUGIN_URL . '/bp-core/css/admin-bar.css' );
 
121
  }
122
- add_action( 'admin_menu', 'bp_core_add_admin_css' );
123
 
124
  /**
125
- * bp_core_add_cropper_js()
126
  *
127
- * Adds the JS needed for general avatar cropping.
128
  *
129
  * @package BuddyPress Core
130
  */
131
- function bp_core_add_cropper_js() {
132
- ?>
133
- <script type="text/javascript">
134
- function cropAndContinue() {
135
- jQuery('#avatar_v1').slideUp();
136
- jQuery('#avatar_v2').slideDown('normal', function(){
137
- v2Cropper();
138
- });
139
- }
140
-
141
- function v1Cropper() {
142
- v1Crop = new Cropper.ImgWithPreview(
143
- 'crop-v1-img',
144
- {
145
- ratioDim: { x: <?php echo round(CORE_AVATAR_V1_W / CORE_AVATAR_V1_H, 5); ?>, y: 1 },
146
- minWidth: <?php echo CORE_AVATAR_V1_W; ?>,
147
- minHeight: <?php echo CORE_AVATAR_V1_H; ?>,
148
- prevWidth: <?php echo CORE_AVATAR_V1_W; ?>,
149
- prevHeight: <?php echo CORE_AVATAR_V1_H; ?>,
150
- onEndCrop: onEndCropv1,
151
- previewWrap: 'crop-preview-v1'
152
- }
153
- );
154
- }
155
-
156
- function onEndCropv1(coords, dimensions) {
157
- jQuery('#v1_x1').val(coords.x1);
158
- jQuery('#v1_y1').val(coords.y1);
159
- jQuery('#v1_x2').val(coords.x2);
160
- jQuery('#v1_y2').val(coords.y2);
161
- jQuery('#v1_w').val(dimensions.width);
162
- jQuery('#v1_h').val(dimensions.height);
163
- }
164
-
165
- <?php if ( CORE_AVATAR_V2_W !== false && CORE_AVATAR_V2_H !== false ) { ?>
166
- function v2Cropper() {
167
- v1Crop = new Cropper.ImgWithPreview(
168
- 'crop-v2-img',
169
- {
170
- ratioDim: { x: <?php echo round(CORE_AVATAR_V2_W / CORE_AVATAR_V2_H, 5); ?>, y: 1 },
171
- minWidth: <?php echo CORE_AVATAR_V2_W; ?>,
172
- minHeight: <?php echo CORE_AVATAR_V2_H; ?>,
173
- prevWidth: <?php echo CORE_AVATAR_V2_W; ?>,
174
- prevHeight: <?php echo CORE_AVATAR_V2_H; ?>,
175
- onEndCrop: onEndCropv2,
176
- previewWrap: 'crop-preview-v2'
177
- }
178
- );
179
- }
180
- <?php } ?>
181
-
182
- function onEndCropv2(coords, dimensions) {
183
- jQuery('#v2_x1').val(coords.x1);
184
- jQuery('#v2_y1').val(coords.y1);
185
- jQuery('#v2_x2').val(coords.x2);
186
- jQuery('#v2_y2').val(coords.y2);
187
- jQuery('#v2_w').val(dimensions.width);
188
- jQuery('#v2_h').val(dimensions.height);
189
- }
190
- </script>
191
- <?php
192
- }
1
  <?php
2
+
3
  /**
4
+ * bp_core_add_admin_bar_css()
5
  *
6
+ * Add the CSS needed for the admin bar on blogs (other than the root) and in the admin area.
 
7
  *
8
  * @package BuddyPress Core
9
  * @uses get_option() Selects a site setting from the DB.
10
  */
11
+ function bp_core_add_admin_bar_css() {
12
+ global $current_blog;
13
+
14
+ if ( defined( 'BP_DISABLE_ADMIN_BAR' ) )
15
+ return false;
16
+
17
+ /* Fetch the admin bar css from the active theme location */
18
+ if ( file_exists( WP_CONTENT_DIR . '/themes/' . get_blog_option( BP_ROOT_BLOG, 'stylesheet' ) . '/_inc/css/adminbar.css' ) )
19
+ $admin_bar_css = WP_CONTENT_URL . '/themes/' . get_blog_option( BP_ROOT_BLOG, 'stylesheet' ) . '/_inc/css/adminbar.css';
20
+ else if ( file_exists( WP_CONTENT_DIR . '/' . get_blog_option( BP_ROOT_BLOG, 'template' ) . '/_inc/css/adminbar.css' ) )
21
+ $admin_bar_css = WP_CONTENT_URL . '/themes/' . get_blog_option( BP_ROOT_BLOG, 'template' ) . '/_inc/css/adminbar.css';
22
+ else
23
+ $admin_bar_css = BP_PLUGIN_URL . '/bp-core/deprecated/css/admin-bar.css';
24
+
25
+ wp_enqueue_style( 'bp-admin-bar', apply_filters( 'bp_core_admin_bar_css', $admin_bar_css ) );
26
  }
27
+ add_action( 'admin_menu', 'bp_core_add_admin_bar_css' );
28
+ add_action( 'template_redirect', 'bp_core_add_admin_bar_css' );
29
 
30
  /**
31
+ * bp_core_add_admin_bar_js()
32
  *
33
+ * Add the minor JS needed for the admin bar.
34
  *
35
  * @package BuddyPress Core
36
  * @uses get_option() Selects a site setting from the DB.
37
  */
38
+ function bp_core_add_admin_bar_js() {
39
+ wp_enqueue_script( 'bp-admin-bar-js', BP_PLUGIN_URL . '/bp-core/js/admin-bar.js', array( 'jquery' ) );
 
 
 
 
40
  }
41
+ add_action( 'admin_menu', 'bp_core_add_admin_bar_js' );
42
+ add_action( 'wp', 'bp_core_add_admin_bar_js' );
43
 
44
  /**
45
+ * bp_core_admin_menu_icon_css()
46
  *
47
+ * Add a hover-able icon to the "BuddyPress" wp-admin area menu.
48
  *
49
  * @package BuddyPress Core
 
50
  */
51
+ function bp_core_admin_menu_icon_css() {
52
+ global $bp;
53
+ ?>
54
+ <style type="text/css">
55
+ ul#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image a { background-image: url( <?php echo BP_PLUGIN_URL . '/bp-core/images/admin_menu_icon.png' ?> ) !important; background-position: -1px -32px; }
56
+ ul#adminmenu li.toplevel_page_bp-general-settings:hover .wp-menu-image a { background-position: -1px 0; }
57
+ ul#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image a img { display: none; }
58
+ </style>
59
+ <?php
60
+ }
61
+ add_action( 'admin_head', 'bp_core_admin_menu_icon_css' );
62
 
63
+ function bp_core_confirmation_js() {
64
+ ?>
65
+ <script type="text/javascript"> jQuery(document).ready( function() { jQuery("a.confirm").click( function() { if ( confirm( '<?php _e( 'Are you sure?', 'buddypress' ) ?>' ) ) return true; else return false; }); });</script>
66
+ <?php
67
  }
68
+ add_action( 'wp_head', 'bp_core_confirmation_js', 100 );
69
 
70
  /**
71
+ * bp_core_add_jquery_cropper()
72
  *
73
+ * Makes sure the jQuery jCrop library is loaded.
74
  *
75
  * @package BuddyPress Core
76
  */
77
+ function bp_core_add_jquery_cropper() {
78
+ wp_enqueue_script( 'jcrop', array( 'jquery' ) );
79
+ add_action( 'wp_head', 'bp_core_add_cropper_inline_js' );
80
+ add_action( 'wp_head', 'bp_core_add_cropper_inline_css' );
 
 
 
 
 
 
 
81
  }
 
82
 
83
  /**
84
+ * bp_core_add_cropper_inline_js()
85
  *
86
+ * Adds the inline JS needed for the cropper to work on a per-page basis.
87
  *
88
  * @package BuddyPress Core
 
89
  */
90
+ function bp_core_add_cropper_inline_js() {
91
+ global $bp;
92
+
93
+ $image = apply_filters( 'bp_inline_cropper_image', getimagesize( $bp->avatar_admin->image->dir ) );
94
+
95
+ $aspect_ratio = 1;
96
+
97
+ /* Calculate Aspect Ratio */
98
+ if ( (int) constant( 'BP_AVATAR_FULL_HEIGHT' ) && ( (int) constant( 'BP_AVATAR_FULL_WIDTH' ) != (int) constant( 'BP_AVATAR_FULL_HEIGHT' ) ) )
99
+ $aspect_ratio = (int) constant( 'BP_AVATAR_FULL_WIDTH' ) / (int) constant( 'BP_AVATAR_FULL_HEIGHT' );
100
+ ?>
101
+ <script type="text/javascript">
102
+ jQuery(window).load( function(){
103
+ jQuery('#avatar-to-crop').Jcrop({
104
+ onChange: showPreview,
105
+ onSelect: showPreview,
106
+ onSelect: updateCoords,
107
+ aspectRatio: <?php echo $aspect_ratio ?>,
108
+ setSelect: [ 50, 50, 200, 200 ]
109
+ });
110
+ });
111
+
112
+ function updateCoords(c) {
113
+ jQuery('#x').val(c.x);
114
+ jQuery('#y').val(c.y);
115
+ jQuery('#w').val(c.w);
116
+ jQuery('#h').val(c.h);
117
+ };
118
+
119
+ function showPreview(coords) {
120
+ if ( parseInt(coords.w) > 0 ) {
121
+ var rx = <?php echo (int) constant( 'BP_AVATAR_FULL_WIDTH' ) ?> / coords.w;
122
+ var ry = <?php echo (int) constant( 'BP_AVATAR_FULL_HEIGHT' ) ?> / coords.h;
123
+
124
+ jQuery('#avatar-crop-preview').css({
125
+ width: Math.round(rx * <?php echo $image[0] ?>) + 'px',
126
+ height: Math.round(ry * <?php echo $image[1] ?>) + 'px',
127
+ marginLeft: '-' + Math.round(rx * coords.x) + 'px',
128
+ marginTop: '-' + Math.round(ry * coords.y) + 'px'
129
+ });
130
+ }
131
+ }
132
+ </script>
133
+ <?php
134
  }
 
135
 
136
  /**
137
+ * bp_core_add_cropper_inline_css()
138
  *
139
+ * Adds the inline CSS needed for the cropper to work on a per-page basis.
140
  *
141
  * @package BuddyPress Core
 
142
  */
143
+ function bp_core_add_cropper_inline_css() {
144
+ global $bp;
145
+ ?>
146
+ <style type="text/css">
147
+ .jcrop-holder { text-align: left; }
148
+ .jcrop-vline, .jcrop-hline { font-size: 0; position: absolute; background: white top left repeat url( <?php echo BP_PLUGIN_URL ?>/bp-core/images/Jcrop.gif ); }
149
+ .jcrop-vline { height: 100%; width: 1px !important; }
150
+ .jcrop-hline { width: 100%; height: 1px !important; }
151
+ .jcrop-handle { font-size: 1px; width: 7px !important; height: 7px !important; border: 1px #eee solid; background-color: #333; *width: 9px; *height: 9px; }
152
+ .jcrop-tracker { width: 100%; height: 100%; }
153
+ .custom .jcrop-vline, .custom .jcrop-hline { background: yellow; }
154
+ .custom .jcrop-handle { border-color: black; background-color: #C7BB00; -moz-border-radius: 3px; -webkit-border-radius: 3px; }
155
+ #avatar-crop-pane { width: <?php echo BP_AVATAR_FULL_WIDTH ?>px; height: <?php echo BP_AVATAR_FULL_HEIGHT ?>px; overflow: hidden; }
156
+ #avatar-crop-submit { margin: 20px 0; }
157
+ #avatar-upload-form img { border: none !important; }
158
+ </style>
159
+ <?php
160
  }
 
161
 
162
  /**
163
+ * bp_core_add_ajax_url_js()
164
  *
165
+ * Adds AJAX target URL so themes can access the WordPress AJAX functionality.
166
  *
167
  * @package BuddyPress Core
 
168
  */
169
+ function bp_core_add_ajax_url_js() {
170
+ global $bp;
171
+
172
+ echo
173
+ '<script type="text/javascript">var ajaxurl = "' . $bp->root_domain . str_replace( 'index.php', 'wp-load.php', $_SERVER['SCRIPT_NAME'] ) . '";</script>
174
+ ';
175
  }
176
+ add_action( 'wp_head', 'bp_core_add_ajax_url_js' );
177
 
178
  /**
179
+ * bp_core_override_adminbar_css()
180
  *
181
+ * Overrides the theme's admin bar CSS to hide the adminbar if disabled.
182
  *
183
  * @package BuddyPress Core
184
  */
185
+ function bp_core_override_adminbar_css() {
186
+ if ( defined( 'BP_DISABLE_ADMIN_BAR' ) || ( get_site_option( 'hide-loggedout-adminbar' ) && !is_user_logged_in() ) ) {
187
+ ?>
188
+ <style type="text/css">body { padding-top: 0 !important; } #wp-admin-bar { display: none; }</style>
189
+ <?php }
190
+ }
191
+ add_action( 'wp_footer', 'bp_core_override_adminbar_css' );
192
+ ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-core/bp-core-notifications.php CHANGED
@@ -59,12 +59,9 @@ function bp_core_get_notifications_for_user( $user_id ) {
59
 
60
  if ( $action_item_count < 1 )
61
  continue;
62
-
63
- $item_id = ( 1 == $action_item_count ) ? $component_action_items[0]->item_id : false;
64
- $secondary_item_id = ( 1 == $action_item_count ) ? $component_action_items[0]->secondary_item_id : false;
65
-
66
  if ( function_exists( $bp->{$component_name}->format_notification_function ) ) {
67
- $renderable[] = call_user_func( $bp->{$component_name}->format_notification_function, $component_action_name, $item_id, $secondary_item_id, $action_item_count );
68
  }
69
  }
70
  }
59
 
60
  if ( $action_item_count < 1 )
61
  continue;
62
+
 
 
 
63
  if ( function_exists( $bp->{$component_name}->format_notification_function ) ) {
64
+ $renderable[] = call_user_func( $bp->{$component_name}->format_notification_function, $component_action_name, $component_action_items[0]->item_id, $component_action_items[0]->secondary_item_id, $action_item_count );
65
  }
66
  }
67
  }
bp-core/bp-core-settings.php CHANGED
@@ -1,16 +1,28 @@
1
  <?php
 
 
 
 
2
  function bp_core_add_settings_nav() {
3
  global $bp;
 
 
 
 
 
 
 
4
 
5
  /* Add the settings navigation item */
6
- bp_core_add_nav_item( __('Settings', 'buddypress'), 'settings', false, false );
7
- bp_core_add_nav_default( 'settings', 'bp_core_screen_general_settings', 'general', false );
 
8
 
9
- bp_core_add_subnav_item( 'settings', 'general', __('General', 'buddypress'), $bp->loggedin_user->domain . 'settings/', 'bp_core_screen_general_settings', false, bp_is_home() );
10
- bp_core_add_subnav_item( 'settings', 'notifications', __('Notifications', 'buddypress'), $bp->loggedin_user->domain . 'settings/', 'bp_core_screen_notification_settings', false, bp_is_home() );
11
 
12
- if ( !is_site_admin() )
13
- bp_core_add_subnav_item( 'settings', 'delete-account', __('Delete Account', 'buddypress'), $bp->loggedin_user->domain . 'settings/', 'bp_core_screen_delete_account', false, bp_is_home() );
14
  }
15
  add_action( 'wp', 'bp_core_add_settings_nav', 2 );
16
  add_action( 'admin_menu', 'bp_core_add_settings_nav', 2 );
@@ -23,21 +35,21 @@ function bp_core_screen_general_settings() {
23
  $bp_settings_updated = false;
24
  $pass_error = false;
25
 
26
- if ( isset($_POST['submit']) && check_admin_referer('bp_settings_general') ) {
 
 
27
  require_once( WPINC . '/registration.php' );
28
 
29
  // Form has been submitted and nonce checks out, lets do it.
30
 
31
- if ( $_POST['email'] != '' ) {
32
- $current_user->user_email = wp_specialchars( trim( $_POST['email'] ));
33
- }
34
 
35
  if ( $_POST['pass1'] != '' && $_POST['pass2'] != '' ) {
36
- if ( $_POST['pass1'] == $_POST['pass2'] && !strpos( " " . $_POST['pass1'], "\\" ) ) {
37
  $current_user->user_pass = $_POST['pass1'];
38
- } else {
39
  $pass_error = true;
40
- }
41
  } else if ( empty( $_POST['pass1'] ) && !empty( $_POST['pass2'] ) || !empty( $_POST['pass1'] ) && empty( $_POST['pass2'] ) ) {
42
  $pass_error = true;
43
  } else {
@@ -73,15 +85,15 @@ function bp_core_screen_general_settings_content() {
73
  </div>
74
  <?php } ?>
75
 
76
- <form action="<?php echo $bp->loggedin_user->domain . 'settings/general' ?>" method="post" id="settings-form">
77
  <label for="email"><?php _e( 'Account Email', 'buddypress' ) ?></label>
78
  <input type="text" name="email" id="email" value="<?php echo attribute_escape( $current_user->user_email ); ?>" class="settings-input" />
79
 
80
  <label for="pass1"><?php _e( 'Change Password <span>(leave blank for no change)</span>', 'buddypress' ) ?></label>
81
- <input type="password" name="pass1" id="pass1" size="16" value="" class="settings-input small" /> &nbsp;<?php _e( 'New Password', 'buddypress' ) ?>
82
  <input type="password" name="pass2" id="pass2" size="16" value="" class="settings-input small" /> &nbsp;<?php _e( 'Repeat New Password', 'buddypress' ) ?>
83
 
84
- <p><input type="submit" name="submit" value="<?php _e( 'Save Changes', 'buddypress' ) ?>" id="submit" class="auto"/></p>
85
  <?php wp_nonce_field('bp_settings_general') ?>
86
  </form>
87
  <?php
@@ -94,7 +106,9 @@ function bp_core_screen_notification_settings() {
94
 
95
  $bp_settings_updated = false;
96
 
97
- if ( $_POST['submit'] && check_admin_referer('bp_settings_notifications') ) {
 
 
98
  if ( $_POST['notifications'] ) {
99
  foreach ( $_POST['notifications'] as $key => $value ) {
100
  update_usermeta( (int)$current_user->id, $key, $value );
@@ -142,7 +156,9 @@ function bp_core_screen_notification_settings_content() {
142
  function bp_core_screen_delete_account() {
143
  global $current_user, $bp_settings_updated, $pass_error;
144
 
145
- if ( isset( $_POST['delete-account-button'] ) && check_admin_referer('delete-account') ) {
 
 
146
  // delete the users account
147
  if ( bp_core_delete_account() )
148
  bp_core_redirect( site_url() );
@@ -151,7 +167,9 @@ function bp_core_screen_delete_account() {
151
  $bp_settings_updated = false;
152
  $pass_error = false;
153
 
154
- if ( isset($_POST['submit']) && check_admin_referer('bp_settings_general') ) {
 
 
155
  require_once( WPINC . '/registration.php' );
156
 
157
  // Form has been submitted and nonce checks out, lets do it.
1
  <?php
2
+
3
+ if ( !defined( 'BP_SETTINGS_SLUG' ) )
4
+ define( 'BP_SETTINGS_SLUG', 'settings' );
5
+
6
  function bp_core_add_settings_nav() {
7
  global $bp;
8
+
9
+ /* Set up settings as a sudo-component for identification and nav selection */
10
+ $bp->settings->id = 'settings';
11
+ $bp->settings->slug = BP_SETTINGS_SLUG;
12
+
13
+ /* Register this in the active components array */
14
+ $bp->active_components[$bp->settings->slug] = $bp->settings->id;
15
 
16
  /* Add the settings navigation item */
17
+ bp_core_new_nav_item( array( 'name' => __('Settings', 'buddypress'), 'slug' => $bp->settings->slug, 'position' => 100, 'show_for_displayed_user' => false, 'screen_function' => 'bp_core_screen_general_settings', 'default_subnav_slug' => 'general' ) );
18
+
19
+ $settings_link = $bp->loggedin_user->domain . 'settings/';
20
 
21
+ bp_core_new_subnav_item( array( 'name' => __( 'General', 'buddypress' ), 'slug' => 'general', 'parent_url' => $settings_link, 'parent_slug' => $bp->settings->slug, 'screen_function' => 'bp_core_screen_general_settings', 'position' => 10, 'user_has_access' => bp_is_home() ) );
22
+ bp_core_new_subnav_item( array( 'name' => __( 'Notifications', 'buddypress' ), 'slug' => 'notifications', 'parent_url' => $settings_link, 'parent_slug' => $bp->settings->slug, 'screen_function' => 'bp_core_screen_notification_settings', 'position' => 20, 'user_has_access' => bp_is_home() ) );
23
 
24
+ if ( !is_site_admin() && !(int) get_site_option( 'bp-disable-account-deletion' ) )
25
+ bp_core_new_subnav_item( array( 'name' => __( 'Delete Account', 'buddypress' ), 'slug' => 'delete-account', 'parent_url' => $settings_link, 'parent_slug' => $bp->settings->slug, 'screen_function' => 'bp_core_screen_delete_account', 'position' => 90, 'user_has_access' => bp_is_home() ) );
26
  }
27
  add_action( 'wp', 'bp_core_add_settings_nav', 2 );
28
  add_action( 'admin_menu', 'bp_core_add_settings_nav', 2 );
35
  $bp_settings_updated = false;
36
  $pass_error = false;
37
 
38
+ if ( isset($_POST['submit']) ) {
39
+ check_admin_referer('bp_settings_general');
40
+
41
  require_once( WPINC . '/registration.php' );
42
 
43
  // Form has been submitted and nonce checks out, lets do it.
44
 
45
+ if ( $_POST['email'] != '' )
46
+ $current_user->user_email = wp_specialchars( trim( $_POST['email'] ) );
 
47
 
48
  if ( $_POST['pass1'] != '' && $_POST['pass2'] != '' ) {
49
+ if ( $_POST['pass1'] == $_POST['pass2'] && !strpos( " " . $_POST['pass1'], "\\" ) )
50
  $current_user->user_pass = $_POST['pass1'];
51
+ else
52
  $pass_error = true;
 
53
  } else if ( empty( $_POST['pass1'] ) && !empty( $_POST['pass2'] ) || !empty( $_POST['pass1'] ) && empty( $_POST['pass2'] ) ) {
54
  $pass_error = true;
55
  } else {
85
  </div>
86
  <?php } ?>
87
 
88
+ <form action="<?php echo $bp->loggedin_user->domain . 'settings/general' ?>" method="post" class="standard-form" id="settings-form">
89
  <label for="email"><?php _e( 'Account Email', 'buddypress' ) ?></label>
90
  <input type="text" name="email" id="email" value="<?php echo attribute_escape( $current_user->user_email ); ?>" class="settings-input" />
91
 
92
  <label for="pass1"><?php _e( 'Change Password <span>(leave blank for no change)</span>', 'buddypress' ) ?></label>
93
+ <input type="password" name="pass1" id="pass1" size="16" value="" class="settings-input small" /> &nbsp;<?php _e( 'New Password', 'buddypress' ) ?><br />
94
  <input type="password" name="pass2" id="pass2" size="16" value="" class="settings-input small" /> &nbsp;<?php _e( 'Repeat New Password', 'buddypress' ) ?>
95
 
96
+ <p class="submit"><input type="submit" name="submit" value="<?php _e( 'Save Changes', 'buddypress' ) ?>" id="submit" class="auto"/></p>
97
  <?php wp_nonce_field('bp_settings_general') ?>
98
  </form>
99
  <?php
106
 
107
  $bp_settings_updated = false;
108
 
109
+ if ( $_POST['submit'] ) {
110
+ check_admin_referer('bp_settings_notifications');
111
+
112
  if ( $_POST['notifications'] ) {
113
  foreach ( $_POST['notifications'] as $key => $value ) {
114
  update_usermeta( (int)$current_user->id, $key, $value );
156
  function bp_core_screen_delete_account() {
157
  global $current_user, $bp_settings_updated, $pass_error;
158
 
159
+ if ( isset( $_POST['delete-account-button'] ) ) {
160
+ check_admin_referer( 'delete-account' );
161
+
162
  // delete the users account
163
  if ( bp_core_delete_account() )
164
  bp_core_redirect( site_url() );
167
  $bp_settings_updated = false;
168
  $pass_error = false;
169
 
170
+ if ( isset($_POST['submit']) ) {
171
+ check_admin_referer('bp_settings_general');
172
+
173
  require_once( WPINC . '/registration.php' );
174
 
175
  // Form has been submitted and nonce checks out, lets do it.
bp-core/bp-core-signup.php CHANGED
@@ -1,420 +1,221 @@
1
  <?php
2
 
3
- function bp_core_signup_set_headers() {
4
- add_action( 'wp_head', 'bp_core_signup_register_headers' ) ;
5
- require_once( ABSPATH . WPINC . '/registration.php' );
6
-
7
- if( is_array( get_site_option( 'illegal_names' )) && $_GET[ 'new' ] != '' && in_array( $_GET[ 'new' ], get_site_option( 'illegal_names' ) ) == true ) {
8
- wp_redirect( "http://{$current_site->domain}{$current_site->path}" );
9
- die();
10
- }
11
- }
12
-
13
- function bp_core_signup_do_headers() {
14
- do_action("signup_header");
15
- }
16
- add_action( 'wp_head', 'bp_core_signup_do_headers' );
17
-
18
- function bp_core_signup_register_headers() {
19
- echo "<meta name='robots' content='noindex,nofollow' />\n";
20
- }
21
-
22
- function bp_core_signup_show_blog_form( $blogname = '', $blog_title = '', $errors = '' ) {
23
- global $current_site;
24
-
25
- ?>
26
- <h3><?php _e( 'Blog Details', 'buddypress' ) ?></h3>
27
- <p id="blog-details-help">
28
- <?php _e( "To register your first blog, just fill in the details below and your registration is complete.", 'buddypress' ) ?>
29
- </p>
30
 
31
- <div id="blog-details-fields">
32
- <?php
 
 
 
 
33
 
34
- // Blog name
35
- if ( 'no' == constant( "VHOST" ) )
36
- echo '<label for="blogname">' . __('Blog Name:', 'buddypress') . '</label>';
37
- else
38
- echo '<label for="blogname">' . __('Blog Domain:', 'buddypress') . '</label>';
39
-
40
- if ( $errmsg = $errors->get_error_message('blogname') ) { ?>
41
- <p class="error"><?php echo $errmsg ?></p>
42
- <?php }
43
 
44
- if ( 'no' == constant( "VHOST" ) ) {
45
- echo '<span class="prefix_address">' . $current_site->domain . $current_site->path . '</span><input name="blogname" type="text" id="blogname" value="'.$blogname.'" maxlength="50" /><br />';
46
- } else {
47
- echo '<input name="blogname" type="text" id="blogname" value="'.$blogname.'" maxlength="50" /><span class="suffix_address">.' . $current_site->domain . $current_site->path . '</span><br />';
48
- }
 
 
 
 
 
 
 
 
 
 
 
49
 
50
- if ( !is_user_logged_in() ) {
51
- echo '<p class="help-text">';
52
- print '(<strong>' . __( 'Your address will be ', 'buddypress' );
53
- if( 'no' == constant( "VHOST" ) ) {
54
- print $current_site->domain . $current_site->path . __( 'blogname', 'buddypress' );
55
- } else {
56
- print __( 'domain.', 'buddypress' ) . $current_site->domain . $current_site->path;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  }
58
- echo '</strong>. ' . __( 'Must be at least 4 characters, letters and numbers only. It cannot be changed so choose carefully!)', 'buddypress' ) . '</p>';
59
- echo '</p>';
 
60
  }
61
 
62
- // Blog Title
63
- ?>
64
- <label for="blog_title"><?php _e( 'Blog Title:', 'buddypress' ) ?></label>
65
- <?php if ( $errmsg = $errors->get_error_message('blog_title') ) { ?>
66
- <p class="error"><?php echo $errmsg ?></p>
67
- <?php }
68
- echo '<input name="blog_title" type="text" id="blog_title" value="'.wp_specialchars($blog_title, 1).'" /></p>';
69
- ?>
70
-
71
- <p>
72
- <label for="blog_public_on"><?php _e( 'Privacy:', 'buddypress' ) ?></label>
73
- <?php _e( 'I would like my blog to appear in search engines like Google and Technorati, and in public listings around this site.', 'buddypress' ); ?>
74
- <label class="checkbox" for="blog_public_on">
75
- <input type="radio" id="blog_public_on" name="blog_public" value="1" <?php if( !isset( $_POST['blog_public'] ) || '1' == $_POST['blog_public'] ) { ?>checked="checked"<?php } ?> />
76
- &nbsp;<?php _e( 'Yes', 'buddypress' ); ?>
77
- </label>
78
- <label class="checkbox" for="blog_public_off">
79
- <input type="radio" id="blog_public_off" name="blog_public" value="0" <?php if( isset( $_POST['blog_public'] ) && '0' == $_POST['blog_public'] ) { ?>checked="checked"<?php } ?> />
80
- &nbsp;<?php _e( 'No', 'buddypress' ); ?>
81
- </label>
82
- </p>
83
- </div>
84
- <?php
85
- do_action('signup_blogform', $errors);
86
- }
87
-
88
- function bp_core_signup_validate_blog_form() {
89
- $user = '';
90
- if ( is_user_logged_in() )
91
- $user = wp_get_current_user();
92
-
93
- return wpmu_validate_blog_signup($_POST['blogname'], $_POST['blog_title'], $user);
94
- }
95
-
96
- function bp_core_signup_show_user_form($user_name = '', $user_email = '', $errors = '') {
97
- // User name
98
- echo '<div id="account-fields">';
99
- echo '<label for="user_name">' . __( 'Username:', 'buddypress' ) . '</label>';
100
- if ( $errmsg = $errors->get_error_message('user_name') ) {
101
- echo '<p class="error">'.$errmsg.'</p>';
102
- }
103
- echo '<input name="user_name" type="text" id="user_name" value="'.$user_name.'" maxlength="50" />';
104
- echo '<p class="help-text">';
105
- _e( '(Must be at least 4 characters, letters and numbers only.)', 'buddypress' );
106
- echo '</p>'
107
- ?>
108
-
109
- <label for="user_email"><?php _e( 'Email&nbsp;Address:', 'buddypress' ) ?></label>
110
- <?php if ( $errmsg = $errors->get_error_message('user_email') ) { ?>
111
- <p class="error"><?php echo $errmsg ?></p>
112
- <?php } ?>
113
- <input name="user_email" type="text" id="user_email" value="<?php echo wp_specialchars($user_email, 1) ?>" maxlength="200" /><p class="help-text"><?php _e( '(We&#8217;ll send your password to this address, so <strong>triple-check it</strong>.)', 'buddypress' ) ?></p>
114
- <?php
115
- if ( $errmsg = $errors->get_error_message('generic') ) {
116
- echo '<p class="error">'.$errmsg.'</p>';
117
- }
118
- echo '</div>';
119
-
120
- echo '<div id="extra-fields">';
121
- do_action( 'signup_extra_fields', $errors );
122
- echo '</div>';
123
- }
124
-
125
- function bp_core_signup_validate_user_form() {
126
- return wpmu_validate_user_signup($_POST['user_name'], $_POST['user_email']);
127
- }
128
 
129
- function bp_core_signup_signup_another_blog($blogname = '', $blog_title = '', $errors = '') {
130
- global $current_user, $current_site;
131
-
132
- if ( ! is_wp_error($errors) ) {
133
- $errors = new WP_Error();
134
- }
135
 
136
- // allow definition of default variables
137
- $filtered_results = apply_filters('signup_another_blog_init', array('blogname' => $blogname, 'blog_title' => $blog_title, 'errors' => $errors ));
138
- $blogname = $filtered_results['blogname'];
139
- $blog_title = $filtered_results['blog_title'];
140
- $errors = $filtered_results['errors'];
141
 
142
- ?>
143
- <h3><?php _e( "You're already registered!", 'buddypress' )?></h3>
144
- <p><?php _e( 'You can still create another blog however. Fill in the form below to add another blog to your account.', 'buddypress' ) ?>
145
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
 
147
- <p><?php _e( "There is no limit to the number of blogs you can have, so create to your heart's content, but blog responsibly. If you&#8217;re not going to use a great blog domain, leave it for a new user. Now have at it!", 'buddypress' ) ?></p>
 
148
 
149
- <form id="setupform" method="post" action="<?php echo site_url(BP_REGISTER_SLUG) ?>">
150
- <input type="hidden" name="stage" value="gimmeanotherblog" />
151
- <?php do_action( "signup_hidden_fields" ); ?>
152
- <?php bp_core_signup_show_blog_form($blogname, $blog_title, $errors); ?>
153
- <p>
154
- <input id="submit" type="submit" name="submit" class="submit" value="<?php _e('Create Blog &raquo;') ?>"/>
155
- </p>
156
- </form>
157
- <?php
158
- }
159
-
160
- function bp_core_signup_validate_another_blog_signup() {
161
- global $wpdb, $current_user, $blogname, $blog_title, $errors, $domain, $path;
162
- $current_user = wp_get_current_user();
163
- if( !is_user_logged_in() )
164
- die();
165
-
166
- $result = bp_core_signup_validate_blog_form();
167
- extract($result);
168
-
169
- if ( $errors->get_error_code() ) {
170
- bp_core_signup_signup_another_blog($blogname, $blog_title, $errors);
171
- return false;
172
  }
173
 
174
- $public = (int) $_POST['blog_public'];
175
- $meta = apply_filters('signup_create_blog_meta', array ('lang_id' => 1, 'public' => $public)); // depreciated
176
- $meta = apply_filters( "add_signup_meta", $meta );
177
-
178
- wpmu_create_blog( $domain, $path, $blog_title, $current_user->id, $meta, $wpdb->siteid );
179
- bp_core_signup_confirm_another_blog_signup($domain, $path, $blog_title, $current_user->user_login, $current_user->user_email, $meta);
180
- return true;
181
- }
182
-
183
- function bp_core_signup_confirm_another_blog_signup($domain, $path, $blog_title, $user_name, $user_email = '', $meta = '') {
184
- ?>
185
- <h2><?php printf( __( 'The blog %s is yours.', 'buddypress' ), "<a href='http://{$domain}{$path}'>{$blog_title}</a>" ) ?></h2>
186
- <p>
187
- <?php printf( __( '<a href="http://%1$s">http://%2$s</a> is your new blog. <a href="%3$s">Login</a> as "%4$s" using your existing password.', 'buddypress' ), $domain.$path, $domain.$path, "http://" . $domain.$path . "/wp-login.php", $user_name) ?>
188
- </p>
189
- <?php
190
- do_action('signup_finished');
191
- }
192
-
193
- function bp_core_signup_signup_user($user_name = '', $user_email = '', $errors = '') {
194
- global $current_site, $active_signup;
195
 
196
- $active_signup = get_site_option( 'registration' );
 
 
 
 
197
 
198
- if ( !is_wp_error($errors) )
199
- $errors = new WP_Error();
200
- if( isset( $_POST[ 'signup_for' ] ) ) {
201
- $signup[ wp_specialchars( $_POST[ 'signup_for' ] ) ] = 'checked="checked"';
202
- } else {
203
- $signup[ 'blog' ] = 'checked="checked"';
 
 
 
 
 
 
 
 
 
 
 
204
  }
205
-
206
- // allow definition of default variables
207
- $filtered_results = apply_filters('signup_user_init', array('user_name' => $user_name, 'user_email' => $user_email, 'errors' => $errors ));
208
- $user_name = $filtered_results['user_name'];
209
- $user_email = $filtered_results['user_email'];
210
- $errors = $filtered_results['errors'];
211
-
212
- ?>
213
 
214
- <form id="setupform" method="post" action="<?php echo site_url(BP_REGISTER_SLUG) ?>">
215
- <p id="intro-text"><?php _e( 'Registering for a new account is easy, just fill in the form below and you\'ll be a new member in no time at all.', 'buddypress' ) ?></p>
216
- <input type="hidden" name="stage" value="validate-user-signup" />
217
- <?php do_action( "signup_hidden_fields" ); ?>
218
-
219
- <?php bp_core_signup_show_user_form($user_name, $user_email, $errors); ?>
220
 
221
- <?php if( 'blog' == $active_signup ) { ?>
222
- <input id="signupblog" type="hidden" name="signup_for" value="blog" />
223
- <?php } elseif( 'user' == $active_signup ) { ?>
224
- <input id="signupblog" type="hidden" name="signup_for" value="user" />
225
- <?php } else { ?>
226
- <div id="blog-or-username">
227
- <h3><?php _e( 'Create a Blog?', 'buddypress' ) ?></h3>
228
- <p id="blog-help-text"><?php _e( 'If you want to create your first blog, select the option below and you\'ll be asked for a few more details.', 'buddypress' ) ?></p>
229
-
230
- <div id="blog-or-username-fields">
231
- <p>
232
- <input id="signupblog" type="radio" name="signup_for" value="blog" <?php echo $signup['blog'] ?> />
233
- <label class="checkbox" for="signupblog"><?php _e( 'Gimme a blog!', 'buddypress' ) ?></label>
234
- </p>
235
-
236
- <p>
237
- <input id="signupuser" type="radio" name="signup_for" value="user" <?php echo $signup['user'] ?> />
238
- <label class="checkbox" for="signupuser"><?php _e( 'Just a username, please.', 'buddypress' ) ?></label>
239
- </p>
240
- </div>
241
- </div>
242
- <?php } ?>
243
 
244
- <input id="submit" type="submit" name="submit" class="submit" value="<?php _e('Next &raquo;') ?>"/>
245
- </form>
246
- <?php
247
  }
 
248
 
249
- function bp_core_signup_validate_user_signup() {
250
- $result = bp_core_signup_validate_user_form();
251
- extract($result);
252
-
253
- if ( $errors->get_error_code() ) {
254
- bp_core_signup_signup_user($user_name, $user_email, $errors);
255
- return false;
256
- }
257
 
258
- if ( 'blog' == $_POST['signup_for'] ) {
259
- bp_core_signup_signup_blog($user_name, $user_email);
260
  return false;
261
- }
262
-
263
- wpmu_signup_user($user_name, $user_email, apply_filters( "add_signup_meta", array() ) );
264
-
265
- bp_core_signup_confirm_user_signup($user_name, $user_email);
266
- return true;
267
- }
268
-
269
- function bp_core_signup_confirm_user_signup($user_name, $user_email) {
270
- ?>
271
- <h3><?php _e( 'Congratulations, you are now registered!', 'buddypress' ) ?></h3>
272
- <p><?php printf(__('Your new username is: %s', 'buddypress' ), $user_name) ?></p>
273
- <p>&nbsp;</p>
274
- <p><?php printf(__('Before you can start using your new username, <strong>you must activate it</strong>. Check your inbox at <strong>%1$s</strong> and click the link given.', 'buddypress' ), $user_email) ?></p>
275
- <p><?php _e('If you do not activate your username within two days, you will have to sign up again.', 'buddypress' ); ?></p>
276
- <?php
277
- do_action('signup_finished');
278
- }
279
 
280
- function bp_core_signup_signup_blog($user_name = '', $user_email = '', $blogname = '', $blog_title = '', $errors = '') {
281
- if ( !is_wp_error($errors) )
282
- $errors = new WP_Error();
 
283
 
284
- // allow definition of default variables
285
- $filtered_results = apply_filters('signup_blog_init', array('user_name' => $user_name, 'user_email' => $user_email, 'blogname' => $blogname, 'blog_title' => $blog_title, 'errors' => $errors ));
286
- $user_name = $filtered_results['user_name'];
287
- $user_email = $filtered_results['user_email'];
288
- $blogname = $filtered_results['blogname'];
289
- $blog_title = $filtered_results['blog_title'];
290
- $errors = $filtered_results['errors'];
291
 
292
- if ( empty($blogname) )
293
- $blogname = $user_name;
294
- ?>
295
- <form id="setupform" method="post" action="<?php echo site_url(BP_REGISTER_SLUG) ?>">
296
- <input type="hidden" name="stage" value="validate-blog-signup" />
297
- <input type="hidden" name="user_name" value="<?php echo $user_name ?>" />
298
- <input type="hidden" name="user_email" value="<?php echo $user_email ?>" />
299
- <?php do_action( "signup_hidden_fields" ); ?>
300
- <?php bp_core_signup_show_blog_form($blogname, $blog_title, $errors); ?>
301
- <p>
302
- <input id="submit" type="submit" name="submit" class="submit" value="<?php _e('Signup &raquo;') ?>"/></p>
303
- </form>
304
- <?php
305
  }
306
 
307
- function bp_core_signup_validate_blog_signup() {
308
- // Re-validate user info.
309
- $result = wpmu_validate_user_signup($_POST['user_name'], $_POST['user_email']);
310
- extract($result);
311
-
312
- if ( $errors->get_error_code() ) {
313
- bp_core_signup_signup_user($user_name, $user_email, $errors);
314
  return false;
315
- }
316
-
317
- $result = wpmu_validate_blog_signup($_POST['blogname'], $_POST['blog_title']);
318
- extract($result);
319
 
320
- if ( $errors->get_error_code() ) {
321
- bp_core_signup_signup_blog($user_name, $user_email, $blogname, $blog_title, $errors);
322
- return false;
323
- }
324
-
325
- $public = (int) $_POST['blog_public'];
326
- $meta = array ('lang_id' => 1, 'public' => $public);
327
- $meta = apply_filters( "add_signup_meta", $meta );
328
-
329
- wpmu_signup_blog($domain, $path, $blog_title, $user_name, $user_email, $meta);
330
- bp_core_signup_confirm_blog_signup($domain, $path, $blog_title, $user_name, $user_email, $meta);
331
- return true;
332
  }
 
333
 
334
- function bp_core_signup_confirm_blog_signup($domain, $path, $blog_title, $user_name = '', $user_email = '', $meta) {
335
- ?>
336
- <h3><?php _e('Congratulations, You are now registered!', 'buddypress' ) ?></h3>
337
-
338
- <p><?php printf( __('But, before you can start using your blog, <strong>you must activate it</strong>. Check your inbox at <strong>%s</strong> and click the link given. It should arrive within 30 minutes.', 'buddypress' ), $user_email) ?></p>
339
- <p>&nbsp;</p>
340
-
341
- <h3><?php _e( 'Still waiting for your email?', 'buddypress' ); ?></h3>
342
- <p>
343
- <?php _e( "If you haven't received your email yet, there are a number of things you can do:", 'buddypress' ) ?>
344
- <ul>
345
- <li><p><strong><?php _e( 'Wait a little longer. Sometimes delivery of email can be delayed by processes outside of our control.', 'buddypress' ) ?></strong></p></li>
346
- <li><p><?php _e( 'Check the junk email or spam folder of your email client. Sometime emails wind up there by mistake.', 'buddypress' ) ?></p></li>
347
- <li><?php printf( __( "Have you entered your email correctly? We think it's %s but if you've entered it incorrectly, you won't receive it.", 'buddypress' ), $user_email) ?></li>
348
- </ul>
349
- </p>
350
- <?php
351
- do_action('signup_finished');
352
- }
353
-
354
- function bp_core_signup_do_signup() {
355
- // Main
356
- $active_signup = get_site_option( 'registration' );
357
- if( !$active_signup )
358
- $active_signup = 'all';
359
-
360
- $active_signup = apply_filters( 'wpmu_active_signup', $active_signup ); // return "all", "none", "blog" or "user"
361
 
362
- if( is_site_admin() )
363
- echo '<div class="mu_alert">' . sprintf( __( "Greetings Site Administrator! You are currently allowing '%s' registrations. To change or disable registration go to your <a href='wp-admin/wpmu-options.php'>Options page</a>.", 'buddypress' ), $active_signup ) . '</div>';
364
 
365
- $newblogname = isset($_GET['new']) ? strtolower(preg_replace('/^-|-$|[^-a-zA-Z0-9]/', '', $_GET['new'])) : null;
366
 
367
- $current_user = wp_get_current_user();
368
- if( $active_signup == "none" ) {
369
- _e( "Registration has been disabled.", 'buddypress' );
370
- } elseif( $active_signup == 'blog' && !is_user_logged_in() ){
371
- if( is_ssl() ) {
372
- $proto = 'https://';
373
- } else {
374
- $proto = 'http://';
375
- }
376
- $login_url = site_url( 'wp-login.php?redirect_to=' . site_url(BP_REGISTER_SLUG) );
377
- echo sprintf( __( "You must first <a href=\"%s\">login</a>, and then you can create a new blog.", 'buddypress' ), $login_url );
378
- } else {
379
- switch ($_POST['stage']) {
380
- case 'validate-user-signup' :
381
- if( $active_signup == 'all' || $_POST[ 'signup_for' ] == 'blog' && $active_signup == 'blog' || $_POST[ 'signup_for' ] == 'user' && $active_signup == 'user' )
382
- bp_core_signup_validate_user_signup();
383
- else
384
- _e( "User registration has been disabled.", 'buddypress' );
385
- break;
386
- case 'validate-blog-signup':
387
- if( $active_signup == 'all' || $active_signup == 'blog' )
388
- bp_core_signup_validate_blog_signup();
389
- else
390
- _e( "Blog registration has been disabled.", 'buddypress' );
391
- break;
392
- case 'gimmeanotherblog':
393
- bp_core_signup_validate_another_blog_signup();
394
- break;
395
- default :
396
- $user_email = $_POST[ 'user_email' ];
397
- do_action( "preprocess_signup_form" ); // populate the form from invites, elsewhere?
398
- if ( is_user_logged_in() && ( $active_signup == 'all' || $active_signup == 'blog' ) ) {
399
- bp_core_signup_signup_another_blog($newblogname);
400
- } elseif( is_user_logged_in() == false && ( $active_signup == 'all' || $active_signup == 'user' ) ) {
401
- bp_core_signup_signup_user( $newblogname, $user_email );
402
- } elseif( is_user_logged_in() == false && ( $active_signup == 'blog' ) ) {
403
- _e( "I'm sorry. We're not accepting new registrations at this time.", 'buddypress' );
404
- } else {
405
- _e( "You're logged in already. No need to register again!", 'buddypress' );
406
- }
407
- if ($newblogname) {
408
- if( constant( "VHOST" ) == 'no' )
409
- $newblog = 'http://' . $current_site->domain . $current_site->path . $newblogname . '/';
410
- else
411
- $newblog = 'http://' . $newblogname . '.' . $current_site->domain . $current_site->path;
412
- if ($active_signup == 'blog' || $active_signup == 'all')
413
- printf( __( "<p><em>The blog you were looking for, <strong>%s</strong> doesn't exist but you can create it now!</em></p>", 'buddypress' ), $newblog );
414
- else
415
- printf( __( "<p><em>The blog you were looking for, <strong>%s</strong> doesn't exist.</em></p>", 'buddypress' ), $newblog );
416
- }
417
- break;
418
- }
419
- }
420
- }
1
  <?php
2
 
3
+ function bp_core_screen_signup() {
4
+ global $bp, $wpdb;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
+ if ( $bp->current_component != BP_REGISTER_SLUG )
7
+ return false;
8
+
9
+ /* If the user is logged in, redirect away from here */
10
+ if ( is_user_logged_in() )
11
+ bp_core_redirect( $bp->root_domain );
12
 
13
+ /***
14
+ * For backwards compatibility with the old pre 1.1 two theme system, skip this screen function
15
+ * if the user is using the old two theme method.
16
+ */
17
+ if ( file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
18
+ return false;
 
 
 
19
 
20
+ /* If signups are disabled, just re-direct */
21
+ if ( 'none' == bp_get_signup_allowed() || 'blog' == bp_get_signup_allowed() )
22
+ bp_core_redirect( $bp->root_domain );
23
+
24
+ $bp->signup->step = 'request-details';
25
+
26
+ /* If the signup page is submitted, validate and save */
27
+ if ( isset( $_POST['signup_submit'] ) ) {
28
+
29
+ /* Check the nonce */
30
+ check_admin_referer( 'bp_new_signup' );
31
+
32
+ require_once( ABSPATH . WPINC . '/registration.php' );
33
+
34
+ /* Check the base account details for problems */
35
+ $account_details = wpmu_validate_user_signup( $_POST['signup_username'] , $_POST['signup_email'] );
36
 
37
+ /* If there are errors with account details, set them for display */
38
+ if ( !empty( $account_details['errors']->errors['user_name'] ) )
39
+ $bp->signup->errors['signup_username'] = $account_details['errors']->errors['user_name'][0];
40
+
41
+ if ( !empty( $account_details['errors']->errors['user_email'] ) )
42
+ $bp->signup->errors['signup_email'] = $account_details['errors']->errors['user_email'][0];
43
+
44
+ /* Check that both password fields are filled in */
45
+ if ( empty( $_POST['signup_password'] ) || empty( $_POST['signup_password_confirm'] ) )
46
+ $bp->signup->errors['signup_password'] = __( 'Please make sure you enter your password twice', 'buddypress' );
47
+
48
+ /* Check that the passwords match */
49
+ if ( ( !empty( $_POST['signup_password'] ) && !empty( $_POST['signup_password_confirm'] ) ) && $_POST['signup_password'] != $_POST['signup_password_confirm'] )
50
+ $bp->signup->errors['signup_password'] = __( 'The passwords you entered do not match.', 'buddypress' );
51
+
52
+ /* Now we've checked account details, we can check profile information */
53
+ $profile_field_ids = explode( ',', $_POST['signup_profile_field_ids'] );
54
+
55
+ /* Loop through the posted fields formatting any datebox values then validate the field */
56
+ foreach ( (array) $profile_field_ids as $field_id ) {
57
+ if ( !isset( $_POST['field_' . $field_id] ) ) {
58
+ if ( isset( $_POST['field_' . $field_id . '_day'] ) )
59
+ $_POST['field_' . $field_id] = strtotime( $_POST['field_' . $field_id . '_day'] . $_POST['field_' . $field_id . '_month'] . $_POST['field_' . $field_id . '_year'] );
60
  }
61
+
62
+ if ( xprofile_check_is_required_field( $field_id ) && empty( $_POST['field_' . $field_id] ) )
63
+ $bp->signup->errors['field_' . $field_id] = __( 'This is a required field', 'buddypress' );
64
  }
65
 
66
+ /* Finally, let's check the blog details, if the user wants a blog and blog creation is enabled */
67
+ if ( isset( $_POST['signup_with_blog'] ) ) {
68
+ $active_signup = get_site_option( 'registration' );
69
+
70
+ if ( 'blog' == $active_signup || 'all' == $active_signup ) {
71
+ $blog_details = wpmu_validate_blog_signup( $_POST['signup_blog_url'], $_POST['signup_blog_title'] );
72
+
73
+ /* If there are errors with blog details, set them for display */
74
+ if ( !empty( $blog_details['errors']->errors['blogname'] ) )
75
+ $bp->signup->errors['signup_blog_url'] = $blog_details['errors']->errors['blogname'][0];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
+ if ( !empty( $blog_details['errors']->errors['blog_title'] ) )
78
+ $bp->signup->errors['signup_blog_title'] = $blog_details['errors']->errors['blog_title'][0];
79
+ }
80
+ }
 
 
81
 
82
+ do_action( 'bp_signup_validate' );
 
 
 
 
83
 
84
+ /* Add any errors to the action for the field in the template for display. */
85
+ if ( !empty( $bp->signup->errors ) ) {
86
+ foreach ( $bp->signup->errors as $fieldname => $error_message )
87
+ add_action( 'bp_' . $fieldname . '_errors', create_function( '', 'echo "<div class=\"error\">' . $error_message . '</div>";' ) );
88
+ } else {
89
+ $bp->signup->step = 'save-details';
90
+
91
+ /* No errors! Let's register those deets. */
92
+ $active_signup = get_site_option( 'registration' );
93
+
94
+ if ( 'none' != $active_signup ) {
95
+
96
+ /* Let's compact any profile field info into usermeta */
97
+ $profile_field_ids = explode( ',', $_POST['signup_profile_field_ids'] );
98
+
99
+ /* Loop through the posted fields formatting any datebox values then add to usermeta */
100
+ foreach ( (array) $profile_field_ids as $field_id ) {
101
+ if ( !isset( $_POST['field_' . $field_id] ) ) {
102
+ if ( isset( $_POST['field_' . $field_id . '_day'] ) )
103
+ $_POST['field_' . $field_id] = strtotime( $_POST['field_' . $field_id . '_day'] . $_POST['field_' . $field_id . '_month'] . $_POST['field_' . $field_id . '_year'] );
104
+ }
105
+
106
+ if ( !empty( $_POST['field_' . $field_id] ) )
107
+ $usermeta['field_' . $field_id] = $_POST['field_' . $field_id];
108
+ }
109
+
110
+ /* Store the profile field ID's in usermeta */
111
+ $usermeta['profile_field_ids'] = $_POST['signup_profile_field_ids'];
112
+
113
+ /* Hash and store the password */
114
+ $usermeta['password'] = wp_hash_password( $_POST['signup_password'] );
115
+
116
+ /* If the user decided to create a blog, save those details to usermeta */
117
+ if ( 'blog' == $active_signup || 'all' == $active_signup ) {
118
+ $usermeta['public'] = ( 'public' == $_POST['signup_blog_privacy'] ) ? true : false;
119
+ $usermeta['blogname'] = $_POST['signup_blog_url'];
120
+ $usermeta['blog_title'] = $_POST['signup_blog_title'];
121
+ }
122
+
123
+ $usermeta = apply_filters( 'bp_signup_usermeta', $usermeta );
124
+
125
+ /* Finally, sign up the user and/or blog*/
126
+ if ( isset( $_POST['signup_with_blog'] ) )
127
+ wpmu_signup_blog( $blog_details['domain'], $blog_details['path'], $blog_details['blog_title'], $_POST['signup_username'], $_POST['signup_email'], $usermeta );
128
+ else
129
+ wpmu_signup_user( $_POST['signup_username'], $_POST['signup_email'], $usermeta );
130
+
131
+ $bp->signup->step = 'completed-confirmation';
132
+ }
133
 
134
+ do_action( 'bp_complete_signup' );
135
+ }
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  }
138
 
139
+ $bp->avatar_admin->step = 'upload-image';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
 
141
+ /* If user has uploaded a new avatar */
142
+ if ( !empty( $_FILES ) ) {
143
+
144
+ /* Check the nonce */
145
+ check_admin_referer( 'bp_avatar_upload' );
146
 
147
+ $bp->signup->step = 'completed-confirmation';
148
+
149
+ /* Get the activation key */
150
+ if ( !$bp->signup->key = $wpdb->get_var( $wpdb->prepare( "SELECT activation_key FROM {$wpdb->signups} WHERE user_login = %s AND user_email = %s", $_POST[ 'signup_username' ], $_POST[ 'signup_email' ] ) ) ) {
151
+ bp_core_add_message( __( 'There was a problem uploading your avatar, please try uploading it again', 'buddypress' ) );
152
+ } else {
153
+ /* Hash the key to create the upload folder (added security so people don't sniff the activation key) */
154
+ $bp->signup->avatar_dir = wp_hash( $bp->signup->key );
155
+
156
+ /* Pass the file to the avatar upload handler */
157
+ if ( bp_core_avatar_handle_upload( $_FILES, 'bp_core_signup_avatar_upload_dir' ) ) {
158
+ $bp->avatar_admin->step = 'crop-image';
159
+
160
+ /* Make sure we include the jQuery jCrop file for image cropping */
161
+ add_action( 'wp', 'bp_core_add_jquery_cropper' );
162
+ }
163
+ }
164
  }
 
 
 
 
 
 
 
 
165
 
166
+ /* If the image cropping is done, crop the image and save a full/thumb version */
167
+ if ( isset( $_POST['avatar-crop-submit'] ) ) {
 
 
 
 
168
 
169
+ /* Check the nonce */
170
+ check_admin_referer( 'bp_avatar_cropstore' );
171
+
172
+ /* Reset the avatar step so we can show the upload form again if needed */
173
+ $bp->signup->step = 'completed-confirmation';
174
+ $bp->avatar_admin->step = 'upload-image';
175
+
176
+ if ( !bp_core_avatar_handle_crop( array( 'original_file' => $_POST['image_src'], 'crop_x' => $_POST['x'], 'crop_y' => $_POST['y'], 'crop_w' => $_POST['w'], 'crop_h' => $_POST['h'] ) ) )
177
+ bp_core_add_message( __( 'There was a problem cropping your avatar, please try uploading it again', 'buddypress' ) );
178
+ else
179
+ bp_core_add_message( __( 'Your new avatar was uploaded successfully', 'buddypress' ) );
 
 
 
 
 
 
 
 
 
 
 
180
 
181
+ }
182
+ bp_core_load_template( 'registration/register' );
 
183
  }
184
+ add_action( 'wp', 'bp_core_screen_signup', 3 );
185
 
186
+ function bp_core_signup_avatar_upload_dir() {
187
+ global $bp;
 
 
 
 
 
 
188
 
189
+ if ( !$bp->signup->avatar_dir )
 
190
  return false;
191
+
192
+ $path = get_blog_option( BP_ROOT_BLOG, 'upload_path' );
193
+ $newdir = WP_CONTENT_DIR . str_replace( 'wp-content', '', $path );
194
+ $newdir .= '/avatars/signups/' . $bp->signup->avatar_dir;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
 
196
+ $newbdir = $newdir;
197
+
198
+ if ( !file_exists( $newdir ) )
199
+ @wp_mkdir_p( $newdir );
200
 
201
+ $newurl = WP_CONTENT_URL . '/blogs.dir/' . BP_ROOT_BLOG . '/files/avatars/signups/' . $bp->signup->avatar_dir;
202
+ $newburl = $newurl;
203
+ $newsubdir = '/avatars/signups/' . $bp->signup->avatar_dir;
 
 
 
 
204
 
205
+ return apply_filters( 'bp_core_signup_avatar_upload_dir', array( 'path' => $newdir, 'url' => $newurl, 'subdir' => $newsubdir, 'basedir' => $newbdir, 'baseurl' => $newburl, 'error' => false ) );
 
 
 
 
 
 
 
 
 
 
 
 
206
  }
207
 
208
+ /* Kill the wp-signup.php if custom registration signup templates are present */
209
+ function bp_core_wpsignup_redirect() {
210
+ if ( false === strpos( $_SERVER['SCRIPT_NAME'], 'wp-signup.php') )
 
 
 
 
211
  return false;
 
 
 
 
212
 
213
+ if ( '' != locate_template( array( 'registration/register.php' ), false ) || '' != locate_template( array( 'register.php' ), false ) )
214
+ die;
 
 
 
 
 
 
 
 
 
 
215
  }
216
+ add_action( 'signup_header', 'bp_core_wpsignup_redirect' );
217
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
 
 
 
219
 
 
220
 
221
+ ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-core/bp-core-templatetags.php CHANGED
@@ -15,16 +15,13 @@
15
  * @package BuddyPress Core
16
  * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
17
  */
18
- function bp_get_nav() {
19
  global $bp, $current_blog;
20
 
21
- /* Sort the nav by key as the array has been put together in different locations */
22
- $bp->bp_nav = bp_core_sort_nav_items( $bp->bp_nav );
23
-
24
  /* Loop through each navigation item */
25
  foreach( (array) $bp->bp_nav as $nav_item ) {
26
  /* If the current component matches the nav item id, then add a highlight CSS class. */
27
- if ( $bp->current_component == $nav_item['css_id'] ) {
28
  $selected = ' class="current"';
29
  } else {
30
  $selected = '';
@@ -37,7 +34,7 @@ function bp_get_nav() {
37
  $selected = '';
38
 
39
  if ( function_exists('friends_install') ) {
40
- if ( $nav_item['css_id'] == $bp->friends->slug ) {
41
  if ( friends_check_friendship( $bp->loggedin_user->id, $bp->displayed_user->id ) )
42
  $selected = ' class="current"';
43
  }
@@ -45,17 +42,54 @@ function bp_get_nav() {
45
  }
46
 
47
  /* echo out the final list item */
48
- echo '<li' . $selected . '><a id="my-' . $nav_item['css_id'] . '" href="' . $nav_item['link'] . '">' . $nav_item['name'] . '</a></li>';
49
  }
50
 
51
  /* Always add a log out list item to the end of the navigation */
52
  if ( function_exists( 'wp_logout_url' ) ) {
53
- echo '<li><a id="wp-logout" href="' . wp_logout_url( site_url() . $_SERVER['REQUEST_URI'] ) . '">' . __( 'Log Out', 'buddypress' ) . '</a></li>';
54
  } else {
55
- echo '<li><a id="wp-logout" href="' . site_url() . '/wp-login.php?action=logout&amp;redirect_to=' . site_url() . $_SERVER['REQUEST_URI'] . '">' . __( 'Log Out', 'buddypress' ) . '</a></li>';
56
  }
 
 
57
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  /**
60
  * bp_get_options_nav()
61
  * TEMPLATE TAG
@@ -85,55 +119,37 @@ function bp_get_options_nav() {
85
  return false;
86
 
87
  /* Loop through each navigation item */
88
- foreach ( $bp->bp_options_nav[$bp->current_component] as $slug => $values ) {
89
- $title = $values['name'];
90
- $link = $values['link'];
91
- $css_id = $values['css_id'];
92
 
93
  /* If the current action or an action variable matches the nav item id, then add a highlight CSS class. */
94
- if ( $slug == $bp->current_action || in_array( $slug, $bp->action_variables ) ) {
95
  $selected = ' class="current"';
96
  } else {
97
  $selected = '';
98
  }
99
 
100
  /* echo out the final list item */
101
- echo '<li' . $selected . '><a id="' . $css_id . '" href="' . $link . '">' . $title . '</a></li>';
102
  }
103
  } else {
104
- if ( !$bp->bp_users_nav )
105
- return false;
106
-
107
- bp_get_user_nav();
108
  }
109
  }
110
 
111
- /**
112
- * bp_get_user_nav()
113
- * TEMPLATE TAG
114
- *
115
- * Uses the $bp->bp_users_nav global to render out the user navigation when viewing another user other than
116
- * yourself.
117
- *
118
- * @package BuddyPress Core
119
- * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
120
- */
121
- function bp_get_user_nav() {
122
  global $bp;
123
-
124
- /* Sort the nav by key as the array has been put together in different locations */
125
- $bp->bp_users_nav = bp_core_sort_nav_items( $bp->bp_users_nav );
126
-
127
- foreach ( $bp->bp_users_nav as $user_nav_item ) {
128
- if ( $bp->current_component == $user_nav_item['css_id'] ) {
129
- $selected = ' class="current"';
130
- } else {
131
- $selected = '';
132
- }
133
-
134
- echo '<li' . $selected . '><a id="user-' . $user_nav_item['css_id'] . '" href="' . $user_nav_item['link'] . '">' . $user_nav_item['name'] . '</a></li>';
135
- }
136
  }
 
 
 
137
 
138
  /**
139
  * bp_has_options_avatar()
@@ -154,36 +170,17 @@ function bp_has_options_avatar() {
154
  return true;
155
  }
156
 
157
- /**
158
- * bp_get_options_avatar()
159
- * TEMPLATE TAG
160
- *
161
- * Gets the avatar for the current sub nav (eg friends avatar or group avatar).
162
- * Does not check if there is one - so always use if ( bp_has_options_avatar() )
163
- *
164
- * @package BuddyPress Core
165
- * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
166
- */
167
  function bp_get_options_avatar() {
168
  global $bp;
169
 
170
  echo apply_filters( 'bp_get_options_avatar', $bp->bp_options_avatar );
171
  }
172
 
173
- function bp_get_options_title() {
174
- global $bp;
175
-
176
- if ( empty( $bp->bp_options_title ) )
177
- $bp->bp_options_title = __( 'Options', 'buddypress' );
178
-
179
- echo apply_filters( 'bp_get_options_avatar', attribute_escape( $bp->bp_options_title ) );
180
- }
181
-
182
  function bp_comment_author_avatar() {
183
  global $comment;
184
 
185
- if ( function_exists('bp_core_get_avatar') ) {
186
- echo apply_filters( 'bp_comment_author_avatar', bp_core_get_avatar( $comment->user_id, 1 ) );
187
  } else if ( function_exists('get_avatar') ) {
188
  get_avatar();
189
  }
@@ -192,33 +189,84 @@ function bp_comment_author_avatar() {
192
  function bp_post_author_avatar() {
193
  global $post;
194
 
195
- if ( function_exists('bp_core_get_avatar') ) {
196
- echo apply_filters( 'bp_post_author_avatar', bp_core_get_avatar( $post->post_author, 1 ) );
197
  } else if ( function_exists('get_avatar') ) {
198
  get_avatar();
199
  }
200
  }
201
 
202
- function bp_loggedinuser_avatar( $width = false, $height = false ) {
203
- global $bp;
204
-
205
- if ( $width && $height )
206
- echo apply_filters( 'bp_loggedinuser_avatar', bp_core_get_avatar( $bp->loggedin_user->id, 2, $width, $height ) );
207
- else
208
- echo apply_filters( 'bp_loggedinuser_avatar', bp_core_get_avatar( $bp->loggedin_user->id, 2 ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  }
 
 
210
 
211
- function bp_loggedinuser_avatar_thumbnail( $width = false, $height = false ) {
 
 
 
 
 
 
 
 
 
 
 
 
212
  global $bp;
213
 
214
- if ( $width && $height )
215
- echo apply_filters( 'bp_get_options_avatar', bp_core_get_avatar( $bp->loggedin_user->id, 1, $width, $height ) );
216
- else
217
- echo apply_filters( 'bp_get_options_avatar', bp_core_get_avatar( $bp->loggedin_user->id, 1 ) );
218
  }
219
 
220
  function bp_site_name() {
221
- echo apply_filters( 'bp_site_name', get_blog_option( 1, 'blogname' ) );
222
  }
223
 
224
  function bp_is_home() {
@@ -230,14 +278,6 @@ function bp_is_home() {
230
  return false;
231
  }
232
 
233
- /* DEPRECATED Use: bp_core_get_user_displayname() */
234
- function bp_fetch_user_fullname( $user_id, $echo = true ) {
235
- if ( $echo )
236
- echo apply_filters( 'bp_fetch_user_fullname', bp_core_get_user_displayname( $user_id ) );
237
- else
238
- return apply_filters( 'bp_fetch_user_fullname', bp_core_get_user_displayname( $user_id ) );
239
- }
240
-
241
  function bp_last_activity( $user_id = false, $echo = true ) {
242
  global $bp;
243
 
@@ -252,16 +292,6 @@ function bp_last_activity( $user_id = false, $echo = true ) {
252
  return apply_filters( 'bp_last_activity', $last_activity );
253
  }
254
 
255
- function bp_the_avatar() {
256
- global $bp;
257
- echo apply_filters( 'bp_the_avatar', bp_core_get_avatar( $bp->displayed_user->id, 2 ) );
258
- }
259
-
260
- function bp_the_avatar_thumbnail() {
261
- global $bp;
262
- echo apply_filters( 'bp_the_avatar_thumbnail', bp_core_get_avatar( $bp->displayed_user->id, 1 ) );
263
- }
264
-
265
  function bp_user_link() {
266
  global $bp;
267
 
@@ -286,7 +316,7 @@ function bp_core_get_wp_profile() {
286
  $ud = get_userdata( $bp->displayed_user->id );
287
  ?>
288
 
289
- <div class="info-group wp-profile">
290
  <h4><?php _e( 'My Profile' ) ?></h4>
291
 
292
  <table class="wp-profile-fields">
@@ -356,7 +386,7 @@ function bp_core_get_wp_profile() {
356
  }
357
 
358
  function bp_get_profile_header() {
359
- load_template( TEMPLATEPATH . '/profile/profile-header.php' );
360
  }
361
 
362
  function bp_exists( $component_name ) {
@@ -424,19 +454,18 @@ function bp_loggedinuser_link() {
424
  }
425
 
426
  function bp_get_plugin_sidebar() {
427
- if ( file_exists(TEMPLATEPATH . '/plugin-sidebar.php') )
428
- load_template( TEMPLATEPATH . '/plugin-sidebar.php' );
429
  }
430
 
431
  function bp_is_blog_page() {
432
  global $bp, $is_member_page;
433
-
434
  if ( $bp->current_component == BP_HOME_BLOG_SLUG )
435
  return true;
436
 
437
  if ( !$is_member_page && !in_array( $bp->current_component, $bp->root_components ) )
438
  return true;
439
-
440
  return false;
441
  }
442
 
@@ -456,9 +485,9 @@ function bp_get_page_title() {
456
  $title = __( 'Blog &#8212; Categories &#8212; ' . ucwords( $wp_query->query_vars['category_name'] ), 'buddypress' );
457
  } else if ( is_tag() ) {
458
  $title = __( 'Blog &#8212; Tags &#8212; ' . ucwords( $wp_query->query_vars['tag'] ), 'buddypress' );
459
- } else {
460
  $title = __( 'Blog', 'buddypress' );
461
- }
462
  } else if ( !empty( $bp->displayed_user->fullname ) ) {
463
  $title = strip_tags( $bp->displayed_user->fullname . ' &#8212; ' . ucwords( $bp->current_component ) . ' &#8212; ' . $bp->bp_options_nav[$bp->current_component][$bp->current_action]['name'] );
464
  } else if ( $bp->is_single_item ) {
@@ -502,28 +531,34 @@ function bp_is_page($page) {
502
  function bp_has_custom_signup_page() {
503
  if ( file_exists( WP_CONTENT_DIR . '/themes/' . get_blog_option( BP_ROOT_BLOG, 'template') . '/register.php') )
504
  return true;
505
-
 
 
 
506
  return false;
507
  }
508
 
509
- function bp_signup_page( $echo = true ) {
510
- global $bp;
511
-
512
- if ( bp_has_custom_signup_page() ) {
513
- if ( $echo )
514
- echo $bp->root_domain . '/' . BP_REGISTER_SLUG;
515
- else
516
- return $bp->root_domain . '/' . BP_REGISTER_SLUG;
517
- } else {
518
- if ( $echo )
519
- echo $bp->root_domain . '/wp-signup.php';
520
- else
521
- return $bp->root_domain . '/wp-signup.php';
522
- }
523
  }
 
 
 
 
 
 
 
 
 
524
 
525
  function bp_has_custom_activation_page() {
526
- if ( file_exists( WP_CONTENT_DIR . '/themes/' . get_blog_option( 1, 'template') . '/activate.php') )
 
 
 
527
  return true;
528
 
529
  return false;
@@ -562,6 +597,10 @@ function bp_search_form_type_select() {
562
  if ( function_exists( 'groups_install' ) ) {
563
  $selection_box .= '<option value="groups">' . __( 'Groups', 'buddypress' ) . '</option>';
564
  }
 
 
 
 
565
 
566
  if ( function_exists( 'bp_blogs_install' ) ) {
567
  $selection_box .= '<option value="blogs">' . __( 'Blogs', 'buddypress' ) . '</option>';
@@ -586,45 +625,14 @@ function bp_search_form() {
586
  echo apply_filters( 'bp_search_form', $form );
587
  }
588
 
589
- function bp_login_bar() {
590
  global $bp;
591
-
592
- if ( !is_user_logged_in() ) : ?>
593
-
594
- <form name="login-form" id="login-form" action="<?php echo $bp->root_domain . '/wp-login.php' ?>" method="post">
595
- <input type="text" name="log" id="user_login" value="<?php _e( 'Username', 'buddypress' ) ?>" onfocus="if (this.value == '<?php _e( 'Username', 'buddypress' ) ?>') {this.value = '';}" onblur="if (this.value == '') {this.value = '<?php _e( 'Username', 'buddypress' ) ?>';}" />
596
- <input type="password" name="pwd" id="user_pass" class="input" value="" />
597
-
598
- <input type="checkbox" name="rememberme" id="rememberme" value="forever" title="<?php _e( 'Remember Me', 'buddypress' ) ?>" />
599
-
600
- <input type="submit" name="wp-submit" id="wp-submit" value="<?php _e( 'Log In', 'buddypress' ) ?>"/>
601
- <input type="button" name="signup-submit" id="signup-submit" value="<?php _e( 'Sign Up', 'buddypress' ) ?>" onclick="location.href='<?php echo bp_signup_page() ?>'" />
602
 
603
- <input type="hidden" name="redirect_to" value="http://<?php echo $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] ?>" />
604
- <input type="hidden" name="testcookie" value="1" />
605
-
606
- <?php do_action( 'bp_login_bar_logged_out' ) ?>
607
- </form>
608
-
609
- <?php else : ?>
610
-
611
- <div id="logout-link">
612
- <?php bp_loggedinuser_avatar_thumbnail( 20, 20 ) ?> &nbsp;
613
- <?php bp_loggedinuser_link() ?>
614
- <?php
615
- if ( function_exists('wp_logout_url') ) {
616
- $logout_link = '/ <a href="' . wp_logout_url( $bp->root_domain ) . '">' . __( 'Log Out', 'buddypress' ) . '</a>';
617
- } else {
618
- $logout_link = '/ <a href="' . $bp->root_domain . '/wp-login.php?action=logout&amp;redirect_to=' . $bp->root_domain . '">' . __( 'Log Out', 'buddypress' ) . '</a>';
619
- }
620
-
621
- echo apply_filters( 'bp_logout_link', $logout_link );
622
- ?>
623
-
624
- <?php do_action( 'bp_login_bar_logged_in' ) ?>
625
- </div>
626
-
627
- <?php endif;
628
  }
629
 
630
  function bp_profile_wire_can_post() {
@@ -670,24 +678,6 @@ function bp_custom_profile_sidebar_boxes() {
670
  do_action( 'bp_custom_profile_sidebar_boxes' );
671
  }
672
 
673
- function bp_get_userbar( $hide_on_directory = true ) {
674
- global $bp;
675
-
676
- if ( $hide_on_directory && $bp->is_directory )
677
- return false;
678
-
679
- include_once( TEMPLATEPATH . '/userbar.php' );
680
- }
681
-
682
- function bp_get_optionsbar( $hide_on_directory = true ) {
683
- global $bp;
684
-
685
- if ( $hide_on_directory && $bp->is_directory )
686
- return false;
687
-
688
- include_once( TEMPLATEPATH . '/optionsbar.php' );
689
- }
690
-
691
  function bp_is_directory() {
692
  global $bp;
693
 
@@ -706,8 +696,7 @@ function bp_is_directory() {
706
  */
707
  function bp_create_excerpt( $text, $excerpt_length = 55, $filter_shortcodes = true ) { // Fakes an excerpt if needed
708
  $text = str_replace(']]>', ']]&gt;', $text);
709
- $text = strip_tags($text);
710
-
711
  if ( $filter_shortcodes )
712
  $text = preg_replace( '|\[(.+?)\](.+?\[/\\1\])?|s', '', $text );
713
 
@@ -718,8 +707,15 @@ function bp_create_excerpt( $text, $excerpt_length = 55, $filter_shortcodes = tr
718
  $text = implode(' ', $words);
719
  }
720
 
721
- return apply_filters( 'the_excerpt', stripslashes($text) );
722
  }
 
 
 
 
 
 
 
723
 
724
  /**
725
  * bp_is_serialized()
@@ -743,6 +739,114 @@ function bp_is_serialized( $data ) {
743
  return false;
744
  }
745
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
746
 
747
  /*** CUSTOM LOOP TEMPLATE CLASSES *******************/
748
 
@@ -813,15 +917,17 @@ class BP_Core_Members_Template {
813
  $this->member_count = count($this->members);
814
  }
815
 
816
- $this->pag_links = paginate_links( array(
817
- 'base' => add_query_arg( 'upage', '%#%' ),
818
- 'format' => '',
819
- 'total' => ceil( (int) $this->total_member_count / (int) $this->pag_num ),
820
- 'current' => (int) $this->pag_page,
821
- 'prev_text' => '&laquo;',
822
- 'next_text' => '&raquo;',
823
- 'mid_size' => 1
824
- ));
 
 
825
  }
826
 
827
  function has_members() {
@@ -926,7 +1032,7 @@ function bp_site_members_pagination_count() {
926
  $to_num = ( $from_num + ( $site_members_template->pag_num - 1 ) > $site_members_template->total_member_count ) ? $site_members_template->total_member_count : $from_num + ( $site_members_template->pag_num - 1) ;
927
 
928
  echo sprintf( __( 'Viewing member %d to %d (of %d members)', 'buddypress' ), $from_num, $to_num, $site_members_template->total_member_count ); ?> &nbsp;
929
- <img id="ajax-loader-members" src="<?php echo $bp->core->image_base ?>/ajax-loader.gif" height="7" alt="<?php _e( "Loading", "buddypress" ) ?>" style="display: none;" /><?php
930
  }
931
 
932
  function bp_site_members_pagination_links() {
@@ -974,6 +1080,7 @@ function bp_the_site_member_name() {
974
  return apply_filters( 'bp_get_the_site_member_name', $site_members_template->member->fullname );
975
  }
976
  add_filter( 'bp_get_the_site_member_name', 'wp_filter_kses' );
 
977
 
978
  function bp_the_site_member_last_active() {
979
  echo bp_get_the_site_member_last_active();
@@ -1047,8 +1154,8 @@ function bp_the_site_member_hidden_fields() {
1047
 
1048
  function bp_directory_members_search_form() {
1049
  global $bp; ?>
1050
- <form action="<?php echo $bp->root_domain . '/' . BP_MEMBERS_SLUG . '/search/' ?>" method="post" id="search-members-form">
1051
- <label><input type="text" name="members_search" id="members_search" value="<?php if ( isset( $_GET['s'] ) ) { echo attribute_escape( $_GET['s'] ); } else { _e( 'Search anything...', 'buddypress' ); } ?>" onfocus="if (this.value == '<?php _e( 'Search anything...', 'buddypress' ) ?>') {this.value = '';}" onblur="if (this.value == '') {this.value = '<?php _e( 'Search anything...', 'buddypress' ) ?>';}" /></label>
1052
  <input type="submit" id="members_search_submit" name="members_search_submit" value="<?php _e( 'Search', 'buddypress' ) ?>" />
1053
  <?php wp_nonce_field( 'directory_members', '_wpnonce-member-filter' ) ?>
1054
  </form>
@@ -1121,10 +1228,521 @@ function bp_current_action() {
1121
  return apply_filters( 'bp_current_action', $bp->current_action );
1122
  }
1123
 
 
 
 
 
 
1124
  function bp_action_variables() {
1125
  global $bp;
1126
  return apply_filters( 'bp_action_variables', $bp->action_variables );
1127
  }
1128
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1129
 
1130
  ?>
15
  * @package BuddyPress Core
16
  * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
17
  */
18
+ function bp_get_loggedin_user_nav() {
19
  global $bp, $current_blog;
20
 
 
 
 
21
  /* Loop through each navigation item */
22
  foreach( (array) $bp->bp_nav as $nav_item ) {
23
  /* If the current component matches the nav item id, then add a highlight CSS class. */
24
+ if ( $bp->active_components[$bp->current_component] == $nav_item['css_id'] ) {
25
  $selected = ' class="current"';
26
  } else {
27
  $selected = '';
34
  $selected = '';
35
 
36
  if ( function_exists('friends_install') ) {
37
+ if ( $nav_item['css_id'] == $bp->friends->id ) {
38
  if ( friends_check_friendship( $bp->loggedin_user->id, $bp->displayed_user->id ) )
39
  $selected = ' class="current"';
40
  }
42
  }
43
 
44
  /* echo out the final list item */
45
+ echo apply_filters( 'bp_get_loggedin_user_nav_' . $nav_item['css_id'], '<li id="li-nav-' . $nav_item['css_id'] . '" ' . $selected . '><a id="my-' . $nav_item['css_id'] . '" href="' . $nav_item['link'] . '">' . $nav_item['name'] . '</a></li>', &$nav_item );
46
  }
47
 
48
  /* Always add a log out list item to the end of the navigation */
49
  if ( function_exists( 'wp_logout_url' ) ) {
50
+ $logout_link = '<li><a id="wp-logout" href="' . wp_logout_url( $bp->root_domain ) . '">' . __( 'Log Out', 'buddypress' ) . '</a></li>';
51
  } else {
52
+ $logout_link = '<li><a id="wp-logout" href="' . site_url() . '/wp-login.php?action=logout&amp;redirect_to=' . $bp->root_domain . '">' . __( 'Log Out', 'buddypress' ) . '</a></li>';
53
  }
54
+
55
+ echo apply_filters( 'bp_logout_nav_link', $logout_link );
56
  }
57
+ /* DEPRECATED - use bp_get_loggedin_user_nav() */
58
+ function bp_get_nav() { bp_get_loggedin_user_nav(); }
59
+
60
+ /**
61
+ * bp_get_displayed_user_nav()
62
+ * TEMPLATE TAG
63
+ *
64
+ * Uses the $bp->bp_users_nav global to render out the user navigation when viewing another user other than
65
+ * yourself.
66
+ *
67
+ * @package BuddyPress Core
68
+ * @global $bp The global BuddyPress settings variable created in bp_core_setup_globals()
69
+ */
70
+ function bp_get_displayed_user_nav() {
71
+ global $bp;
72
 
73
+ foreach ( $bp->bp_nav as $user_nav_item ) {
74
+ if ( !$user_nav_item['show_for_displayed_user'] )
75
+ continue;
76
+
77
+ if ( $bp->current_component == $user_nav_item['css_id'] )
78
+ $selected = ' class="current"';
79
+ else
80
+ $selected = '';
81
+
82
+ if ( $bp->loggedin_user->domain )
83
+ $link = str_replace( $bp->loggedin_user->domain, $bp->displayed_user->domain, $user_nav_item['link'] );
84
+ else
85
+ $link = $bp->displayed_user->domain . $user_nav_item['link'];
86
+
87
+ echo apply_filters( 'bp_get_displayed_user_nav_' . $user_nav_item['css_id'], '<li id="li-subnav-' . $user_nav_item['css_id'] . '" ' . $selected . '><a id="user-' . $user_nav_item['css_id'] . '" href="' . $link . '">' . $user_nav_item['name'] . '</a></li>', &$user_nav_item );
88
+ }
89
+ }
90
+ /* DEPRECATED - use bp_get_displayed_user_nav() */
91
+ function bp_get_user_nav() { bp_get_displayed_user_nav(); }
92
+
93
  /**
94
  * bp_get_options_nav()
95
  * TEMPLATE TAG
119
  return false;
120
 
121
  /* Loop through each navigation item */
122
+ foreach ( $bp->bp_options_nav[$bp->current_component] as $subnav_item ) {
123
+ if ( !$subnav_item['user_has_access'] )
124
+ continue;
 
125
 
126
  /* If the current action or an action variable matches the nav item id, then add a highlight CSS class. */
127
+ if ( $subnav_item['slug'] == $bp->current_action ) {
128
  $selected = ' class="current"';
129
  } else {
130
  $selected = '';
131
  }
132
 
133
  /* echo out the final list item */
134
+ echo apply_filters( 'bp_get_options_nav_' . $subnav_item['css_id'], '<li id="li-subnav-' . $subnav_item['css_id'] . '" ' . $selected . '><a id="' . $subnav_item['css_id'] . '" href="' . $subnav_item['link'] . '">' . $subnav_item['name'] . '</a></li>', $subnav_item );
135
  }
136
  } else {
137
+ /* If we get here we are viewing another user, so show the displayed user's nav items */
138
+ bp_get_displayed_user_nav();
 
 
139
  }
140
  }
141
 
142
+ function bp_get_options_title() {
 
 
 
 
 
 
 
 
 
 
143
  global $bp;
144
+
145
+ if ( empty( $bp->bp_options_title ) )
146
+ $bp->bp_options_title = __( 'Options', 'buddypress' );
147
+
148
+ echo apply_filters( 'bp_get_options_title', attribute_escape( $bp->bp_options_title ) );
 
 
 
 
 
 
 
 
149
  }
150
+
151
+
152
+ /** AVATAR TEMPLATE TAGS *******************************************************/
153
 
154
  /**
155
  * bp_has_options_avatar()
170
  return true;
171
  }
172
 
 
 
 
 
 
 
 
 
 
 
173
  function bp_get_options_avatar() {
174
  global $bp;
175
 
176
  echo apply_filters( 'bp_get_options_avatar', $bp->bp_options_avatar );
177
  }
178
 
 
 
 
 
 
 
 
 
 
179
  function bp_comment_author_avatar() {
180
  global $comment;
181
 
182
+ if ( function_exists('bp_core_fetch_avatar') ) {
183
+ echo apply_filters( 'bp_comment_author_avatar', bp_core_fetch_avatar( array( 'item_id' => $comment->user_id, 'type' => 'thumb' ) ) );
184
  } else if ( function_exists('get_avatar') ) {
185
  get_avatar();
186
  }
189
  function bp_post_author_avatar() {
190
  global $post;
191
 
192
+ if ( function_exists('bp_core_fetch_avatar') ) {
193
+ echo apply_filters( 'bp_post_author_avatar', bp_core_fetch_avatar( array( 'item_id' => $post->post_author, 'type' => 'thumb' ) ) );
194
  } else if ( function_exists('get_avatar') ) {
195
  get_avatar();
196
  }
197
  }
198
 
199
+ function bp_loggedin_user_avatar( $args = '' ) {
200
+ echo bp_get_loggedin_user_avatar( $args );
201
+ }
202
+ function bp_get_loggedin_user_avatar( $args = '' ) {
203
+ global $bp;
204
+
205
+ $defaults = array(
206
+ 'type' => 'thumb',
207
+ 'width' => false,
208
+ 'height' => false
209
+ );
210
+
211
+ $r = wp_parse_args( $args, $defaults );
212
+ extract( $r, EXTR_SKIP );
213
+
214
+ return apply_filters( 'bp_get_loggedin_user_avatar', bp_core_fetch_avatar( array( 'item_id' => $bp->loggedin_user->id, 'type' => $type, 'width' => $width, 'height' => $height ) ) );
215
+ }
216
+
217
+ function bp_displayed_user_avatar( $args = '' ) {
218
+ echo bp_get_displayed_user_avatar( $args );
219
+ }
220
+ function bp_get_displayed_user_avatar( $args = '' ) {
221
+ global $bp;
222
+
223
+ $defaults = array(
224
+ 'type' => 'thumb',
225
+ 'width' => false,
226
+ 'height' => false
227
+ );
228
+
229
+ $r = wp_parse_args( $args, $defaults );
230
+ extract( $r, EXTR_SKIP );
231
+
232
+ return apply_filters( 'bp_get_displayed_user_avatar', bp_core_fetch_avatar( array( 'item_id' => $bp->displayed_user->id, 'type' => $type, 'width' => $width, 'height' => $height ) ) );
233
+ }
234
+
235
+ function bp_avatar_admin_step() {
236
+ echo bp_get_avatar_admin_step();
237
+ }
238
+ function bp_get_avatar_admin_step() {
239
+ global $bp;
240
+
241
+ return apply_filters( 'bp_get_avatar_admin_step', $bp->avatar_admin->step );
242
+ }
243
+
244
+ function bp_avatar_to_crop() {
245
+ echo bp_get_avatar_to_crop();
246
  }
247
+ function bp_get_avatar_to_crop() {
248
+ global $bp;
249
 
250
+ return apply_filters( 'bp_get_avatar_to_crop', $bp->avatar_admin->image->url );
251
+ }
252
+
253
+ function bp_avatar_to_crop_src() {
254
+ echo bp_get_avatar_to_crop_src();
255
+ }
256
+ function bp_get_avatar_to_crop_src() {
257
+ global $bp;
258
+
259
+ return apply_filters( 'bp_get_avatar_to_crop_src', str_replace( WP_CONTENT_DIR, '', $bp->avatar_admin->image->dir ) );
260
+ }
261
+
262
+ function bp_avatar_cropper() {
263
  global $bp;
264
 
265
+ echo '<img id="avatar-to-crop" class="avatar" src="' . $bp->avatar_admin->image . '" />';
 
 
 
266
  }
267
 
268
  function bp_site_name() {
269
+ echo apply_filters( 'bp_site_name', get_blog_option( BP_ROOT_BLOG, 'blogname' ) );
270
  }
271
 
272
  function bp_is_home() {
278
  return false;
279
  }
280
 
 
 
 
 
 
 
 
 
281
  function bp_last_activity( $user_id = false, $echo = true ) {
282
  global $bp;
283
 
292
  return apply_filters( 'bp_last_activity', $last_activity );
293
  }
294
 
 
 
 
 
 
 
 
 
 
 
295
  function bp_user_link() {
296
  global $bp;
297
 
316
  $ud = get_userdata( $bp->displayed_user->id );
317
  ?>
318
 
319
+ <div class="bp-widget wp-profile">
320
  <h4><?php _e( 'My Profile' ) ?></h4>
321
 
322
  <table class="wp-profile-fields">
386
  }
387
 
388
  function bp_get_profile_header() {
389
+ locate_template( array( '/profile/profile-header.php' ), true );
390
  }
391
 
392
  function bp_exists( $component_name ) {
454
  }
455
 
456
  function bp_get_plugin_sidebar() {
457
+ locate_template( array( 'plugin-sidebar.php' ), true );
 
458
  }
459
 
460
  function bp_is_blog_page() {
461
  global $bp, $is_member_page;
462
+
463
  if ( $bp->current_component == BP_HOME_BLOG_SLUG )
464
  return true;
465
 
466
  if ( !$is_member_page && !in_array( $bp->current_component, $bp->root_components ) )
467
  return true;
468
+
469
  return false;
470
  }
471
 
485
  $title = __( 'Blog &#8212; Categories &#8212; ' . ucwords( $wp_query->query_vars['category_name'] ), 'buddypress' );
486
  } else if ( is_tag() ) {
487
  $title = __( 'Blog &#8212; Tags &#8212; ' . ucwords( $wp_query->query_vars['tag'] ), 'buddypress' );
488
+ } else
489
  $title = __( 'Blog', 'buddypress' );
490
+
491
  } else if ( !empty( $bp->displayed_user->fullname ) ) {
492
  $title = strip_tags( $bp->displayed_user->fullname . ' &#8212; ' . ucwords( $bp->current_component ) . ' &#8212; ' . $bp->bp_options_nav[$bp->current_component][$bp->current_action]['name'] );
493
  } else if ( $bp->is_single_item ) {
531
  function bp_has_custom_signup_page() {
532
  if ( file_exists( WP_CONTENT_DIR . '/themes/' . get_blog_option( BP_ROOT_BLOG, 'template') . '/register.php') )
533
  return true;
534
+
535
+ if ( file_exists( WP_CONTENT_DIR . '/themes/' . get_blog_option( BP_ROOT_BLOG, 'template') . '/registration/register.php') )
536
+ return true;
537
+
538
  return false;
539
  }
540
 
541
+ function bp_signup_page( $deprecated = true ) {
542
+ if ( !$deprecated )
543
+ return bp_get_signup_page();
544
+ else
545
+ echo bp_get_signup_page();
 
 
 
 
 
 
 
 
 
546
  }
547
+ function bp_get_signup_page() {
548
+ global $bp;
549
+
550
+ if ( bp_has_custom_signup_page() ) {
551
+ return apply_filters( 'bp_get_signup_page', $bp->root_domain . '/' . BP_REGISTER_SLUG );
552
+ } else {
553
+ return apply_filters( 'bp_get_signup_page', $bp->root_domain . '/wp-signup.php' );
554
+ }
555
+ }
556
 
557
  function bp_has_custom_activation_page() {
558
+ if ( file_exists( WP_CONTENT_DIR . '/themes/' . get_blog_option( BP_ROOT_BLOG, 'template') . '/activate.php') )
559
+ return true;
560
+
561
+ if ( file_exists( WP_CONTENT_DIR . '/themes/' . get_blog_option( BP_ROOT_BLOG, 'template') . '/registration/activate.php') )
562
  return true;
563
 
564
  return false;
597
  if ( function_exists( 'groups_install' ) ) {
598
  $selection_box .= '<option value="groups">' . __( 'Groups', 'buddypress' ) . '</option>';
599
  }
600
+
601
+ if ( function_exists( 'bp_forums_setup' ) && !(int) get_site_option( 'bp-disable-forum-directory' ) ) {
602
+ $selection_box .= '<option value="forums">' . __( 'Forums', 'buddypress' ) . '</option>';
603
+ }
604
 
605
  if ( function_exists( 'bp_blogs_install' ) ) {
606
  $selection_box .= '<option value="blogs">' . __( 'Blogs', 'buddypress' ) . '</option>';
625
  echo apply_filters( 'bp_search_form', $form );
626
  }
627
 
628
+ function bp_log_out_link() {
629
  global $bp;
630
+ if ( function_exists('wp_logout_url') )
631
+ $logout_link = '<a href="' . wp_logout_url( $bp->root_domain ) . '">' . __( 'Log Out', 'buddypress' ) . '</a>';
632
+ else
633
+ $logout_link = '<a href="' . $bp->root_domain . '/wp-login.php?action=logout&amp;redirect_to=' . $bp->root_domain . '">' . __( 'Log Out', 'buddypress' ) . '</a>';
 
 
 
 
 
 
 
634
 
635
+ echo apply_filters( 'bp_logout_link', $logout_link );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
636
  }
637
 
638
  function bp_profile_wire_can_post() {
678
  do_action( 'bp_custom_profile_sidebar_boxes' );
679
  }
680
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
681
  function bp_is_directory() {
682
  global $bp;
683
 
696
  */
697
  function bp_create_excerpt( $text, $excerpt_length = 55, $filter_shortcodes = true ) { // Fakes an excerpt if needed
698
  $text = str_replace(']]>', ']]&gt;', $text);
699
+
 
700
  if ( $filter_shortcodes )
701
  $text = preg_replace( '|\[(.+?)\](.+?\[/\\1\])?|s', '', $text );
702
 
707
  $text = implode(' ', $words);
708
  }
709
 
710
+ return apply_filters( 'bp_create_excerpt', $text );
711
  }
712
+ add_filter( 'bp_create_excerpt', 'wptexturize' );
713
+ add_filter( 'bp_create_excerpt', 'convert_smilies' );
714
+ add_filter( 'bp_create_excerpt', 'convert_chars' );
715
+ add_filter( 'bp_create_excerpt', 'wpautop' );
716
+ add_filter( 'bp_create_excerpt', 'wp_trim_excerpt' );
717
+ add_filter( 'bp_create_excerpt', 'stripslashes_deep' );
718
+ add_filter( 'bp_create_excerpt', 'force_balance_tags' );
719
 
720
  /**
721
  * bp_is_serialized()
739
  return false;
740
  }
741
 
742
+ /*** Signup form template tags **********************/
743
+
744
+ function bp_signup_username_value() {
745
+ echo bp_get_signup_username_value();
746
+ }
747
+ function bp_get_signup_username_value() {
748
+ return apply_filters( 'bp_get_signup_username_value', $_POST['signup_username'] );
749
+ }
750
+
751
+ function bp_signup_email_value() {
752
+ echo bp_get_signup_email_value();
753
+ }
754
+ function bp_get_signup_email_value() {
755
+ return apply_filters( 'bp_get_signup_email_value', $_POST['signup_email'] );
756
+ }
757
+
758
+ function bp_signup_with_blog_value() {
759
+ echo bp_get_signup_with_blog_value();
760
+ }
761
+ function bp_get_signup_with_blog_value() {
762
+ return apply_filters( 'bp_get_signup_with_blog_value', $_POST['signup_with_blog'] );
763
+ }
764
+
765
+ function bp_signup_blog_url_value() {
766
+ echo bp_get_signup_blog_url_value();
767
+ }
768
+ function bp_get_signup_blog_url_value() {
769
+ return apply_filters( 'bp_get_signup_blog_url_value', $_POST['signup_blog_url'] );
770
+ }
771
+
772
+ function bp_signup_blog_title_value() {
773
+ echo bp_get_signup_blog_title_value();
774
+ }
775
+ function bp_get_signup_blog_title_value() {
776
+ return apply_filters( 'bp_get_signup_blog_title_value', $_POST['signup_blog_title'] );
777
+ }
778
+
779
+ function bp_signup_blog_privacy_value() {
780
+ echo bp_get_signup_blog_privacy_value();
781
+ }
782
+ function bp_get_signup_blog_privacy_value() {
783
+ return apply_filters( 'bp_get_signup_blog_privacy_value', $_POST['signup_blog_privacy'] );
784
+ }
785
+
786
+ function bp_signup_avatar_dir_value() {
787
+ echo bp_get_signup_avatar_dir_value();
788
+ }
789
+ function bp_get_signup_avatar_dir_value() {
790
+ global $bp;
791
+
792
+ return apply_filters( 'bp_get_signup_avatar_dir_value', $bp->signup->avatar_dir );
793
+ }
794
+
795
+ function bp_current_signup_step() {
796
+ echo bp_get_current_signup_step();
797
+ }
798
+ function bp_get_current_signup_step() {
799
+ global $bp;
800
+
801
+ return $bp->signup->step;
802
+ }
803
+
804
+ function bp_signup_avatar( $args = '' ) {
805
+ echo bp_get_signup_avatar( $args = '' );
806
+ }
807
+ function bp_get_signup_avatar( $args = '' ) {
808
+ global $bp;
809
+
810
+ $defaults = array(
811
+ 'size' => BP_AVATAR_FULL_WIDTH,
812
+ 'class' => 'avatar',
813
+ 'alt' => __( 'Your Avatar', 'buddypress' )
814
+ );
815
+
816
+ $r = wp_parse_args( $args, $defaults );
817
+ extract( $r, EXTR_SKIP );
818
+
819
+ $signup_avatar_dir = ( !empty( $_POST['signup_avatar_dir'] ) ) ? $_POST['signup_avatar_dir'] : $bp->signup->avatar_dir;
820
+
821
+ if ( empty( $signup_avatar_dir ) ) {
822
+ if ( empty( $bp->grav_default->user ) ) {
823
+ $default_grav = 'wavatar';
824
+ } else if ( 'mystery' == $bp->grav_default->user ) {
825
+ $default_grav = BP_PLUGIN_URL . '/bp-core/images/mystery-man.jpg';
826
+ } else {
827
+ $default_grav = $bp->grav_default->user;
828
+ }
829
+
830
+ $gravatar_url = apply_filters( 'bp_gravatar_url', 'http://www.gravatar.com/avatar/' );
831
+ return apply_filters( 'bp_get_signup_avatar', '<img src="' . $gravatar_url . md5( $_POST['signup_email'] ) . '?d=' . $default_grav . '&amp;s=' . $size ) . '" width="' . $size . '" height="' . $size . '" alt="' . $alt . '" class="' . $class . '" />';
832
+ } else {
833
+ return apply_filters( 'bp_get_signup_avatar', bp_core_fetch_avatar( array( 'item_id' => $signup_avatar_dir, 'object' => 'signup', 'avatar_dir' => 'avatars/signups', 'type' => 'full', 'width' => $size, 'height' => $size, 'alt' => $alt, 'class' => $class ) ) );
834
+ }
835
+ }
836
+
837
+ function bp_signup_allowed() {
838
+ echo bp_get_signup_allowed();
839
+ }
840
+ function bp_get_signup_allowed() {
841
+ return get_site_option( 'registration' );
842
+ }
843
+
844
+ function bp_account_was_activated() {
845
+ global $bp;
846
+
847
+ return $bp->activation_complete;
848
+ }
849
+
850
 
851
  /*** CUSTOM LOOP TEMPLATE CLASSES *******************/
852
 
917
  $this->member_count = count($this->members);
918
  }
919
 
920
+ if ( (int) $this->total_member_count && (int) $this->pag_num ) {
921
+ $this->pag_links = paginate_links( array(
922
+ 'base' => add_query_arg( 'upage', '%#%' ),
923
+ 'format' => '',
924
+ 'total' => ceil( (int) $this->total_member_count / (int) $this->pag_num ),
925
+ 'current' => (int) $this->pag_page,
926
+ 'prev_text' => '&laquo;',
927
+ 'next_text' => '&raquo;',
928
+ 'mid_size' => 1
929
+ ));
930
+ }
931
  }
932
 
933
  function has_members() {
1032
  $to_num = ( $from_num + ( $site_members_template->pag_num - 1 ) > $site_members_template->total_member_count ) ? $site_members_template->total_member_count : $from_num + ( $site_members_template->pag_num - 1) ;
1033
 
1034
  echo sprintf( __( 'Viewing member %d to %d (of %d members)', 'buddypress' ), $from_num, $to_num, $site_members_template->total_member_count ); ?> &nbsp;
1035
+ <span class="ajax-loader"></span><?php
1036
  }
1037
 
1038
  function bp_site_members_pagination_links() {
1080
  return apply_filters( 'bp_get_the_site_member_name', $site_members_template->member->fullname );
1081
  }
1082
  add_filter( 'bp_get_the_site_member_name', 'wp_filter_kses' );
1083
+ add_filter( 'bp_get_the_site_member_name', 'stripslashes' );
1084
 
1085
  function bp_the_site_member_last_active() {
1086
  echo bp_get_the_site_member_last_active();
1154
 
1155
  function bp_directory_members_search_form() {
1156
  global $bp; ?>
1157
+ <form action="" method="get" id="search-members-form">
1158
+ <label><input type="text" name="s" id="members_search" value="<?php if ( isset( $_GET['s'] ) ) { echo attribute_escape( $_GET['s'] ); } else { _e( 'Search anything...', 'buddypress' ); } ?>" onfocus="if (this.value == '<?php _e( 'Search anything...', 'buddypress' ) ?>') {this.value = '';}" onblur="if (this.value == '') {this.value = '<?php _e( 'Search anything...', 'buddypress' ) ?>';}" /></label>
1159
  <input type="submit" id="members_search_submit" name="members_search_submit" value="<?php _e( 'Search', 'buddypress' ) ?>" />
1160
  <?php wp_nonce_field( 'directory_members', '_wpnonce-member-filter' ) ?>
1161
  </form>
1228
  return apply_filters( 'bp_current_action', $bp->current_action );
1229
  }
1230
 
1231
+ function bp_current_item() {
1232
+ global $bp;
1233
+ return apply_filters( 'bp_current_item', $bp->current_item );
1234
+ }
1235
+
1236
  function bp_action_variables() {
1237
  global $bp;
1238
  return apply_filters( 'bp_action_variables', $bp->action_variables );
1239
  }
1240
 
1241
+ function bp_root_domain() {
1242
+ echo bp_get_root_domain();
1243
+ }
1244
+ function bp_get_root_domain() {
1245
+ global $bp;
1246
+
1247
+ return $bp->root_domain;
1248
+ }
1249
+
1250
+ /* Template is_() functions to determine the current page */
1251
+
1252
+ function bp_is_profile_component() {
1253
+ global $bp;
1254
+
1255
+ if ( BP_XPROFILE_SLUG == $bp->current_component )
1256
+ return true;
1257
+
1258
+ return false;
1259
+ }
1260
+
1261
+ function bp_is_activity_component() {
1262
+ global $bp;
1263
+
1264
+ if ( BP_ACTIVITY_SLUG == $bp->current_component )
1265
+ return true;
1266
+
1267
+ return false;
1268
+ }
1269
+
1270
+ function bp_is_blogs_component() {
1271
+ global $bp;
1272
+
1273
+ if ( BP_BLOGS_SLUG == $bp->current_component )
1274
+ return true;
1275
+
1276
+ return false;
1277
+ }
1278
+
1279
+ function bp_is_wire_component() {
1280
+ global $bp;
1281
+
1282
+ if ( BP_WIRE_SLUG == $bp->current_action || in_array( BP_WIRE_SLUG, (array)$bp->action_variables ) )
1283
+ return true;
1284
+
1285
+ return false;
1286
+ }
1287
+
1288
+ function bp_is_messages_component() {
1289
+ global $bp;
1290
+
1291
+ if ( BP_MESSAGES_SLUG == $bp->current_component )
1292
+ return true;
1293
+
1294
+ return false;
1295
+ }
1296
+
1297
+ function bp_is_friends_component() {
1298
+ global $bp;
1299
+
1300
+ if ( BP_FRIENDS_SLUG == $bp->current_component )
1301
+ return true;
1302
+
1303
+ return false;
1304
+ }
1305
+
1306
+ function bp_is_groups_component() {
1307
+ global $bp;
1308
+
1309
+ if ( BP_GROUPS_SLUG == $bp->current_component )
1310
+ return true;
1311
+
1312
+ return false;
1313
+ }
1314
+
1315
+ function bp_is_settings_component() {
1316
+ global $bp;
1317
+
1318
+ if ( BP_SETTINGS_SLUG == $bp->current_component )
1319
+ return true;
1320
+
1321
+ return false;
1322
+ }
1323
+
1324
+ function bp_is_user_activity() {
1325
+ global $bp;
1326
+
1327
+ if ( BP_ACTIVITY_SLUG == $bp->current_component && ( !$bp->current_action || 'my-activity' == $bp->current_action ) )
1328
+ return true;
1329
+
1330
+ return false;
1331
+ }
1332
+
1333
+ function bp_is_user_friends_activity() {
1334
+ global $bp;
1335
+
1336
+ if ( BP_ACTIVITY_SLUG == $bp->current_component && 'my-friends' == $bp->current_action )
1337
+ return true;
1338
+
1339
+ return false;
1340
+ }
1341
+
1342
+ function bp_is_user_profile() {
1343
+ global $bp;
1344
+
1345
+ if ( BP_XPROFILE_SLUG == $bp->current_component )
1346
+ return true;
1347
+
1348
+ return false;
1349
+ }
1350
+
1351
+ function bp_is_profile_edit() {
1352
+ global $bp;
1353
+
1354
+ if ( BP_XPROFILE_SLUG == $bp->current_component && 'edit' == $bp->current_action )
1355
+ return true;
1356
+
1357
+ return false;
1358
+ }
1359
+
1360
+ function bp_is_change_avatar() {
1361
+ global $bp;
1362
+
1363
+ if ( BP_XPROFILE_SLUG == $bp->current_component && 'change-avatar' == $bp->current_action )
1364
+ return true;
1365
+
1366
+ return false;
1367
+ }
1368
+
1369
+ function bp_is_profile_wire() {
1370
+ global $bp;
1371
+
1372
+ if ( BP_XPROFILE_SLUG == $bp->current_component && 'wire' == $bp->current_action )
1373
+ return true;
1374
+
1375
+ return false;
1376
+ }
1377
+
1378
+ function bp_is_user_groups() {
1379
+ global $bp;
1380
+
1381
+ if ( BP_GROUPS_SLUG == $bp->current_component && ( !$bp->current_action || 'my-groups' == $bp->current_action ) )
1382
+ return true;
1383
+
1384
+ return false;
1385
+ }
1386
+
1387
+ function bp_is_group_home() {
1388
+ global $bp;
1389
+
1390
+ if ( BP_GROUPS_SLUG == $bp->current_component && $bp->is_single_item && ( !$bp->current_action || 'home' == $bp->current_action ) )
1391
+ return true;
1392
+
1393
+ return false;
1394
+ }
1395
+
1396
+ function bp_is_group_create() {
1397
+ global $bp;
1398
+
1399
+ if ( BP_GROUPS_SLUG == $bp->current_component && 'create' == $bp->current_action )
1400
+ return true;
1401
+
1402
+ return false;
1403
+ }
1404
+
1405
+
1406
+ function bp_is_group_admin_page() {
1407
+ global $bp;
1408
+
1409
+ if ( BP_GROUPS_SLUG == $bp->current_component && $bp->is_single_item && 'admin' == $bp->current_action )
1410
+ return true;
1411
+
1412
+ return false;
1413
+ }
1414
+
1415
+ function bp_is_group_wire() {
1416
+ global $bp;
1417
+
1418
+ if ( BP_GROUPS_SLUG == $bp->current_component && $bp->is_single_item && 'wire' == $bp->current_action )
1419
+ return true;
1420
+
1421
+ return false;
1422
+ }
1423
+
1424
+ function bp_is_group_forum() {
1425
+ global $bp;
1426
+
1427
+ if ( BP_GROUPS_SLUG == $bp->current_component && $bp->is_single_item && 'forum' == $bp->current_action )
1428
+ return true;
1429
+
1430
+ return false;
1431
+ }
1432
+
1433
+ function bp_is_group_forum_topic() {
1434
+ global $bp;
1435
+
1436
+ if ( BP_GROUPS_SLUG == $bp->current_component && $bp->is_single_item && 'forum' == $bp->current_action && 'topic' == $bp->action_variables[0] )
1437
+ return true;
1438
+
1439
+ return false;
1440
+ }
1441
+
1442
+ function bp_is_group_members() {
1443
+ global $bp;
1444
+
1445
+ if ( BP_GROUPS_SLUG == $bp->current_component && $bp->is_single_item && 'members' == $bp->current_action )
1446
+ return true;
1447
+
1448
+ return false;
1449
+ }
1450
+
1451
+ function bp_is_group_invites() {
1452
+ global $bp;
1453
+
1454
+ if ( BP_GROUPS_SLUG == $bp->current_component && 'invites' == $bp->current_action )
1455
+ return true;
1456
+
1457
+ return false;
1458
+ }
1459
+
1460
+ function bp_is_group_leave() {
1461
+ global $bp;
1462
+
1463
+ if ( BP_GROUPS_SLUG == $bp->current_component && $bp->is_single_item && 'leave-group' == $bp->current_action )
1464
+ return true;
1465
+
1466
+ return false;
1467
+ }
1468
+
1469
+ function bp_is_user_blogs() {
1470
+ global $bp;
1471
+
1472
+ if ( BP_BLOGS_SLUG == $bp->current_component && ( !$bp->current_action || 'my-blogs' == $bp->current_action ) )
1473
+ return true;
1474
+
1475
+ return false;
1476
+ }
1477
+
1478
+ function bp_is_user_recent_posts() {
1479
+ global $bp;
1480
+
1481
+ if ( BP_BLOGS_SLUG == $bp->current_component && 'recent-posts' == $bp->current_action )
1482
+ return true;
1483
+
1484
+ return false;
1485
+ }
1486
+
1487
+ function bp_is_user_recent_commments() {
1488
+ global $bp;
1489
+
1490
+ if ( BP_BLOGS_SLUG == $bp->current_component && 'recent-comments' == $bp->current_action )
1491
+ return true;
1492
+
1493
+ return false;
1494
+ }
1495
+
1496
+ function bp_is_create_blog() {
1497
+ global $bp;
1498
+
1499
+ if ( BP_BLOGS_SLUG == $bp->current_component && 'create-a-blog' == $bp->current_action )
1500
+ return true;
1501
+
1502
+ return false;
1503
+ }
1504
+
1505
+ function bp_is_user_friends() {
1506
+ global $bp;
1507
+
1508
+ if ( BP_FRIENDS_SLUG == $bp->current_component && ( !$bp->current_action || 'my-friends' == $bp->current_action ) )
1509
+ return true;
1510
+
1511
+ return false;
1512
+ }
1513
+
1514
+ function bp_is_friend_requests() {
1515
+ global $bp;
1516
+
1517
+ if ( BP_FRIENDS_SLUG == $bp->current_component && 'requests' == $bp->current_action )
1518
+ return true;
1519
+
1520
+ return false;
1521
+ }
1522
+
1523
+ function bp_is_messages_inbox() {
1524
+ global $bp;
1525
+
1526
+ if ( BP_MESSAGES_SLUG == $bp->current_component && ( !$bp->current_action || 'inbox' == $bp->current_action ) )
1527
+ return true;
1528
+
1529
+ return false;
1530
+ }
1531
+
1532
+ function bp_is_messages_sentbox() {
1533
+ global $bp;
1534
+
1535
+ if ( BP_MESSAGES_SLUG == $bp->current_component && 'sentbox' == $bp->current_action )
1536
+ return true;
1537
+
1538
+ return false;
1539
+ }
1540
+
1541
+
1542
+ function bp_is_notices() {
1543
+ global $bp;
1544
+
1545
+ if ( BP_MESSAGES_SLUG == $bp->current_component && 'notices' == $bp->current_action )
1546
+ return true;
1547
+
1548
+ return false;
1549
+ }
1550
+
1551
+
1552
+ function bp_is_messages_compose_screen() {
1553
+ global $bp;
1554
+
1555
+ if ( BP_MESSAGES_SLUG == $bp->current_component && 'compose' == $bp->current_action )
1556
+ return true;
1557
+
1558
+ return false;
1559
+ }
1560
+
1561
+ function bp_is_single_item() {
1562
+ global $bp;
1563
+
1564
+ if ( $bp->is_single_item )
1565
+ return true;
1566
+
1567
+ return false;
1568
+ }
1569
+
1570
+ function bp_is_activation_page() {
1571
+ global $bp;
1572
+
1573
+ if ( BP_ACTIVATION_SLUG == $bp->current_component )
1574
+ return true;
1575
+
1576
+ return false;
1577
+ }
1578
+
1579
+ function bp_is_register_page() {
1580
+ global $bp;
1581
+
1582
+ if ( BP_REGISTER_SLUG == $bp->current_component )
1583
+ return true;
1584
+
1585
+ return false;
1586
+ }
1587
+
1588
+ /* Use the above is_() functions to output a body class for each page */
1589
+
1590
+ function bp_the_body_class() {
1591
+ echo bp_get_the_body_class();
1592
+ }
1593
+ function bp_get_the_body_class( $wp_classes, $custom_classes ) {
1594
+ global $bp;
1595
+
1596
+ if ( bp_is_blog_page() && is_front_page() && $bp->current_component != BP_HOME_BLOG_SLUG )
1597
+ $bp_classes[] = 'home-page';
1598
+
1599
+ if ( bp_is_blog_page() || bp_is_register_page() || bp_is_activation_page() )
1600
+ $bp_classes[] = 'blog-page';
1601
+
1602
+ if ( !bp_is_blog_page() && !bp_is_register_page() && !bp_is_activation_page() )
1603
+ $bp_classes[] = 'internal-page';
1604
+
1605
+ if ( bp_is_directory() )
1606
+ $bp_classes[] = 'directory';
1607
+
1608
+ if ( bp_is_user_profile() && !bp_is_blog_page() )
1609
+ $bp_classes[] = 'profile';
1610
+
1611
+ if ( bp_is_activity_component() && !bp_is_blog_page() )
1612
+ $bp_classes[] = 'activity';
1613
+
1614
+ if ( bp_is_blogs_component() && !bp_is_blog_page() )
1615
+ $bp_classes[] = 'blogs';
1616
+
1617
+ if ( bp_is_wire_component() && !bp_is_blog_page() )
1618
+ $bp_classes[] = 'wire';
1619
+
1620
+ if ( bp_is_messages_component() && !bp_is_blog_page() )
1621
+ $bp_classes[] = 'messages';
1622
+
1623
+ if ( bp_is_friends_component() && !bp_is_blog_page() )
1624
+ $bp_classes[] = 'friends';
1625
+
1626
+ if ( bp_is_groups_component() && !bp_is_blog_page() )
1627
+ $bp_classes[] = 'groups';
1628
+
1629
+ if ( bp_is_settings_component() && !bp_is_blog_page() )
1630
+ $bp_classes[] = 'settings';
1631
+
1632
+ if ( bp_is_single_item() )
1633
+ $bp_classes[] = 'single-item';
1634
+
1635
+ if ( bp_is_messages_inbox() )
1636
+ $bp_classes[] = 'inbox';
1637
+
1638
+ if ( bp_is_messages_sentbox() )
1639
+ $bp_classes[] = 'sentbox';
1640
+
1641
+ if ( bp_is_messages_compose_screen() )
1642
+ $bp_classes[] = 'compose';
1643
+
1644
+ if ( bp_is_notices() )
1645
+ $bp_classes[] = 'notices';
1646
+
1647
+ if ( bp_is_friend_requests() )
1648
+ $bp_classes[] = 'friend-requests';
1649
+
1650
+ if ( bp_is_user_friends() )
1651
+ $bp_classes[] = 'my-friends';
1652
+
1653
+ if ( bp_is_create_blog() )
1654
+ $bp_classes[] = 'create-blog';
1655
+
1656
+ if ( bp_is_user_recent_commments() )
1657
+ $bp_classes[] = 'recent-comments';
1658
+
1659
+ if ( bp_is_user_recent_posts() )
1660
+ $bp_classes[] = 'recent-posts';
1661
+
1662
+ if ( bp_is_user_blogs() && !bp_is_directory() )
1663
+ $bp_classes[] = 'my-blogs';
1664
+
1665
+ if ( bp_is_user_groups() && !bp_is_directory() )
1666
+ $bp_classes[] = 'my-groups';
1667
+
1668
+ if ( bp_is_group_leave() )
1669
+ $bp_classes[] = 'leave-group';
1670
+
1671
+ if ( bp_is_group_invites() )
1672
+ $bp_classes[] = 'group-invites';
1673
+
1674
+ if ( bp_is_group_members() )
1675
+ $bp_classes[] = 'group-members';
1676
+
1677
+ if ( bp_is_group_forum_topic() )
1678
+ $bp_classes[] = 'group-forum-topic';
1679
+
1680
+ if ( bp_is_group_forum() )
1681
+ $bp_classes[] = 'group-forum';
1682
+
1683
+ if ( bp_is_group_wire() )
1684
+ $bp_classes[] = 'group-wire';
1685
+
1686
+ if ( bp_is_group_admin_page() )
1687
+ $bp_classes[] = 'group-admin';
1688
+
1689
+ if ( bp_is_group_create() )
1690
+ $bp_classes[] = 'group-create';
1691
+
1692
+ if ( bp_is_group_home() )
1693
+ $bp_classes[] = 'group-home';
1694
+
1695
+ if ( bp_is_profile_wire() )
1696
+ $bp_classes[] = 'profile-wire';
1697
+
1698
+ if ( bp_is_change_avatar() )
1699
+ $bp_classes[] = 'change-avatar';
1700
+
1701
+ if ( bp_is_profile_edit() )
1702
+ $bp_classes[] = 'profile-edit';
1703
+
1704
+ if ( bp_is_user_friends_activity() )
1705
+ $bp_classes[] = 'friends-activity';
1706
+
1707
+ if ( bp_is_user_activity() )
1708
+ $bp_classes[] = 'my-activity';
1709
+
1710
+ if ( bp_is_register_page() )
1711
+ $bp_classes[] = 'registration';
1712
+
1713
+ if ( bp_is_activation_page() )
1714
+ $bp_classes[] = 'activation';
1715
+
1716
+ if ( is_user_logged_in() )
1717
+ $bp_classes[] = 'logged-in';
1718
+
1719
+ /* Add the current_component, current_action into the bp classes */
1720
+ if ( !bp_is_blog_page() ) {
1721
+ if ( !empty( $bp->current_component ) )
1722
+ $bp_classes[] = $bp->current_component;
1723
+
1724
+ if ( !empty( $bp->current_action ) )
1725
+ $bp_classes[] = $bp->current_action;
1726
+ }
1727
+
1728
+ /* We don't want WordPress blog classes to appear on non-blog pages. */
1729
+ if ( !bp_is_blog_page() || is_home() ) {
1730
+ /* Preserve any custom classes already set */
1731
+ if ( !empty( $custom_classes ) )
1732
+ $wp_classes = (array) $custom_classes;
1733
+ else
1734
+ $wp_classes = array();
1735
+ }
1736
+
1737
+ /* Merge WP classes with BP classes */
1738
+ $classes = array_merge( (array) $bp_classes, (array) $wp_classes );
1739
+
1740
+ /* Remove any duplicates */
1741
+ $classes = array_unique( $classes );
1742
+
1743
+ return apply_filters( 'bp_get_the_body_class', $classes, $bp_classes, $wp_classes, $custom_classes );
1744
+ }
1745
+ add_filter( 'body_class', 'bp_get_the_body_class', 10, 2 )
1746
+
1747
 
1748
  ?>
bp-core/bp-core-widgets.php CHANGED
@@ -13,7 +13,7 @@ add_action( 'plugins_loaded', 'bp_core_register_widgets' );
13
 
14
  class BP_Core_Welcome_Widget extends WP_Widget {
15
  function bp_core_welcome_widget() {
16
- parent::WP_Widget( false, $name = 'Welcome' );
17
  }
18
 
19
  function widget($args, $instance) {
@@ -70,9 +70,10 @@ add_filter( 'bp_core_welcome_widget_text', 'force_balance_tags' );
70
 
71
  class BP_Core_Members_Widget extends WP_Widget {
72
  function bp_core_members_widget() {
73
- parent::WP_Widget( false, $name = 'Members' );
74
- wp_enqueue_script( 'bp_core_widget_members-js', BP_PLUGIN_URL . '/bp-core/js/widget-members.js', array('jquery', 'jquery-livequery-pack') );
75
- wp_enqueue_style( 'bp_core_widget_members-css', BP_PLUGIN_URL . '/bp-core/css/widget-members.css' );
 
76
  }
77
 
78
  function widget($args, $instance) {
@@ -87,7 +88,7 @@ class BP_Core_Members_Widget extends WP_Widget {
87
 
88
  <?php if ( bp_has_site_members( 'type=newest&max=' . $instance['max_members'] ) ) : ?>
89
  <div class="item-options" id="members-list-options">
90
- <img id="ajax-loader-members" src="<?php echo $bp->core->image_base ?>/ajax-loader.gif" height="7" alt="<?php _e( 'Loading', 'buddypress' ) ?>" style="display: none;" />
91
  <a href="<?php echo site_url() . '/' . BP_MEMBERS_SLUG ?>" id="newest-members" class="selected"><?php _e( 'Newest', 'buddypress' ) ?></a> |
92
  <a href="<?php echo site_url() . '/' . BP_MEMBERS_SLUG ?>" id="recently-active-members"><?php _e( 'Active', 'buddypress' ) ?></a> |
93
  <a href="<?php echo site_url() . '/' . BP_MEMBERS_SLUG ?>" id="popular-members"><?php _e( 'Popular', 'buddypress' ) ?></a>
@@ -144,7 +145,7 @@ class BP_Core_Members_Widget extends WP_Widget {
144
 
145
  class BP_Core_Whos_Online_Widget extends WP_Widget {
146
  function bp_core_whos_online_widget() {
147
- parent::WP_Widget( false, $name = 'Who\'s Online Avatars' );
148
  }
149
 
150
  function widget($args, $instance) {
@@ -198,7 +199,7 @@ class BP_Core_Whos_Online_Widget extends WP_Widget {
198
 
199
  class BP_Core_Recently_Active_Widget extends WP_Widget {
200
  function bp_core_recently_active_widget() {
201
- parent::WP_Widget( false, $name = 'Recently Active Member Avatars' );
202
  }
203
 
204
  function widget($args, $instance) {
@@ -248,4 +249,71 @@ class BP_Core_Recently_Active_Widget extends WP_Widget {
248
  }
249
  }
250
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  ?>
13
 
14
  class BP_Core_Welcome_Widget extends WP_Widget {
15
  function bp_core_welcome_widget() {
16
+ parent::WP_Widget( false, $name = __( 'Welcome', 'buddypress' ) );
17
  }
18
 
19
  function widget($args, $instance) {
70
 
71
  class BP_Core_Members_Widget extends WP_Widget {
72
  function bp_core_members_widget() {
73
+ parent::WP_Widget( false, $name = __( 'Members', 'buddypress' ) );
74
+
75
+ if ( is_active_widget( false, false, $this->id_base ) )
76
+ wp_enqueue_script( 'bp_core_widget_members-js', BP_PLUGIN_URL . '/bp-core/js/widget-members.js', array('jquery', 'jquery-livequery-pack') );
77
  }
78
 
79
  function widget($args, $instance) {
88
 
89
  <?php if ( bp_has_site_members( 'type=newest&max=' . $instance['max_members'] ) ) : ?>
90
  <div class="item-options" id="members-list-options">
91
+ <span class="ajax-loader" id="ajax-loader-members"></span>
92
  <a href="<?php echo site_url() . '/' . BP_MEMBERS_SLUG ?>" id="newest-members" class="selected"><?php _e( 'Newest', 'buddypress' ) ?></a> |
93
  <a href="<?php echo site_url() . '/' . BP_MEMBERS_SLUG ?>" id="recently-active-members"><?php _e( 'Active', 'buddypress' ) ?></a> |
94
  <a href="<?php echo site_url() . '/' . BP_MEMBERS_SLUG ?>" id="popular-members"><?php _e( 'Popular', 'buddypress' ) ?></a>
145
 
146
  class BP_Core_Whos_Online_Widget extends WP_Widget {
147
  function bp_core_whos_online_widget() {
148
+ parent::WP_Widget( false, $name = __( "Who's Online Avatars", 'buddypress' ) );
149
  }
150
 
151
  function widget($args, $instance) {
199
 
200
  class BP_Core_Recently_Active_Widget extends WP_Widget {
201
  function bp_core_recently_active_widget() {
202
+ parent::WP_Widget( false, $name = __( 'Recently Active Member Avatars', 'buddypress' ) );
203
  }
204
 
205
  function widget($args, $instance) {
249
  }
250
  }
251
 
252
+ /** Widget AJAX ******************/
253
+
254
+ function bp_core_ajax_widget_members() {
255
+ global $bp;
256
+
257
+ check_ajax_referer('bp_core_widget_members');
258
+
259
+ switch ( $_POST['filter'] ) {
260
+ case 'newest-members':
261
+ if ( !$users = wp_cache_get( 'newest_users', 'bp' ) ) {
262
+ $users = BP_Core_User::get_newest_users( $_POST['max-members'], 1 );
263
+ wp_cache_set( 'newest_users', $users, 'bp' );
264
+ }
265
+ break;
266
+ case 'recently-active-members':
267
+ if ( !$users = wp_cache_get( 'active_users', 'bp' ) ) {
268
+ $users = BP_Core_User::get_active_users( $_POST['max-members'], 1 );
269
+ wp_cache_set( 'active_users', $users, 'bp' );
270
+ }
271
+ break;
272
+ case 'popular-members':
273
+ if ( !$users = wp_cache_get( 'popular_users', 'bp' ) ) {
274
+ $users = BP_Core_User::get_popular_users( $_POST['max-members'], 1 );
275
+ wp_cache_set( 'popular_users', $users, 'bp' );
276
+ }
277
+ break;
278
+ }
279
+
280
+ if ( $users['users'] ) {
281
+ echo '0[[SPLIT]]'; // return valid result.
282
+
283
+ foreach ( (array) $users['users'] as $user ) {
284
+ ?>
285
+ <li class="vcard">
286
+ <div class="item-avatar">
287
+ <a href="<?php echo bp_core_get_userlink( $user->user_id, false, true ) ?>"><?php echo bp_core_get_avatar( $user->user_id, 1 ) ?></a>
288
+ </div>
289
+
290
+ <div class="item">
291
+ <div class="item-title"><?php echo bp_core_get_userlink( $user->user_id ) ?></div>
292
+ <div class="item-meta">
293
+ <span class="activity">
294
+ <?php
295
+ if ( 'newest-members' == $_POST['filter'] ) {
296
+ echo bp_core_get_last_activity( $user->user_registered, __( 'registered %s ago', 'buddypress' ) );
297
+ } else if ( 'recently-active-members' == $_POST['filter'] ) {
298
+ echo bp_core_get_last_activity( get_usermeta( $user->user_id, 'last_activity' ), __( 'active %s ago', 'buddypress' ) );
299
+ } else if ( 'popular-members' == $_POST['filter'] ) {
300
+ if ( 1 == get_usermeta( $user->user_id, 'total_friend_count' ) )
301
+ echo get_usermeta( $user->user_id, 'total_friend_count' ) . __(' friend', 'buddypress');
302
+ else
303
+ echo get_usermeta( $user->user_id, 'total_friend_count' ) . __(' friends', 'buddypress');
304
+ }
305
+ ?>
306
+ </span>
307
+ </div>
308
+ </div>
309
+ </li>
310
+ <?php
311
+ }
312
+ } else {
313
+ echo "-1[[SPLIT]]<li>" . __("No members matched the current filter.", 'buddypress');
314
+ }
315
+ }
316
+ add_action( 'wp_ajax_widget_members', 'bp_core_ajax_widget_members' );
317
+
318
+
319
  ?>
bp-core/deprecated/bp-core-deprecated.php ADDED
@@ -0,0 +1,980 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /***
3
+ * Deprecated Core Functionality
4
+ *
5
+ * This file contains functions that are deprecated.
6
+ * You should not under any circumstance use these functions as they are
7
+ * either no longer valid, or have been replaced with something much more awesome.
8
+ *
9
+ * If you are using functions in this file you should slap the back of your head
10
+ * and then use the functions or solutions that have replaced them.
11
+ * Most functions contain a note telling you what you should be doing or using instead.
12
+ *
13
+ * Of course, things will still work if you use these functions but you will
14
+ * be the laughing stock of the BuddyPress community. We will all point and laugh at
15
+ * you. You'll also be making things harder for yourself in the long run,
16
+ * and you will miss out on lovely performance and functionality improvements.
17
+ *
18
+ * If you've checked you are not using any deprecated functions and finished your little
19
+ * dance, you can add the following line to your wp-config.php file to prevent any of
20
+ * these old functions from being loaded:
21
+ *
22
+ * define( 'BP_IGNORE_DEPRECATED', true );
23
+ */
24
+
25
+ function bp_core_deprecated_globals() {
26
+ global $bp;
27
+
28
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
29
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
30
+ return false;
31
+
32
+ $bp->core->image_base = BP_PLUGIN_URL . '/bp-core/deprecated/images';
33
+ }
34
+ add_action( 'plugins_loaded', 'bp_core_deprecated_globals', 3 );
35
+ add_action( '_admin_menu', 'bp_core_deprecated_globals', 3 ); // must be _admin_menu hook.
36
+
37
+
38
+ /*** BEGIN DEPRECATED SIGNUP FUNCTIONS **********/
39
+
40
+ /***
41
+ * Instead of duplicating the WPMU signup functions as in previous versions
42
+ * of BuddyPress, all signup functionality is now in the template for easier
43
+ * customization. Check out the default theme in the file 'register.php'.
44
+ */
45
+
46
+ function bp_core_signup_set_headers() {
47
+ add_action( 'wp_head', 'bp_core_signup_register_headers' ) ;
48
+ require_once( ABSPATH . WPINC . '/registration.php' );
49
+
50
+ if( is_array( get_site_option( 'illegal_names' )) && $_GET[ 'new' ] != '' && in_array( $_GET[ 'new' ], get_site_option( 'illegal_names' ) ) == true ) {
51
+ wp_redirect( "http://{$current_site->domain}{$current_site->path}" );
52
+ die();
53
+ }
54
+ }
55
+
56
+ function bp_core_signup_do_headers() {
57
+ do_action("signup_header");
58
+ }
59
+ add_action( 'wp_head', 'bp_core_signup_do_headers' );
60
+
61
+ function bp_core_signup_register_headers() {
62
+ echo "<meta name='robots' content='noindex,nofollow' />\n";
63
+ }
64
+
65
+ function bp_core_signup_show_blog_form( $blogname = '', $blog_title = '', $errors = '' ) {
66
+ global $current_site;
67
+
68
+ ?>
69
+ <h3><?php _e( 'Blog Details', 'buddypress' ) ?></h3>
70
+ <p id="blog-details-help">
71
+ <?php _e( "To register your first blog, just fill in the details below and your registration is complete.", 'buddypress' ) ?>
72
+ </p>
73
+
74
+ <div id="blog-details-fields">
75
+ <?php
76
+
77
+ // Blog name
78
+ if ( 'no' == constant( "VHOST" ) )
79
+ echo '<label for="blogname">' . __('Blog Name:', 'buddypress') . '</label>';
80
+ else
81
+ echo '<label for="blogname">' . __('Blog Domain:', 'buddypress') . '</label>';
82
+
83
+ if ( $errmsg = $errors->get_error_message('blogname') ) { ?>
84
+ <p class="error"><?php echo $errmsg ?></p>
85
+ <?php }
86
+
87
+ if ( 'no' == constant( "VHOST" ) ) {
88
+ echo '<span class="prefix_address">' . $current_site->domain . $current_site->path . '</span><input name="blogname" type="text" id="blogname" value="'.$blogname.'" maxlength="50" /><br />';
89
+ } else {
90
+ echo '<input name="blogname" type="text" id="blogname" value="'.$blogname.'" maxlength="50" /><span class="suffix_address">.' . $current_site->domain . $current_site->path . '</span><br />';
91
+ }
92
+
93
+ if ( !is_user_logged_in() ) {
94
+ echo '<p class="help-text">';
95
+ print '(<strong>' . __( 'Your address will be ', 'buddypress' );
96
+ if( 'no' == constant( "VHOST" ) ) {
97
+ print $current_site->domain . $current_site->path . __( 'blogname', 'buddypress' );
98
+ } else {
99
+ print __( 'domain.', 'buddypress' ) . $current_site->domain . $current_site->path;
100
+ }
101
+ echo '</strong>. ' . __( 'Must be at least 4 characters, letters and numbers only. It cannot be changed so choose carefully!)', 'buddypress' ) . '</p>';
102
+ echo '</p>';
103
+ }
104
+
105
+ // Blog Title
106
+ ?>
107
+ <label for="blog_title"><?php _e( 'Blog Title:', 'buddypress' ) ?></label>
108
+ <?php if ( $errmsg = $errors->get_error_message('blog_title') ) { ?>
109
+ <p class="error"><?php echo $errmsg ?></p>
110
+ <?php }
111
+ echo '<input name="blog_title" type="text" id="blog_title" value="'.wp_specialchars($blog_title, 1).'" /></p>';
112
+ ?>
113
+
114
+ <p>
115
+ <label for="blog_public_on"><?php _e( 'Privacy:', 'buddypress' ) ?></label>
116
+ <?php _e( 'I would like my blog to appear in search engines like Google and Technorati, and in public listings around this site.', 'buddypress' ); ?>
117
+ <label class="checkbox" for="blog_public_on">
118
+ <input type="radio" id="blog_public_on" name="blog_public" value="1" <?php if( !isset( $_POST['blog_public'] ) || '1' == $_POST['blog_public'] ) { ?>checked="checked"<?php } ?> />
119
+ &nbsp;<?php _e( 'Yes', 'buddypress' ); ?>
120
+ </label>
121
+ <label class="checkbox" for="blog_public_off">
122
+ <input type="radio" id="blog_public_off" name="blog_public" value="0" <?php if( isset( $_POST['blog_public'] ) && '0' == $_POST['blog_public'] ) { ?>checked="checked"<?php } ?> />
123
+ &nbsp;<?php _e( 'No', 'buddypress' ); ?>
124
+ </label>
125
+ </p>
126
+ </div>
127
+ <?php
128
+ do_action('signup_blogform', $errors);
129
+ }
130
+
131
+ function bp_core_signup_validate_blog_form() {
132
+ $user = '';
133
+ if ( is_user_logged_in() )
134
+ $user = wp_get_current_user();
135
+
136
+ return wpmu_validate_blog_signup($_POST['blogname'], $_POST['blog_title'], $user);
137
+ }
138
+
139
+ function bp_core_signup_show_user_form($user_name = '', $user_email = '', $errors = '') {
140
+ // User name
141
+ echo '<div id="account-fields">';
142
+ echo '<label for="user_name">' . __( 'Username:', 'buddypress' ) . '</label>';
143
+ if ( $errmsg = $errors->get_error_message('user_name') ) {
144
+ echo '<p class="error">'.$errmsg.'</p>';
145
+ }
146
+ echo '<input name="user_name" type="text" id="user_name" value="'.$user_name.'" maxlength="50" />';
147
+ echo '<p class="help-text">';
148
+ _e( '(Must be at least 4 characters, letters and numbers only.)', 'buddypress' );
149
+ echo '</p>'
150
+ ?>
151
+
152
+ <label for="user_email"><?php _e( 'Email&nbsp;Address:', 'buddypress' ) ?></label>
153
+ <?php if ( $errmsg = $errors->get_error_message('user_email') ) { ?>
154
+ <p class="error"><?php echo $errmsg ?></p>
155
+ <?php } ?>
156
+ <input name="user_email" type="text" id="user_email" value="<?php echo wp_specialchars($user_email, 1) ?>" maxlength="200" /><p class="help-text"><?php _e( '(We&#8217;ll send your password to this address, so <strong>triple-check it</strong>.)', 'buddypress' ) ?></p>
157
+ <?php
158
+ if ( $errmsg = $errors->get_error_message('generic') ) {
159
+ echo '<p class="error">'.$errmsg.'</p>';
160
+ }
161
+ echo '</div>';
162
+
163
+ echo '<div id="extra-fields">';
164
+ do_action( 'signup_extra_fields', $errors );
165
+ echo '</div>';
166
+ }
167
+
168
+ function bp_core_signup_validate_user_form() {
169
+ return wpmu_validate_user_signup($_POST['user_name'], $_POST['user_email']);
170
+ }
171
+
172
+ function bp_core_signup_signup_another_blog($blogname = '', $blog_title = '', $errors = '') {
173
+ global $current_user, $current_site;
174
+
175
+ if ( ! is_wp_error($errors) ) {
176
+ $errors = new WP_Error();
177
+ }
178
+
179
+ // allow definition of default variables
180
+ $filtered_results = apply_filters('signup_another_blog_init', array('blogname' => $blogname, 'blog_title' => $blog_title, 'errors' => $errors ));
181
+ $blogname = $filtered_results['blogname'];
182
+ $blog_title = $filtered_results['blog_title'];
183
+ $errors = $filtered_results['errors'];
184
+
185
+ ?>
186
+ <h3><?php _e( "You're already registered!", 'buddypress' )?></h3>
187
+ <p><?php _e( 'You can still create another blog however. Fill in the form below to add another blog to your account.', 'buddypress' ) ?>
188
+
189
+
190
+ <p><?php _e( "There is no limit to the number of blogs you can have, so create to your heart's content, but blog responsibly. If you&#8217;re not going to use a great blog domain, leave it for a new user. Now have at it!", 'buddypress' ) ?></p>
191
+
192
+ <form id="setupform" method="post" action="<?php echo site_url(BP_REGISTER_SLUG) ?>">
193
+ <input type="hidden" name="stage" value="gimmeanotherblog" />
194
+ <?php do_action( "signup_hidden_fields" ); ?>
195
+ <?php bp_core_signup_show_blog_form($blogname, $blog_title, $errors); ?>
196
+ <p>
197
+ <input id="submit" type="submit" name="submit" class="submit" value="<?php _e('Create Blog &raquo;') ?>"/>
198
+ </p>
199
+ </form>
200
+ <?php
201
+ }
202
+
203
+ function bp_core_signup_validate_another_blog_signup() {
204
+ global $wpdb, $current_user, $blogname, $blog_title, $errors, $domain, $path;
205
+ $current_user = wp_get_current_user();
206
+ if( !is_user_logged_in() )
207
+ die();
208
+
209
+ $result = bp_core_signup_validate_blog_form();
210
+ extract($result);
211
+
212
+ if ( $errors->get_error_code() ) {
213
+ bp_core_signup_signup_another_blog($blogname, $blog_title, $errors);
214
+ return false;
215
+ }
216
+
217
+ $public = (int) $_POST['blog_public'];
218
+ $meta = apply_filters('signup_create_blog_meta', array ('lang_id' => 1, 'public' => $public)); // depreciated
219
+ $meta = apply_filters( "add_signup_meta", $meta );
220
+
221
+ wpmu_create_blog( $domain, $path, $blog_title, $current_user->id, $meta, $wpdb->siteid );
222
+ bp_core_signup_confirm_another_blog_signup($domain, $path, $blog_title, $current_user->user_login, $current_user->user_email, $meta);
223
+ return true;
224
+ }
225
+
226
+ function bp_core_signup_confirm_another_blog_signup($domain, $path, $blog_title, $user_name, $user_email = '', $meta = '') {
227
+ ?>
228
+ <h2><?php printf( __( 'The blog %s is yours.', 'buddypress' ), "<a href='http://{$domain}{$path}'>{$blog_title}</a>" ) ?></h2>
229
+ <p>
230
+ <?php printf( __( '<a href="http://%1$s">http://%2$s</a> is your new blog. <a href="%3$s">Login</a> as "%4$s" using your existing password.', 'buddypress' ), $domain.$path, $domain.$path, "http://" . $domain.$path . "/wp-login.php", $user_name) ?>
231
+ </p>
232
+ <?php
233
+ do_action('signup_finished');
234
+ }
235
+
236
+ function bp_core_signup_signup_user($user_name = '', $user_email = '', $errors = '') {
237
+ global $current_site, $active_signup;
238
+
239
+ $active_signup = get_site_option( 'registration' );
240
+
241
+ if ( !is_wp_error($errors) )
242
+ $errors = new WP_Error();
243
+ if( isset( $_POST[ 'signup_for' ] ) ) {
244
+ $signup[ wp_specialchars( $_POST[ 'signup_for' ] ) ] = 'checked="checked"';
245
+ } else {
246
+ $signup[ 'blog' ] = 'checked="checked"';
247
+ }
248
+
249
+ // allow definition of default variables
250
+ $filtered_results = apply_filters('signup_user_init', array('user_name' => $user_name, 'user_email' => $user_email, 'errors' => $errors ));
251
+ $user_name = $filtered_results['user_name'];
252
+ $user_email = $filtered_results['user_email'];
253
+ $errors = $filtered_results['errors'];
254
+
255
+ ?>
256
+
257
+ <form id="setupform" method="post" action="<?php echo site_url(BP_REGISTER_SLUG) ?>">
258
+ <p id="intro-text"><?php _e( 'Registering for a new account is easy, just fill in the form below and you\'ll be a new member in no time at all.', 'buddypress' ) ?></p>
259
+ <input type="hidden" name="stage" value="validate-user-signup" />
260
+ <?php do_action( "signup_hidden_fields" ); ?>
261
+
262
+ <?php bp_core_signup_show_user_form($user_name, $user_email, $errors); ?>
263
+
264
+ <?php if( 'blog' == $active_signup ) { ?>
265
+ <input id="signupblog" type="hidden" name="signup_for" value="blog" />
266
+ <?php } elseif( 'user' == $active_signup ) { ?>
267
+ <input id="signupblog" type="hidden" name="signup_for" value="user" />
268
+ <?php } else { ?>
269
+ <div id="blog-or-username">
270
+ <h3><?php _e( 'Create a Blog?', 'buddypress' ) ?></h3>
271
+ <p id="blog-help-text"><?php _e( 'If you want to create your first blog, select the option below and you\'ll be asked for a few more details.', 'buddypress' ) ?></p>
272
+
273
+ <div id="blog-or-username-fields">
274
+ <p>
275
+ <input id="signupblog" type="radio" name="signup_for" value="blog" <?php echo $signup['blog'] ?> />
276
+ <label class="checkbox" for="signupblog"><?php _e( 'Gimme a blog!', 'buddypress' ) ?></label>
277
+ </p>
278
+
279
+ <p>
280
+ <input id="signupuser" type="radio" name="signup_for" value="user" <?php echo $signup['user'] ?> />
281
+ <label class="checkbox" for="signupuser"><?php _e( 'Just a username, please.', 'buddypress' ) ?></label>
282
+ </p>
283
+ </div>
284
+ </div>
285
+ <?php } ?>
286
+
287
+ <input id="submit" type="submit" name="submit" class="submit" value="<?php _e('Next &raquo;') ?>"/>
288
+ </form>
289
+ <?php
290
+ }
291
+
292
+ function bp_core_signup_validate_user_signup() {
293
+ $result = bp_core_signup_validate_user_form();
294
+ extract($result);
295
+
296
+ if ( $errors->get_error_code() ) {
297
+ bp_core_signup_signup_user($user_name, $user_email, $errors);
298
+ return false;
299
+ }
300
+
301
+ if ( 'blog' == $_POST['signup_for'] ) {
302
+ bp_core_signup_signup_blog($user_name, $user_email);
303
+ return false;
304
+ }
305
+
306
+ wpmu_signup_user($user_name, $user_email, apply_filters( "add_signup_meta", array() ) );
307
+
308
+ bp_core_signup_confirm_user_signup($user_name, $user_email);
309
+ return true;
310
+ }
311
+
312
+ function bp_core_signup_confirm_user_signup($user_name, $user_email) {
313
+ ?>
314
+ <h3><?php _e( 'Congratulations, you are now registered!', 'buddypress' ) ?></h3>
315
+ <p><?php printf(__('Your new username is: %s', 'buddypress' ), $user_name) ?></p>
316
+ <p>&nbsp;</p>
317
+ <p><?php printf(__('Before you can start using your new username, <strong>you must activate it</strong>. Check your inbox at <strong>%1$s</strong> and click the link given.', 'buddypress' ), $user_email) ?></p>
318
+ <p><?php _e('If you do not activate your username within two days, you will have to sign up again.', 'buddypress' ); ?></p>
319
+ <?php
320
+ do_action('signup_finished');
321
+ }
322
+
323
+ function bp_core_signup_signup_blog($user_name = '', $user_email = '', $blogname = '', $blog_title = '', $errors = '') {
324
+ if ( !is_wp_error($errors) )
325
+ $errors = new WP_Error();
326
+
327
+ // allow definition of default variables
328
+ $filtered_results = apply_filters('signup_blog_init', array('user_name' => $user_name, 'user_email' => $user_email, 'blogname' => $blogname, 'blog_title' => $blog_title, 'errors' => $errors ));
329
+ $user_name = $filtered_results['user_name'];
330
+ $user_email = $filtered_results['user_email'];
331
+ $blogname = $filtered_results['blogname'];
332
+ $blog_title = $filtered_results['blog_title'];
333
+ $errors = $filtered_results['errors'];
334
+
335
+ if ( empty($blogname) )
336
+ $blogname = $user_name;
337
+ ?>
338
+ <form id="setupform" method="post" action="<?php echo site_url(BP_REGISTER_SLUG) ?>">
339
+ <input type="hidden" name="stage" value="validate-blog-signup" />
340
+ <input type="hidden" name="user_name" value="<?php echo $user_name ?>" />
341
+ <input type="hidden" name="user_email" value="<?php echo $user_email ?>" />
342
+ <?php do_action( "signup_hidden_fields" ); ?>
343
+ <?php bp_core_signup_show_blog_form($blogname, $blog_title, $errors); ?>
344
+ <p>
345
+ <input id="submit" type="submit" name="submit" class="submit" value="<?php _e('Signup &raquo;') ?>"/></p>
346
+ </form>
347
+ <?php
348
+ }
349
+
350
+ function bp_core_signup_validate_blog_signup() {
351
+ // Re-validate user info.
352
+ $result = wpmu_validate_user_signup($_POST['user_name'], $_POST['user_email']);
353
+ extract($result);
354
+
355
+ if ( $errors->get_error_code() ) {
356
+ bp_core_signup_signup_user($user_name, $user_email, $errors);
357
+ return false;
358
+ }
359
+
360
+ $result = wpmu_validate_blog_signup($_POST['blogname'], $_POST['blog_title']);
361
+ extract($result);
362
+
363
+ if ( $errors->get_error_code() ) {
364
+ bp_core_signup_signup_blog($user_name, $user_email, $blogname, $blog_title, $errors);
365
+ return false;
366
+ }
367
+
368
+ $public = (int) $_POST['blog_public'];
369
+ $meta = array ('lang_id' => 1, 'public' => $public);
370
+ $meta = apply_filters( "add_signup_meta", $meta );
371
+
372
+ wpmu_signup_blog($domain, $path, $blog_title, $user_name, $user_email, $meta);
373
+ bp_core_signup_confirm_blog_signup($domain, $path, $blog_title, $user_name, $user_email, $meta);
374
+ return true;
375
+ }
376
+
377
+ function bp_core_signup_confirm_blog_signup($domain, $path, $blog_title, $user_name = '', $user_email = '', $meta) {
378
+ ?>
379
+ <h3><?php _e('Congratulations, You are now registered!', 'buddypress' ) ?></h3>
380
+
381
+ <p><?php printf( __('But, before you can start using your blog, <strong>you must activate it</strong>. Check your inbox at <strong>%s</strong> and click the link given. It should arrive within 30 minutes.', 'buddypress' ), $user_email) ?></p>
382
+ <p>&nbsp;</p>
383
+
384
+ <h3><?php _e( 'Still waiting for your email?', 'buddypress' ); ?></h3>
385
+ <p>
386
+ <?php _e( "If you haven't received your email yet, there are a number of things you can do:", 'buddypress' ) ?>
387
+ <ul>
388
+ <li><p><strong><?php _e( 'Wait a little longer. Sometimes delivery of email can be delayed by processes outside of our control.', 'buddypress' ) ?></strong></p></li>
389
+ <li><p><?php _e( 'Check the junk email or spam folder of your email client. Sometime emails wind up there by mistake.', 'buddypress' ) ?></p></li>
390
+ <li><?php printf( __( "Have you entered your email correctly? We think it's %s but if you've entered it incorrectly, you won't receive it.", 'buddypress' ), $user_email) ?></li>
391
+ </ul>
392
+ </p>
393
+ <?php
394
+ do_action('signup_finished');
395
+ }
396
+
397
+ function bp_core_signup_do_signup() {
398
+ // Main
399
+ $active_signup = get_site_option( 'registration' );
400
+ if( !$active_signup )
401
+ $active_signup = 'all';
402
+
403
+ $active_signup = apply_filters( 'wpmu_active_signup', $active_signup ); // return "all", "none", "blog" or "user"
404
+
405
+ if( is_site_admin() )
406
+ echo '<div class="mu_alert">' . sprintf( __( "Greetings Site Administrator! You are currently allowing '%s' registrations. To change or disable registration go to your <a href='wp-admin/wpmu-options.php'>Options page</a>.", 'buddypress' ), $active_signup ) . '</div>';
407
+
408
+ $newblogname = isset($_GET['new']) ? strtolower(preg_replace('/^-|-$|[^-a-zA-Z0-9]/', '', $_GET['new'])) : null;
409
+
410
+ $current_user = wp_get_current_user();
411
+ if( $active_signup == "none" ) {
412
+ _e( "Registration has been disabled.", 'buddypress' );
413
+ } elseif( $active_signup == 'blog' && !is_user_logged_in() ){
414
+ if( is_ssl() ) {
415
+ $proto = 'https://';
416
+ } else {
417
+ $proto = 'http://';
418
+ }
419
+ $login_url = site_url( 'wp-login.php?redirect_to=' . site_url(BP_REGISTER_SLUG) );
420
+ echo sprintf( __( "You must first <a href=\"%s\">login</a>, and then you can create a new blog.", 'buddypress' ), $login_url );
421
+ } else {
422
+ switch ($_POST['stage']) {
423
+ case 'validate-user-signup' :
424
+ if( $active_signup == 'all' || $_POST[ 'signup_for' ] == 'blog' && $active_signup == 'blog' || $_POST[ 'signup_for' ] == 'user' && $active_signup == 'user' )
425
+ bp_core_signup_validate_user_signup();
426
+ else
427
+ _e( "User registration has been disabled.", 'buddypress' );
428
+ break;
429
+ case 'validate-blog-signup':
430
+ if( $active_signup == 'all' || $active_signup == 'blog' )
431
+ bp_core_signup_validate_blog_signup();
432
+ else
433
+ _e( "Blog registration has been disabled.", 'buddypress' );
434
+ break;
435
+ case 'gimmeanotherblog':
436
+ bp_core_signup_validate_another_blog_signup();
437
+ break;
438
+ default :
439
+ $user_email = $_POST[ 'user_email' ];
440
+ do_action( "preprocess_signup_form" ); // populate the form from invites, elsewhere?
441
+ if ( is_user_logged_in() && ( $active_signup == 'all' || $active_signup == 'blog' ) ) {
442
+ bp_core_signup_signup_another_blog($newblogname);
443
+ } elseif( is_user_logged_in() == false && ( $active_signup == 'all' || $active_signup == 'user' ) ) {
444
+ bp_core_signup_signup_user( $newblogname, $user_email );
445
+ } elseif( is_user_logged_in() == false && ( $active_signup == 'blog' ) ) {
446
+ _e( "I'm sorry. We're not accepting new registrations at this time.", 'buddypress' );
447
+ } else {
448
+ _e( "You're logged in already. No need to register again!", 'buddypress' );
449
+ }
450
+ if ($newblogname) {
451
+ if( constant( "VHOST" ) == 'no' )
452
+ $newblog = 'http://' . $current_site->domain . $current_site->path . $newblogname . '/';
453
+ else
454
+ $newblog = 'http://' . $newblogname . '.' . $current_site->domain . $current_site->path;
455
+ if ($active_signup == 'blog' || $active_signup == 'all')
456
+ printf( __( "<p><em>The blog you were looking for, <strong>%s</strong> doesn't exist but you can create it now!</em></p>", 'buddypress' ), $newblog );
457
+ else
458
+ printf( __( "<p><em>The blog you were looking for, <strong>%s</strong> doesn't exist.</em></p>", 'buddypress' ), $newblog );
459
+ }
460
+ break;
461
+ }
462
+ }
463
+ }
464
+
465
+ function bp_core_activation_set_headers() {
466
+ global $wp_object_cache;
467
+
468
+ define( "WP_INSTALLING", true );
469
+
470
+ require_once( ABSPATH . WPINC . '/registration.php');
471
+
472
+ if( is_object( $wp_object_cache ) )
473
+ $wp_object_cache->cache_enabled = false;
474
+
475
+ do_action("activate_header");
476
+ }
477
+
478
+ function bp_core_activation_do_activation() {
479
+ global $current_site, $blog_id, $user_id; ?>
480
+
481
+ <?php if ( empty( $_GET['key'] ) && empty( $_POST['key'] ) ) { ?>
482
+
483
+ <h3><?php _e( 'Activation Key Required', 'buddypress' ) ?></h3>
484
+
485
+ <p id="intro-text"><?php _e( 'This is the key contained in the email you were sent after registering for this site.', 'buddypress' ) ?></p>
486
+
487
+ <div class="field-box">
488
+ <form name="activateform" id="activateform" method="post" action="<?php echo 'http://' . $current_site->domain . $current_site->path ?>wp-activate.php">
489
+ <p>
490
+ <label for="key"><?php _e('Activation Key:', 'buddypress' ) ?></label>
491
+ <br /><input type="text" name="key" id="key" value="" size="50" />
492
+ </p>
493
+ <p class="submit">
494
+ <input id="submit" type="submit" name="Submit" class="submit" value="<?php _e('Activate &raquo;', 'buddypress' ) ?>"/>
495
+ </p>
496
+ </form>
497
+ </div>
498
+
499
+ <?php } else {
500
+
501
+ $key = !empty($_GET['key']) ? $_GET['key'] : $_POST['key'];
502
+ $result = wpmu_activate_signup($key);
503
+
504
+ if ( is_wp_error($result) ) {
505
+ if ( 'already_active' == $result->get_error_code() || 'blog_taken' == $result->get_error_code() ) {
506
+ $signup = $result->get_error_data();
507
+ ?>
508
+
509
+ <h3><?php _e('Your account is now active!', 'buddypress' ); ?></h3>
510
+
511
+ <?php
512
+ _e( 'Your account has already been activated. You can now log in with the account details that were emailed to you.' );
513
+
514
+ } else {
515
+ ?>
516
+ <h2><?php _e('An error occurred during the activation', 'buddypress' ); ?></h2>
517
+ <?php
518
+ echo '<p>'.$result->get_error_message().'</p>';
519
+ }
520
+ } else {
521
+ extract($result);
522
+
523
+ $user = new WP_User( (int) $user_id);
524
+
525
+ ?>
526
+
527
+ <h3><?php _e('Your account is now active!', 'buddypress' ); ?></h3>
528
+
529
+ <p class="view"><?php printf( __( 'Your account is now activated. <a href="%1$s">Login</a> or go back to the <a href="%2$s">homepage</a>.', 'buddypress' ), site_url( 'wp-login.php?redirect_to=' . site_url() ), site_url() ); ?></p>
530
+
531
+ <div class="field-box" id="signup-welcome">
532
+ <p><span class="label"><?php _e( 'Username:', 'buddypress' ); ?></span> <?php echo $user->user_login ?></p>
533
+ <p><span class="label"><?php _e( 'Password:', 'buddypress' ); ?></span> <?php echo $password; ?></p>
534
+ </div>
535
+
536
+ <?php
537
+ do_action( 'bp_activation_extras', $user_id, $meta );
538
+ }
539
+ }
540
+ }
541
+
542
+ // Notify user of signup success.
543
+ function bp_core_activation_signup_blog_notification( $domain, $path, $title, $user, $user_email, $key, $meta ) {
544
+ global $current_site;
545
+
546
+ // Send email with activation link.
547
+ if ( 'no' == constant( "VHOST" ) ) {
548
+ $activate_url = bp_activation_page( false ) . "?key=$key";
549
+ } else {
550
+ $activate_url = bp_activation_page( false ) ."?key=$key";
551
+ }
552
+
553
+ $activate_url = clean_url($activate_url);
554
+ $admin_email = get_site_option( "admin_email" );
555
+
556
+ if ( empty( $admin_email ) )
557
+ $admin_email = 'support@' . $_SERVER['SERVER_NAME'];
558
+
559
+ $from_name = ( '' == get_site_option( "site_name" ) ) ? 'WordPress' : wp_specialchars( get_site_option( "site_name" ) );
560
+ $message_headers = "MIME-Version: 1.0\n" . "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
561
+ $message = sprintf(__("To activate your blog, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login.\n\nAfter you activate, you can visit your blog here:\n\n%s", 'buddypress' ), $activate_url, clean_url("http://{$domain}{$path}" ) );
562
+ $subject = '[' . $from_name . '] ' . sprintf(__('Activate %s', 'buddypress' ), clean_url('http://' . $domain . $path));
563
+
564
+ wp_mail($user_email, $subject, $message, $message_headers);
565
+
566
+ // Return false to stop the original WPMU function from continuing
567
+ return false;
568
+ }
569
+ add_filter( 'wpmu_signup_blog_notification', 'bp_core_activation_signup_blog_notification', 1, 7 );
570
+
571
+ function bp_core_activation_signup_user_notification( $user, $user_email, $key, $meta ) {
572
+ global $current_site;
573
+
574
+ // Send email with activation link.
575
+ $admin_email = get_site_option( "admin_email" );
576
+
577
+ if ( empty( $admin_email ) )
578
+ $admin_email = 'support@' . $_SERVER['SERVER_NAME'];
579
+
580
+ $from_name = ( '' == get_site_option( "site_name" ) ) ? 'WordPress' : wp_specialchars( get_site_option( "site_name" ) );
581
+ $message_headers = "MIME-Version: 1.0\n" . "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
582
+ $message = apply_filters( 'wpmu_signup_user_notification_email', sprintf( __( "To activate your user, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login.\n\n", 'buddypress' ), clean_url( bp_activation_page( false ) . "?key=$key" ) ) );
583
+ $subject = apply_filters( 'wpmu_signup_user_notification_subject', sprintf( __( 'Activate %s', 'buddypress' ), $user ) );
584
+
585
+ wp_mail( $user_email, $subject, $message, $message_headers );
586
+
587
+ // Return false to stop the original WPMU function from continuing
588
+ return false;
589
+ }
590
+ add_filter( 'wpmu_signup_user_notification', 'bp_core_activation_signup_user_notification', 1, 4 );
591
+
592
+ /*** END DEPRECATED SIGNUP FUNCTIONS **********/
593
+
594
+
595
+ /* DEPRECATED - use bp_core_new_nav_item() as it's more friendly and allows ordering */
596
+ function bp_core_add_nav_item( $name, $slug, $css_id = false, $show_for_displayed_user = true ) {
597
+ bp_core_new_nav_item( array( 'name' => $name, 'slug' => $slug, 'item_css_id' => $css_id, 'show_for_displayed_user' => $show_for_displayed_user ) );
598
+ }
599
+
600
+ /* DEPRECATED - use bp_core_new_subnav_item() as it's more friendly and allows ordering. */
601
+ function bp_core_add_subnav_item( $parent_id, $slug, $name, $link, $function, $css_id = false, $user_has_access = true, $admin_only = false ) {
602
+ bp_core_new_subnav_item( array( 'name' => $name, 'slug' => $slug, 'parent_slug' => $parent_id, 'parent_url' => $link, 'item_css_id' => $css_id, 'user_has_access' => $user_has_access, 'site_admin_only' => $admin_only, 'screen_function' => $function ) );
603
+ }
604
+
605
+ /* DEPRECATED - use bp_core_get_userid() */
606
+ function bp_core_get_userid_from_user_login( $deprecated ) {
607
+ return bp_core_get_userid( $deprecated );
608
+ }
609
+
610
+ /* DEPRECATED - use bp_core_get_user_displayname() */
611
+ function bp_core_global_user_fullname( $user_id ) { return bp_core_get_user_displayname( $user_id ); }
612
+
613
+ /* DEPRECATED use bp_core_fetch_avatar() */
614
+ function bp_core_get_avatar( $user, $version = 1, $width = null, $height = null, $no_tag = false ) {
615
+ $type = ( 2 == $version ) ? 'full' : 'thumb';
616
+ return bp_core_fetch_avatar( array( 'item_id' => $user, 'type' => $type, 'width' => $width, 'height' => $height ) );
617
+ }
618
+
619
+ /* DEPRECATED - use bp_displayed_user_avatar( 'size=full' ) */
620
+ function bp_the_avatar() {
621
+ global $bp;
622
+ echo apply_filters( 'bp_the_avatar', bp_core_fetch_avatar( array( 'item_id' => $bp->displayed_user->id, 'type' => 'full' ) ) );
623
+ }
624
+
625
+ /* DEPRECATED - use bp_displayed_user_avatar( 'size=thumb' ) */
626
+ function bp_the_avatar_thumbnail() {
627
+ global $bp;
628
+ echo apply_filters( 'bp_the_avatar_thumbnail', bp_core_fetch_avatar( array( 'item_id' => $bp->displayed_user->id, 'type' => 'thumb' ) ) );
629
+ }
630
+
631
+ /* DEPRECATED - use bp_loggedin_user_avatar( 'type=full' ); */
632
+ function bp_loggedinuser_avatar( $width = false, $height = false ) {
633
+ global $bp;
634
+
635
+ echo apply_filters( 'bp_loggedinuser_avatar', bp_core_fetch_avatar( array( 'item_id' => $bp->displayed_user->id, 'type' => 'thumb', 'width' => $width, 'height' => $height ) ) );
636
+ }
637
+
638
+ /* DEPRECATED - use bp_loggedin_user_avatar( 'type=thumb' ); */
639
+ function bp_loggedinuser_avatar_thumbnail( $width = false, $height = false ) {
640
+ global $bp;
641
+
642
+ echo apply_filters( 'bp_get_options_avatar', bp_core_fetch_avatar( array( 'item_id' => $bp->loggedin_user->id, 'type' => 'thumb', 'width' => $width, 'height' => $height ) ) );
643
+ }
644
+
645
+ /* DEPRECATED - use bp_core_get_user_displayname( $user_id ) */
646
+ function bp_fetch_user_fullname( $user_id, $echo = true ) {
647
+ if ( $echo )
648
+ echo apply_filters( 'bp_fetch_user_fullname', bp_core_get_user_displayname( $user_id ) );
649
+ else
650
+ return apply_filters( 'bp_fetch_user_fullname', bp_core_get_user_displayname( $user_id ) );
651
+ }
652
+
653
+ /*** BEGIN OLD AVATAR CROPPING SUPPORT ****************************************/
654
+
655
+ /* DEPRECATED - constant values that are no longer used. */
656
+ define( 'CORE_AVATAR_V1_W', apply_filters( 'bp_core_avatar_v1_w', 50 ) );
657
+ define( 'CORE_AVATAR_V1_H', apply_filters( 'bp_core_avatar_v1_h', 50 ) );
658
+ define( 'CORE_AVATAR_V2_W', apply_filters( 'bp_core_avatar_v2_w', 150 ) );
659
+ define( 'CORE_AVATAR_V2_H', apply_filters( 'bp_core_avatar_v2_h', 150 ) );
660
+ define( 'CORE_CROPPING_CANVAS_MAX', apply_filters( 'bp_core_avatar_cropping_canvas_max', 450 ) );
661
+ define( 'CORE_MAX_FILE_SIZE', get_site_option('fileupload_maxk') * 1024 );
662
+ define( 'CORE_DEFAULT_AVATAR', apply_filters( 'bp_core_avatar_default_src', BP_PLUGIN_URL . '/bp-xprofile/images/none.gif' ) );
663
+ define( 'CORE_DEFAULT_AVATAR_THUMB', apply_filters( 'bp_core_avatar_default_thumb_src', BP_PLUGIN_URL . '/bp-xprofile/images/none-thumbnail.gif' ) );
664
+
665
+ /* DEPRECATED - this is handled via a screen function. See xprofile_screen_change_avatar() */
666
+ function bp_core_avatar_admin( $message = null, $action, $delete_action) { ?>
667
+ <p><?php _e('Your avatar will be used on your profile and throughout the site.', 'buddypress') ?></p>
668
+ <p><?php _e( 'Click below to select a JPG, GIF or PNG format photo from your computer and then click \'Upload Photo\' to proceed.', 'buddypress' ) ?></p>
669
+
670
+ <form action="" method="post" id="avatar-upload-form" enctype="multipart/form-data">
671
+
672
+ <?php if ( 'upload-image' == bp_get_avatar_admin_step() ) : ?>
673
+
674
+ <h3><?php _e( 'Your Current Avatar', 'buddypress' ) ?></h3>
675
+
676
+ <?php bp_displayed_user_avatar( 'type=full') ?>
677
+ <?php bp_displayed_user_avatar( 'type=thumb' ) ?>
678
+
679
+ <p>
680
+ <input type="file" name="file" id="file" />
681
+ <input type="submit" name="upload" id="upload" value="<?php _e( 'Upload Image', 'buddypress' ) ?>" />
682
+ <input type="hidden" name="action" id="action" value="bp_avatar_upload" />
683
+ </p>
684
+
685
+ <?php wp_nonce_field( 'bp_avatar_upload' ) ?>
686
+
687
+ <?php endif; ?>
688
+
689
+ <?php if ( 'crop-image' == bp_get_avatar_admin_step() ) : ?>
690
+
691
+ <h3><?php _e( 'Crop Your New Avatar', 'buddypress' ) ?></h3>
692
+
693
+ <img src="<?php bp_avatar_to_crop() ?>" id="avatar-to-crop" class="avatar" alt="<?php _e( 'Avatar to crop', 'buddypress' ) ?>" />
694
+
695
+ <div id="avatar-crop-pane" style="width:100px;height:100px;overflow:hidden;">
696
+ <img src="<?php bp_avatar_to_crop() ?>" id="avatar-crop-preview" class="avatar" alt="<?php _e( 'Avatar preview', 'buddypress' ) ?>" />
697
+ </div>
698
+
699
+ <input type="submit" name="avatar-crop-submit" id="avatar-crop-submit" value="<?php _e( 'Crop Image', 'buddypress' ) ?>" />
700
+
701
+ <input type="hidden" name="image_src" id="image_src" value="<?php bp_avatar_to_crop_src() ?>" />
702
+ <input type="hidden" id="x" name="x" />
703
+ <input type="hidden" id="y" name="y" />
704
+ <input type="hidden" id="w" name="w" />
705
+ <input type="hidden" id="h" name="h" />
706
+
707
+ <?php wp_nonce_field( 'bp_avatar_cropstore' ) ?>
708
+
709
+ <?php endif; ?>
710
+
711
+ </form> <?php
712
+ }
713
+
714
+
715
+ /*** END OLD AVATAR CROPPING SUPPORT **************************/
716
+
717
+
718
+ /*** BEGIN DEPRECATED OLD BUDDYPRESS THEME SUPPORT ************/
719
+
720
+ /***
721
+ * In older versions of BuddyPress, BuddyPress templates were in a seperate theme.
722
+ * The child theme setup makes upgrades and extending themes much easier, so the
723
+ * old method was deprecated.
724
+ */
725
+
726
+ function bp_core_get_buddypress_themes() {
727
+ global $wp_themes;
728
+
729
+ /* Remove the cached WP themes first */
730
+ $wp_existing_themes = &$wp_themes;
731
+ $wp_themes = null;
732
+
733
+ add_filter( 'theme_root', 'bp_core_filter_buddypress_theme_root' );
734
+ $themes = get_themes();
735
+
736
+ if ( $themes ) {
737
+ foreach ( $themes as $name => $values ) {
738
+ if ( $name == 'BuddyPress Default Home Theme' )
739
+ continue;
740
+
741
+ $member_themes[] = array(
742
+ 'name' => $name,
743
+ 'template' => $values['Template'],
744
+ 'version' => $values['Version']
745
+ );
746
+ }
747
+ }
748
+
749
+ /* Restore the cached WP themes */
750
+ $wp_themes = $wp_existing_themes;
751
+
752
+ return $member_themes;
753
+ }
754
+ function bp_core_get_member_themes() { return bp_core_get_buddypress_themes(); } // DEPRECATED
755
+
756
+ function bp_get_buddypress_theme_uri() {
757
+ return apply_filters( 'bp_get_buddypress_theme_uri', WP_CONTENT_URL . '/bp-themes/' . get_site_option( 'active-member-theme' ) );
758
+ }
759
+
760
+ function bp_get_buddypress_theme_path() {
761
+ return apply_filters( 'bp_get_buddypress_theme_path', WP_CONTENT_DIR . '/bp-themes/' . get_site_option( 'active-member-theme' ) );
762
+ }
763
+
764
+ function bp_core_filter_buddypress_theme_root() {
765
+ return apply_filters( 'bp_core_filter_buddypress_theme_root', WP_CONTENT_DIR . "/bp-themes" );
766
+ }
767
+
768
+ function bp_core_filter_buddypress_theme_root_uri() {
769
+ return apply_filters( 'bp_core_filter_buddypress_theme_root_uri', WP_CONTENT_URL . '/bp-themes' );
770
+ }
771
+
772
+ function bp_core_force_buddypress_theme( $template ) {
773
+ global $is_member_page, $bp;
774
+
775
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
776
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
777
+ return $template;
778
+
779
+ if ( $is_member_page ) {
780
+ $member_theme = get_site_option( 'active-member-theme' );
781
+
782
+ if ( empty( $member_theme ) )
783
+ $member_theme = 'bpmember';
784
+
785
+ add_filter( 'theme_root', 'bp_core_filter_buddypress_theme_root' );
786
+ add_filter( 'theme_root_uri', 'bp_core_filter_buddypress_theme_root_uri' );
787
+
788
+ return $member_theme;
789
+ } else {
790
+ return $template;
791
+ }
792
+ }
793
+ add_filter( 'template', 'bp_core_force_buddypress_theme' );
794
+
795
+ function bp_core_force_buddypress_stylesheet( $stylesheet ) {
796
+ global $is_member_page;
797
+
798
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
799
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
800
+ return $stylesheet;
801
+
802
+ $member_theme = get_site_option( 'active-member-theme' );
803
+
804
+ if ( empty( $member_theme ) )
805
+ $member_theme = 'bpmember';
806
+
807
+ if ( $is_member_page ) {
808
+ add_filter( 'theme_root', 'bp_core_filter_buddypress_theme_root' );
809
+ add_filter( 'theme_root_uri', 'bp_core_filter_buddypress_theme_root_uri' );
810
+
811
+ return $member_theme;
812
+ } else {
813
+ return $stylesheet;
814
+ }
815
+ }
816
+ add_filter( 'stylesheet', 'bp_core_force_buddypress_stylesheet' );
817
+
818
+
819
+ /* DEPRECATED - All CSS is in the theme in BP 1.1+ */
820
+ function bp_core_add_structure_css() {
821
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
822
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
823
+ return false;
824
+
825
+ /* Enqueue the structure CSS file to give basic positional formatting for components */
826
+ wp_enqueue_style( 'bp-core-structure', BP_PLUGIN_URL . '/bp-core/deprecated/css/structure.css' );
827
+ }
828
+ add_action( 'bp_styles', 'bp_core_add_structure_css' );
829
+
830
+ /* DEPRECATED - All CSS is now in the theme */
831
+ function bp_core_add_css() {
832
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
833
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
834
+ return false;
835
+
836
+ // Enable a sitewide CSS file that will apply styles to both the home blog theme
837
+ // and the member theme.
838
+ if ( file_exists( WP_CONTENT_DIR . '/themes/' . get_blog_option( BP_ROOT_BLOG, 'stylesheet' ) . '/css/site-wide.css' ) )
839
+ wp_enqueue_style( 'site-wide-styles', WP_CONTENT_URL . '/themes/' . get_blog_option( BP_ROOT_BLOG, 'stylesheet' ) . '/css/site-wide.css' );
840
+
841
+ wp_print_styles();
842
+ }
843
+ add_action( 'wp_head', 'bp_core_add_css', 2 );
844
+
845
+ /* DEPRECATED - Admin bar CSS is now in the theme */
846
+ function bp_core_admin_bar_css() {
847
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
848
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
849
+ return false;
850
+
851
+ if ( defined( 'BP_DISABLE_ADMIN_BAR') )
852
+ return false;
853
+
854
+ if ( is_user_logged_in() || ( !(int)get_site_option( 'hide-loggedout-adminbar' ) && !is_user_logged_in() ) ) {
855
+ wp_enqueue_style( 'bp-admin-bar', apply_filters( 'bp_core_admin_bar_css', BP_PLUGIN_URL . '/bp-core/deprecated/css/admin-bar.css' ) );
856
+
857
+ if ( 'rtl' == get_bloginfo('text_direction') && file_exists( BP_PLUGIN_DIR . '/bp-core/deprecated/css/admin-bar-rtl.css' ) )
858
+ wp_enqueue_style( 'bp-admin-bar-rtl', BP_PLUGIN_URL . '/bp-core/deprecated/css/admin-bar-rtl.css' );
859
+ }
860
+ }
861
+ add_action( 'wp_head', 'bp_core_admin_bar_css' );
862
+ add_action( 'admin_menu', 'bp_core_admin_bar_css' );
863
+
864
+ /* DEPRECATED - Javascript is added by the theme on a per-theme basis. */
865
+ function bp_core_add_js() {
866
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
867
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
868
+ return $template;
869
+
870
+ wp_enqueue_script( 'jquery' );
871
+ wp_enqueue_script( 'jquery-livequery-pack', BP_PLUGIN_URL . '/bp-core/deprecated/js/jquery/jquery.livequery.pack.js', 'jquery' );
872
+ wp_enqueue_script( 'bp-general-js', BP_PLUGIN_URL . '/bp-core/deprecated/js/general.js' );
873
+ }
874
+ add_action( 'wp', 'bp_core_add_js' );
875
+ add_action( 'admin_menu', 'bp_core_add_js' );
876
+
877
+ function bp_core_directory_members_js() {
878
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
879
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
880
+ return $template;
881
+
882
+ wp_enqueue_script( 'bp-core-directory-members', BP_PLUGIN_URL . '/bp-core/deprecated/js/directory-members.js', array( 'jquery', 'jquery-livequery-pack' ) );
883
+ }
884
+ add_action( 'bp_core_action_directory_members', 'bp_core_directory_members_js' );
885
+
886
+ /*** END DEPRECATED OLD BUDDYPRESS THEME SUPPORT ************/
887
+
888
+ function bp_core_ajax_directory_members() {
889
+ /* If we are using a BuddyPress 1.1+ theme ignore this. */
890
+ if ( !file_exists( WP_CONTENT_DIR . '/bp-themes' ) )
891
+ return false;
892
+
893
+ check_ajax_referer('directory_members');
894
+
895
+ locate_template( array( 'directories/members/members-loop.php' ), true );
896
+ }
897
+ add_action( 'wp_ajax_directory_members', 'bp_core_ajax_directory_members' );
898
+
899
+ /* DEPRECATED -- This should now be directly in the template */
900
+ function bp_login_bar() {
901
+ global $bp;
902
+
903
+ if ( !is_user_logged_in() ) : ?>
904
+
905
+ <form name="login-form" id="login-form" action="<?php echo $bp->root_domain . '/wp-login.php' ?>" method="post">
906
+ <input type="text" name="log" id="user_login" value="<?php _e( 'Username', 'buddypress' ) ?>" onfocus="if (this.value == '<?php _e( 'Username', 'buddypress' ) ?>') {this.value = '';}" onblur="if (this.value == '') {this.value = '<?php _e( 'Username', 'buddypress' ) ?>';}" />
907
+ <input type="password" name="pwd" id="user_pass" class="input" value="" />
908
+
909
+ <input type="checkbox" name="rememberme" id="rememberme" value="forever" title="<?php _e( 'Remember Me', 'buddypress' ) ?>" />
910
+
911
+ <input type="submit" name="wp-submit" id="wp-submit" value="<?php _e( 'Log In', 'buddypress' ) ?>"/>
912
+ <input type="button" name="signup-submit" id="signup-submit" value="<?php _e( 'Sign Up', 'buddypress' ) ?>" onclick="location.href='<?php echo bp_signup_page() ?>'" />
913
+
914
+ <input type="hidden" name="redirect_to" value="http://<?php echo $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] ?>" />
915
+ <input type="hidden" name="testcookie" value="1" />
916
+
917
+ <?php do_action( 'bp_login_bar_logged_out' ) ?>
918
+ </form>
919
+
920
+ <?php else : ?>
921
+
922
+ <div id="logout-link">
923
+ <?php bp_loggedinuser_avatar_thumbnail( 20, 20 ) ?> &nbsp;
924
+ <?php bp_loggedinuser_link() ?>
925
+ <?php
926
+ if ( function_exists('wp_logout_url') ) {
927
+ $logout_link = '/ <a href="' . wp_logout_url( $bp->root_domain ) . '">' . __( 'Log Out', 'buddypress' ) . '</a>';
928
+ } else {
929
+ $logout_link = '/ <a href="' . $bp->root_domain . '/wp-login.php?action=logout&amp;redirect_to=' . $bp->root_domain . '">' . __( 'Log Out', 'buddypress' ) . '</a>';
930
+ }
931
+
932
+ echo apply_filters( 'bp_logout_link', $logout_link );
933
+ ?>
934
+
935
+ <?php do_action( 'bp_login_bar_logged_in' ) ?>
936
+ </div>
937
+
938
+ <?php endif;
939
+ }
940
+
941
+ /* DEPRECATED - use the param 'default_subnav_slug' in bp_core_new_nav_item() OR bp_core_new_nav_default() */
942
+ function bp_core_add_nav_default( $parent_id, $function, $slug = false, $user_has_access = true, $admin_only = false ) {
943
+ global $bp;
944
+
945
+ if ( !$user_has_access && !bp_is_home() )
946
+ return false;
947
+
948
+ if ( $admin_only && !is_site_admin() )
949
+ return false;
950
+
951
+ if ( $bp->current_component == $parent_id && !$bp->current_action ) {
952
+ if ( function_exists($function) ) {
953
+ add_action( 'wp', $function, 3 );
954
+ }
955
+
956
+ if ( $slug )
957
+ $bp->current_action = $slug;
958
+ }
959
+ }
960
+
961
+ /* DEPRECATED - use <?php locate_template( array( 'userbar.php' ), true ) ?> */
962
+ function bp_get_userbar( $hide_on_directory = true ) {
963
+ global $bp;
964
+
965
+ if ( $hide_on_directory && $bp->is_directory )
966
+ return false;
967
+
968
+ load_template( TEMPLATEPATH . '/userbar.php' );
969
+ }
970
+
971
+ /* DEPRECATED - use <?php locate_template( array( 'optionsbar.php' ), true ) ?> */
972
+ function bp_get_optionsbar( $hide_on_directory = true ) {
973
+ global $bp;
974
+
975
+ if ( $hide_on_directory && $bp->is_directory )
976
+ return false;
977
+
978
+ load_template( TEMPLATEPATH . '/optionsbar.php' );
979
+ }
980
+
bp-core/{css → deprecated/css}/admin-bar.css RENAMED
@@ -16,10 +16,15 @@ body { padding-top: 28px !important; }
16
 
17
  #wp-admin-bar * { z-index: 999 !important; }
18
 
19
- #wp-admin-bar img#admin-bar-logo {
20
  position: absolute !important;
21
  top: 8px;
22
  left: 10px;
 
 
 
 
 
23
  }
24
 
25
  #wp-admin-bar a img {
16
 
17
  #wp-admin-bar * { z-index: 999 !important; }
18
 
19
+ #wp-admin-bar a#admin-bar-logo {
20
  position: absolute !important;
21
  top: 8px;
22
  left: 10px;
23
+ background: url( ../images/admin_bar_logo.gif) top left no-repeat;
24
+ text-indent: -999em;
25
+ width: 61px;
26
+ height: 14px;
27
+ overflow: hidden;
28
  }
29
 
30
  #wp-admin-bar a img {
bp-core/{css → deprecated/css}/structure.css RENAMED
@@ -61,6 +61,7 @@ These structure styles can be overridden by the theme CSS file if needed.
61
  * Main Column & Info Groups
62
  */
63
 
 
64
  .main-column {
65
  margin-left: 200px;
66
  }
@@ -245,7 +246,7 @@ table.notification-settings {
245
  /* Buttons */
246
 
247
  .friendship-button {
248
- background: url(../../bp-core/images/button_back.gif) top left no-repeat;
249
  display: inline-block;
250
  margin-bottom: 10px;
251
  margin-left: -6px;
@@ -268,19 +269,19 @@ table.notification-settings {
268
  }
269
 
270
  .friendship-button a.add {
271
- background: url(../../bp-core/images/add_button_side.gif) top right no-repeat;
272
  }
273
 
274
  .friendship-button a.remove {
275
- background: url(../../bp-core/images/remove_button_side.gif) top right no-repeat;
276
  }
277
 
278
  .friendship-button a.requested {
279
- background: url(../../bp-core/images/check_button_side.gif) top right no-repeat;
280
  }
281
 
282
  .loading a {
283
- background: url(../../bp-core/images/loading_button_side.gif) top right no-repeat !important;
284
  }
285
 
286
  .button-block {
@@ -289,7 +290,7 @@ table.notification-settings {
289
  }
290
 
291
  .generic-button {
292
- background: url(../../bp-core/images/button_back.gif) top left no-repeat;
293
  display: inline-block;
294
  margin: 0 5px 8px 0;
295
  }
@@ -303,10 +304,10 @@ table.notification-settings {
303
  margin-right: -7px;
304
  text-shadow: 0 1px 0 #fff;
305
  text-decoration: none;
306
- background: url(../../bp-core/images/view_button_side.gif) top right no-repeat;
307
  }
308
- .accept a { background-image: url(../../bp-core/images/accept_button_side.gif); }
309
- .reject a { background-image: url(../../bp-core/images/reject_button_side.gif); }
310
 
311
  .generic-button a:hover {
312
  color: #555;
61
  * Main Column & Info Groups
62
  */
63
 
64
+
65
  .main-column {
66
  margin-left: 200px;
67
  }
246
  /* Buttons */
247
 
248
  .friendship-button {
249
+ background: url(../../../bp-core/deprecated/images/button_back.gif) top left no-repeat;
250
  display: inline-block;
251
  margin-bottom: 10px;
252
  margin-left: -6px;
269
  }
270
 
271
  .friendship-button a.add {
272
+ background: url(../../../bp-core/deprecated/images/add_button_side.gif) top right no-repeat;
273
  }
274
 
275
  .friendship-button a.remove {
276
+ background: url(../../../bp-core/deprecated/images/remove_button_side.gif) top right no-repeat;
277
  }
278
 
279
  .friendship-button a.requested {
280
+ background: url(../../../bp-core/deprecated/images/check_button_side.gif) top right no-repeat;
281
  }
282
 
283
  .loading a {
284
+ background: url(../../../bp-core/deprecated/images/loading_button_side.gif) top right no-repeat !important;
285
  }
286
 
287
  .button-block {
290
  }
291
 
292
  .generic-button {
293
+ background: url(../../../bp-core/deprecated/images/button_back.gif) top left no-repeat;
294
  display: inline-block;
295
  margin: 0 5px 8px 0;
296
  }
304
  margin-right: -7px;
305
  text-shadow: 0 1px 0 #fff;
306
  text-decoration: none;
307
+ background: url(../../../bp-core/deprecated/images/view_button_side.gif) top right no-repeat;
308
  }
309
+ .accept a { background-image: url(../../../bp-core/deprecated/images/accept_button_side.gif); }
310
+ .reject a { background-image: url(../../../bp-core/deprecated/images/reject_button_side.gif); }
311
 
312
  .generic-button a:hover {
313
  color: #555;
bp-core/{images → deprecated/images}/accept_button_side.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/add_button_side.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/add_friend_button.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/admin-menu-arrow.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/admin_bar_back.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/admin_bar_logo.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/ajax-loader.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/blog.png RENAMED
File without changes
bp-core/{images → deprecated/images}/button_back.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/check_button_side.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/loading_button_side.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/logout_bullet.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/member.png RENAMED
File without changes
bp-core/{images → deprecated/images}/nav_bullet.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/reject_button_side.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/remove_button_side.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/remove_friend_button.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/requested_friend_button.gif RENAMED
File without changes
bp-core/{images → deprecated/images}/view_button_side.gif RENAMED
File without changes
bp-core/{js → deprecated/js}/directory-members.js RENAMED
File without changes
bp-core/{js → deprecated/js}/general.js RENAMED
@@ -87,7 +87,6 @@ jQuery("div#wire-pagination a").livequery('click',
87
  }
88
  );
89
 
90
-
91
  function clear(container) {
92
  if(!document.getElementById(container)) return false;
93
 
@@ -99,14 +98,3 @@ function clear(container) {
99
  radioButtons[i].checked = false;
100
  }
101
  }
102
-
103
- /* For admin-bar */
104
- jQuery(document).ready( function() {
105
- jQuery("#wp-admin-bar ul.main-nav li").mouseover( function() {
106
- jQuery(this).addClass('sfhover');
107
- });
108
-
109
- jQuery("#wp-admin-bar ul.main-nav li").mouseout( function() {
110
- jQuery(this).removeClass('sfhover');
111
- });
112
- });
87
  }
88
  );
89
 
 
90
  function clear(container) {
91
  if(!document.getElementById(container)) return false;
92
 
98
  radioButtons[i].checked = false;
99
  }
100
  }
 
 
 
 
 
 
 
 
 
 
 
bp-core/{js → deprecated/js}/jquery/jquery.livequery.pack.js RENAMED
File without changes
bp-core/{js → deprecated/js}/jquery/jquery.tablednd.js RENAMED
File without changes
bp-core/images/Jcrop.gif ADDED
Binary file
bp-core/images/admin_menu_icon.png ADDED
Binary file
bp-core/js/admin-bar.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready( function() {
2
+ jQuery("#wp-admin-bar ul.main-nav li").mouseover( function() {
3
+ jQuery(this).addClass('sfhover');
4
+ });
5
+
6
+ jQuery("#wp-admin-bar ul.main-nav li").mouseout( function() {
7
+ jQuery(this).removeClass('sfhover');
8
+ });
9
+ });
bp-core/js/widget-members.js CHANGED
@@ -15,6 +15,7 @@ jQuery(document).ready( function() {
15
  },
16
  function(response)
17
  {
 
18
  member_wiget_response(response);
19
  });
20
 
@@ -30,7 +31,6 @@ function member_wiget_response(response) {
30
  if ( response[0] != "-1" ) {
31
  jQuery("ul#members-list").fadeOut(200,
32
  function() {
33
- jQuery('#ajax-loader-members').toggle();
34
  jQuery("ul#members-list").html(response[1]);
35
  jQuery("ul#members-list").fadeIn(200);
36
  }
@@ -39,7 +39,6 @@ function member_wiget_response(response) {
39
  } else {
40
  jQuery("ul#members-list").fadeOut(200,
41
  function() {
42
- jQuery('#ajax-loader-members').toggle();
43
  var message = '<p>' + response[1] + '</p>';
44
  jQuery("ul#members-list").html(message);
45
  jQuery("ul#members-list").fadeIn(200);
15
  },
16
  function(response)
17
  {
18
+ jQuery('#ajax-loader-members').toggle();
19
  member_wiget_response(response);
20
  });
21
 
31
  if ( response[0] != "-1" ) {
32
  jQuery("ul#members-list").fadeOut(200,
33
  function() {
 
34
  jQuery("ul#members-list").html(response[1]);
35
  jQuery("ul#members-list").fadeIn(200);
36
  }
39
  } else {
40
  jQuery("ul#members-list").fadeOut(200,
41
  function() {
 
42
  var message = '<p>' + response[1] + '</p>';
43
  jQuery("ul#members-list").html(message);
44
  jQuery("ul#members-list").fadeIn(200);
bp-forums.php CHANGED
@@ -2,185 +2,371 @@
2
 
3
  /* Define the parent forum ID */
4
  if ( !defined( 'BP_FORUMS_PARENT_FORUM_ID' ) )
5
- define ( 'BP_FORUMS_PARENT_FORUM_ID', 1 );
 
 
 
 
 
 
6
 
7
- require ( BP_PLUGIN_DIR . '/bp-forums/bp-forums-bbpress-live.php' );
8
  require ( BP_PLUGIN_DIR . '/bp-forums/bp-forums-templatetags.php' );
9
  require ( BP_PLUGIN_DIR . '/bp-forums/bp-forums-filters.php' );
10
 
11
- if ( is_admin() )
12
- require ( BP_PLUGIN_DIR . '/bp-forums/bp-forums-admin.php' );
13
-
14
  function bp_forums_setup() {
15
- global $bp, $bbpress_live;
16
 
17
- if ( '' == get_usermeta( $bp->loggedin_user->id, 'bb_capabilities' ) )
18
- bp_forums_make_user_active_member( $bp->loggedin_user->id );
 
 
 
 
19
 
20
- $bp->version_numbers->forums = BP_FORUMS_VERSION;
 
 
 
21
  }
22
  add_action( 'plugins_loaded', 'bp_forums_setup', 5 );
23
- add_action( 'admin_head', 'bp_forums_setup', 3 );
24
 
25
  function bp_forums_is_installed_correctly() {
26
- global $bbpress_live;
 
 
 
27
 
28
- if ( !is_object( $bbpress_live ) ) {
29
- include_once( ABSPATH . WPINC . '/class-IXR.php' );
30
- $bbpress_live = new bbPress_Live();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  }
 
 
 
 
 
32
 
33
- if ( !$bbpress_live->fetch->endpoint )
34
  return false;
 
 
35
 
36
- return true;
 
 
 
 
 
 
 
 
 
37
  }
38
 
39
- function bp_forums_get_forum( $parent = 0, $depth = 0 ) {
40
- global $bbpress_live;
41
 
42
- if ( !is_object( $bbpress_live ) ) {
43
- include_once( ABSPATH . WPINC . '/class-IXR.php' );
44
- $bbpress_live = new bbPress_Live();
45
- }
 
 
 
 
 
 
46
 
47
- if ( $forum = $bbpress_live->get_forums( $parent, $depth ) ) {
48
- do_action( 'bp_forums_get_forum', $forum );
49
- return $forum;
50
- }
 
51
 
52
- return false;
 
 
 
53
  }
54
 
55
- function bp_forums_get_topics( $forum_id = 0, $number = 0, $page = 1 ) {
56
- global $bbpress_live;
 
 
57
 
58
- if ( !is_object( $bbpress_live ) ) {
59
- include_once( ABSPATH . WPINC . '/class-IXR.php' );
60
- $bbpress_live = new bbPress_Live();
61
- }
62
 
63
- if ( $topics = $bbpress_live->get_topics( $forum_id, $number, $page ) ) {
64
- do_action( 'bp_forums_get_topics', $topics );
65
- return $topics;
66
- }
 
 
 
 
 
67
 
68
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  }
70
 
71
- function bp_forums_get_topic_details( $topic_id = 0 ) {
72
- global $bbpress_live;
 
 
 
 
 
73
 
74
- if ( !is_object( $bbpress_live ) ) {
75
- include_once( ABSPATH . WPINC . '/class-IXR.php' );
76
- $bbpress_live = new bbPress_Live();
77
- }
78
 
79
- if ( $topic = $bbpress_live->get_topic_details( $topic_id ) ) {
80
- do_action( 'bp_forums_get_topic_details', $topic );
81
- return $topic;
82
- }
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
- return false;
 
 
 
 
 
 
 
 
 
 
85
  }
86
 
87
- function bp_forums_get_posts( $topic_id = 0, $number = 0, $page = 1 ) {
88
- global $bbpress_live;
89
 
90
- if ( !is_object( $bbpress_live ) ) {
91
- include_once( ABSPATH . WPINC . '/class-IXR.php' );
92
- $bbpress_live = new bbPress_Live();
93
- }
94
 
95
- if ( $posts = $bbpress_live->get_posts( $topic_id, $number, $page ) ) {
96
- do_action( 'bp_forums_get_posts', $posts );
97
- return $posts;
98
- }
 
99
 
100
- return false;
101
- }
102
-
103
- function bp_forums_get_post( $post_id = 0 ) {
104
- global $bbpress_live;
105
 
106
- if ( !is_object( $bbpress_live ) ) {
107
- include_once( ABSPATH . WPINC . '/class-IXR.php' );
108
- $bbpress_live = new bbPress_Live();
109
- }
110
-
111
- if ( $post = $bbpress_live->get_post( $post_id ) ) {
112
- do_action( 'bp_forums_get_post', $post );
113
- return $post;
114
- }
115
 
116
- return false;
 
 
 
 
117
  }
118
 
119
- function bp_forums_new_forum( $name = '', $desc = '', $parent = BP_FORUMS_PARENT_FORUM_ID, $order = 0, $is_category = false ) {
120
- global $bbpress_live;
121
 
122
- if ( !is_object( $bbpress_live ) ) {
123
- include_once( ABSPATH . WPINC . '/class-IXR.php' );
124
- $bbpress_live = new bbPress_Live();
125
- }
126
 
127
- if ( $forum = $bbpress_live->new_forum( $name, $desc, $parent, $order, $is_category ) ) {
128
- do_action( 'bp_forums_new_forum', $forum );
129
- return $forum;
130
- }
 
 
 
131
 
 
 
 
 
 
132
  return false;
133
  }
134
 
135
- function bp_forums_new_topic( $title = '', $topic_text = '', $topic_tags = '', $forum_id = 0 ) {
136
- global $bbpress_live;
137
-
138
- if ( !is_object( $bbpress_live ) ) {
139
- include_once( ABSPATH . WPINC . '/class-IXR.php' );
140
- $bbpress_live = new bbPress_Live();
141
- }
142
 
143
- $topic_text = apply_filters( 'bp_forums_new_post_text', $topic_text );
144
- $title = apply_filters( 'bp_forums_new_post_title', $title );
145
- $topic_tags = apply_filters( 'bp_forums_new_post_tags', $topic_tags );
146
 
147
- if ( $topic = $bbpress_live->new_topic( $title, $topic_text, $topic_tags, (int)$forum_id ) ) {
148
- do_action( 'bp_forums_new_topic', $topic );
149
- return $topic;
150
- }
 
 
 
151
 
 
 
 
 
 
152
  return false;
153
  }
154
 
155
- function bp_forums_new_post( $post_text = '', $topic_id = 0 ) {
156
- global $bbpress_live;
157
-
158
- if ( !is_object( $bbpress_live ) ) {
159
- include_once( ABSPATH . WPINC . '/class-IXR.php' );
160
- $bbpress_live = new bbPress_Live();
161
- }
162
 
163
- $post_text = apply_filters( 'bp_forums_new_post_text', $post_text );
164
 
165
- if ( $post = $bbpress_live->new_post( $post_text, (int)$topic_id ) ) {
166
- do_action( 'bp_forums_new_post', $post );
167
- return $post;
168
- }
 
 
 
 
 
 
 
 
 
 
169
 
170
- return false;
 
 
 
 
 
 
 
 
 
 
171
  }
172
 
173
- function bp_forums_make_user_active_member( $user_id ) {
174
- update_usermeta( $user_id, 'bb_capabilities', array( 'member' => true ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  }
176
- add_action( 'wpmu_new_user', 'bp_forums_make_user_active_member' );
177
 
178
- function bp_forums_get_keymaster() {
179
- global $wpdb;
180
 
181
- $user_id = $wpdb->get_var( $wpdb->prepare( "SELECT user_id FROM " . CUSTOM_USER_META_TABLE . " WHERE meta_key = 'bb_capabilities' AND meta_value LIKE '%%keymaster%%'" ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
 
183
- return get_userdata( $user_id );
 
 
 
 
 
 
184
  }
185
 
186
  // List actions to clear super cached pages on, if super cache is installed
@@ -188,6 +374,19 @@ add_action( 'bp_forums_new_forum', 'bp_core_clear_cache' );
188
  add_action( 'bp_forums_new_topic', 'bp_core_clear_cache' );
189
  add_action( 'bp_forums_new_post', 'bp_core_clear_cache' );
190
 
 
 
 
 
191
 
192
-
 
 
 
 
 
 
 
 
 
193
  ?>
2
 
3
  /* Define the parent forum ID */
4
  if ( !defined( 'BP_FORUMS_PARENT_FORUM_ID' ) )
5
+ define( 'BP_FORUMS_PARENT_FORUM_ID', 1 );
6
+
7
+ if ( !defined( 'BP_FORUMS_SLUG' ) )
8
+ define( 'BP_FORUMS_SLUG', 'forums' );
9
+
10
+ if ( !defined( 'BB_PATH' ) )
11
+ require ( BP_PLUGIN_DIR . '/bp-forums/bp-forums-bbpress.php' );
12
 
 
13
  require ( BP_PLUGIN_DIR . '/bp-forums/bp-forums-templatetags.php' );
14
  require ( BP_PLUGIN_DIR . '/bp-forums/bp-forums-filters.php' );
15
 
 
 
 
16
  function bp_forums_setup() {
17
+ global $bp;
18
 
19
+ /* For internal identification */
20
+ $bp->forums->id = 'forums';
21
+
22
+ $bp->forums->image_base = BP_PLUGIN_URL . '/bp-forums/images';
23
+ $bp->forums->bbconfig = get_site_option( 'bb-config-location' );
24
+ $bp->forums->slug = BP_FORUMS_SLUG;
25
 
26
+ /* Register this in the active components array */
27
+ $bp->active_components[$bp->forums->slug] = $bp->forums->id;
28
+
29
+ do_action( 'bp_forums_setup' );
30
  }
31
  add_action( 'plugins_loaded', 'bp_forums_setup', 5 );
32
+ add_action( 'admin_head', 'bp_forums_setup', 2 );
33
 
34
  function bp_forums_is_installed_correctly() {
35
+ global $bp;
36
+
37
+ if ( file_exists( $bp->forums->bbconfig ) )
38
+ return true;
39
 
40
+ return false;
41
+ }
42
+
43
+ function bp_forums_setup_root_component() {
44
+ /* Register 'forums' as a root component */
45
+ bp_core_add_root_component( BP_FORUMS_SLUG );
46
+ }
47
+ add_action( 'plugins_loaded', 'bp_forums_setup_root_component', 2 );
48
+
49
+ function bp_forums_directory_forums_setup() {
50
+ global $bp;
51
+
52
+ if ( $bp->current_component == $bp->forums->slug ) {
53
+ if ( (int) get_site_option( 'bp-disable-forum-directory' ) || !function_exists( 'groups_install' ) )
54
+ return false;
55
+
56
+ if ( !bp_forums_is_installed_correctly() ) {
57
+ bp_core_add_message( __( 'The forums component has not been set up yet.', 'buddypress' ), 'error' );
58
+ bp_core_redirect( $bp->root_domain );
59
+ }
60
+
61
+ $bp->is_directory = true;
62
+
63
+ do_action( 'bbpress_init' );
64
+ do_action( 'bp_forums_directory_forums_setup' );
65
+ bp_core_load_template( apply_filters( 'bp_forums_template_directory_forums_setup', 'directories/forums/index' ) );
66
  }
67
+ }
68
+ add_action( 'wp', 'bp_forums_directory_forums_setup', 2 );
69
+
70
+ function bp_forums_add_admin_menu() {
71
+ global $bp;
72
 
73
+ if ( !is_site_admin() )
74
  return false;
75
+
76
+ require ( BP_PLUGIN_DIR . '/bp-forums/bp-forums-admin.php' );
77
 
78
+ /* Add the administration tab under the "Site Admin" tab for site administrators */
79
+ add_submenu_page( 'bp-general-settings', __( 'Forums Setup', 'buddypress' ), __( 'Forums Setup', 'buddypress' ), 'manage_options', 'bb-forums-setup', "bp_forums_bbpress_admin" );
80
+ }
81
+ add_action( 'admin_menu', 'bp_forums_add_admin_menu' );
82
+
83
+ /* Forum Functions */
84
+
85
+ function bp_forums_get_forum( $forum_id ) {
86
+ do_action( 'bbpress_init' );
87
+ return bb_get_forum( $forum_id );
88
  }
89
 
90
+ function bp_forums_new_forum( $args = '' ) {
91
+ do_action( 'bbpress_init' );
92
 
93
+ $defaults = array(
94
+ 'forum_name' => '',
95
+ 'forum_desc' => '',
96
+ 'forum_parent_id' => BP_FORUMS_PARENT_FORUM_ID,
97
+ 'forum_order' => false,
98
+ 'forum_is_category' => 0
99
+ );
100
+
101
+ $r = wp_parse_args( $args, $defaults );
102
+ extract( $r, EXTR_SKIP );
103
 
104
+ return bb_new_forum( array( 'forum_name' => stripslashes( $forum_name ), 'forum_desc' => stripslashes( $forum_desc ), 'forum_parent' => $forum_parent_id, 'forum_order' => $forum_order, 'forum_is_category' => $forum_is_category ) );
105
+ }
106
+
107
+ function bp_forums_get_forum_topicpost_count( $forum_id ) {
108
+ global $wpdb, $bbdb;
109
 
110
+ do_action( 'bbpress_init' );
111
+
112
+ /* Need to find a bbPress function that does this */
113
+ return $wpdb->get_results( $wpdb->prepare( "SELECT topics, posts from {$bbdb->forums} WHERE forum_id = %d", $forum_id ) );
114
  }
115
 
116
+ /* Topic Functions */
117
+
118
+ function bp_forums_get_forum_topics( $args = '' ) {
119
+ global $bp;
120
 
121
+ do_action( 'bbpress_init' );
 
 
 
122
 
123
+ $defaults = array(
124
+ 'type' => 'newest',
125
+ 'forum_id' => false,
126
+ 'page' => 1,
127
+ 'per_page' => 15,
128
+ 'exclude' => false,
129
+ 'show_stickies' => 'all',
130
+ 'filter' => false // if $type = tag then filter is the tag name, otherwise it's terms to search on.
131
+ );
132
 
133
+ $r = wp_parse_args( $args, $defaults );
134
+ extract( $r, EXTR_SKIP );
135
+
136
+ switch ( $type ) {
137
+ case 'newest':
138
+ $query = new BB_Query( 'topic', array( 'forum_id' => $forum_id, 'per_page' => $per_page, 'page' => $page, 'number' => $per_page, 'exclude' => $exclude, 'topic_title' => $filter, 'sticky' => $show_stickies ), 'get_latest_topics' );
139
+ $topics = $query->results;
140
+ break;
141
+
142
+ case 'popular':
143
+ $query = new BB_Query( 'topic', array( 'forum_id' => $forum_id, 'per_page' => $per_page, 'page' => $page, 'order_by' => 't.topic_posts', 'topic_title' => $filter, 'sticky' => $show_stickies ) );
144
+ $topics =& $query->results;
145
+ break;
146
+
147
+ case 'unreplied':
148
+ $query = new BB_Query( 'topic', array( 'forum_id' => $forum_id, 'post_count' => 1, 'per_page' => $per_page, 'page' => $page, 'order_by' => 't.topic_time', 'topic_title' => $filter, 'sticky' => $show_stickies ) );
149
+ $topics =& $query->results;
150
+ break;
151
+
152
+ case 'personal':
153
+ $query = new BB_Query( 'topic', array( 'forum_id' => $forum_id, 'per_page' => $per_page, 'page' => $page, 'topic_author_id' => $bp->loggedin_user->id, 'order_by' => 't.topic_time', 'topic_title' => $filter, 'sticky' => $show_stickies ), 'get_recent_user_threads' );
154
+ $topics =& $query->results;
155
+ break;
156
+
157
+ case 'tag':
158
+ $query = new BB_Query( 'topic', array( 'forum_id' => $forum_id, 'tag' => $filter, 'per_page' => $per_page, 'page' => $page, 'order_by' => 't.topic_time', 'sticky' => $show_stickies ) );
159
+ $topics =& $query->results;
160
+ break;
161
+ }
162
+
163
+ return apply_filters( 'bp_forums_get_forum_topics', $topics, &$r );
164
+ }
165
+
166
+ function bp_forums_get_topic_details( $topic_id ) {
167
+ do_action( 'bbpress_init' );
168
+
169
+ $query = new BB_Query( 'topic', 'topic_id=' . $topic_id );
170
+ return $query->results[0];
171
  }
172
 
173
+ function bp_forums_get_topic_id_from_slug( $topic_slug ) {
174
+ do_action( 'bbpress_init' );
175
+ return bb_get_id_from_slug( 'topic', $topic_slug );
176
+ }
177
+
178
+ function bp_forums_new_topic( $args = '' ) {
179
+ global $bp;
180
 
181
+ do_action( 'bbpress_init' );
 
 
 
182
 
183
+ $defaults = array(
184
+ 'topic_title' => '',
185
+ 'topic_slug' => '',
186
+ 'topic_poster' => $bp->loggedin_user->id, // accepts ids
187
+ 'topic_poster_name' => $bp->loggedin_user->fullname, // accept names
188
+ 'topic_last_poster' => $bp->loggedin_user->id, // accepts ids
189
+ 'topic_last_poster_name' => $bp->loggedin_user->fullname, // accept names
190
+ 'topic_start_time' => date( 'Y-m-d H:i:s' ),
191
+ 'topic_time' => date( 'Y-m-d H:i:s' ),
192
+ 'topic_open' => 1,
193
+ 'topic_tags' => false, // accepts array or comma delim
194
+ 'forum_id' => 0 // accepts ids or slugs
195
+ );
196
+
197
+ $r = wp_parse_args( $args, $defaults );
198
+ extract( $r, EXTR_SKIP );
199
 
200
+ if ( empty( $topic_slug ) )
201
+ $topic_slug = sanitize_title( $topic_title );
202
+
203
+ if ( !$topic_id = bb_insert_topic( array( 'topic_title' => stripslashes( $topic_title ), 'topic_slug' => $topic_slug, 'topic_poster' => $topic_poster, 'topic_poster_name' => $topic_poster_name, 'topic_last_poster' => $topic_last_poster, 'topic_last_poster_name' => $topic_last_poster_name, 'topic_start_time' => $topic_start_time, 'topic_time' => $topic_time, 'topic_open' => $topic_open, 'forum_id' => (int)$forum_id, 'tags' => $topic_tags ) ) )
204
+ return false;
205
+
206
+ /* Now insert the first post. */
207
+ if ( !bp_forums_insert_post( array( 'topic_id' => $topic_id, 'post_text' => $topic_text, 'post_time' => $topic_time, 'poster_id' => $topic_poster ) ) )
208
+ return false;
209
+
210
+ return $topic_id;
211
  }
212
 
213
+ function bp_forums_update_topic( $args = '' ) {
214
+ global $bp;
215
 
216
+ do_action( 'bbpress_init' );
 
 
 
217
 
218
+ $defaults = array(
219
+ 'topic_id' => false,
220
+ 'topic_title' => '',
221
+ 'topic_text' => ''
222
+ );
223
 
224
+ $r = wp_parse_args( $args, $defaults );
225
+ extract( $r, EXTR_SKIP );
 
 
 
226
 
227
+ if ( !$topic_id = bb_insert_topic( array( 'topic_id' => $topic_id, 'topic_title' => stripslashes( $topic_title ) ) ) )
228
+ return false;
229
+
230
+ if ( !$post = bb_get_first_post( $topic_id ) )
231
+ return false;
 
 
 
 
232
 
233
+ /* Update the first post */
234
+ if ( !$post = bb_insert_post( array( 'post_id' => $post->post_id, 'topic_id' => $topic_id, 'post_text' => $topic_text, 'post_time' => $post->post_time, 'poster_id' => $post->poster_id, 'poster_ip' => $post->poster_ip, 'post_status' => $post->post_status, 'post_position' => $post->post_position ) ) )
235
+ return false;
236
+
237
+ return bp_forums_get_topic_details( $topic_id );
238
  }
239
 
240
+ function bp_forums_sticky_topic( $args = '' ) {
241
+ global $bp;
242
 
243
+ do_action( 'bbpress_init' );
 
 
 
244
 
245
+ $defaults = array(
246
+ 'topic_id' => false,
247
+ 'mode' => 'stick' // stick/unstick
248
+ );
249
+
250
+ $r = wp_parse_args( $args, $defaults );
251
+ extract( $r, EXTR_SKIP );
252
 
253
+ if ( 'stick' == $mode )
254
+ return bb_stick_topic( $topic_id );
255
+ else if ( 'unstick' == $mode )
256
+ return bb_unstick_topic( $topic_id );
257
+
258
  return false;
259
  }
260
 
261
+ function bp_forums_openclose_topic( $args = '' ) {
262
+ global $bp;
 
 
 
 
 
263
 
264
+ do_action( 'bbpress_init' );
 
 
265
 
266
+ $defaults = array(
267
+ 'topic_id' => false,
268
+ 'mode' => 'close' // stick/unstick
269
+ );
270
+
271
+ $r = wp_parse_args( $args, $defaults );
272
+ extract( $r, EXTR_SKIP );
273
 
274
+ if ( 'close' == $mode )
275
+ return bb_close_topic( $topic_id );
276
+ else if ( 'open' == $mode )
277
+ return bb_open_topic( $topic_id );
278
+
279
  return false;
280
  }
281
 
282
+ function bp_forums_delete_topic( $args = '' ) {
283
+ global $bp;
 
 
 
 
 
284
 
285
+ do_action( 'bbpress_init' );
286
 
287
+ $defaults = array(
288
+ 'topic_id' => false
289
+ );
290
+
291
+ $r = wp_parse_args( $args, $defaults );
292
+ extract( $r, EXTR_SKIP );
293
+
294
+ return bb_delete_topic( $topic_id, 1 );
295
+ }
296
+
297
+ /* Post Functions */
298
+
299
+ function bp_forums_get_topic_posts( $args = '' ) {
300
+ do_action( 'bbpress_init' );
301
 
302
+ $defaults = array(
303
+ 'topic_id' => false,
304
+ 'page' => 1,
305
+ 'per_page' => 15,
306
+ 'order' => 'ASC'
307
+ );
308
+
309
+ $args = wp_parse_args( $args, $defaults );
310
+
311
+ $query = new BB_Query( 'post', $args, 'get_thread' );
312
+ return $query->results;
313
  }
314
 
315
+ function bp_forums_get_post( $post_id ) {
316
+ do_action( 'bbpress_init' );
317
+ return bb_get_post( $post_id );
318
+ }
319
+
320
+ function bp_forums_delete_post( $args = '' ) {
321
+ global $bp;
322
+
323
+ do_action( 'bbpress_init' );
324
+
325
+ $defaults = array(
326
+ 'post_id' => false
327
+ );
328
+
329
+ $r = wp_parse_args( $args, $defaults );
330
+ extract( $r, EXTR_SKIP );
331
+
332
+ return bb_delete_post( $post_id, 1 );
333
  }
 
334
 
335
+ function bp_forums_insert_post( $args = '' ) {
336
+ global $bp;
337
 
338
+ do_action( 'bbpress_init' );
339
+
340
+ $defaults = array(
341
+ 'post_id' => false,
342
+ 'topic_id' => false,
343
+ 'post_text' => '',
344
+ 'post_time' => date( 'Y-m-d H:i:s' ),
345
+ 'poster_id' => $bp->loggedin_user->id, // accepts ids or names
346
+ 'poster_ip' => $_SERVER['REMOTE_ADDR'],
347
+ 'post_status' => 0, // use bb_delete_post() instead
348
+ 'post_position' => false
349
+ );
350
+
351
+ $r = wp_parse_args( $args, $defaults );
352
+ extract( $r, EXTR_SKIP );
353
+
354
+ if ( !$post = bp_forums_get_post( $post_id ) )
355
+ $post_id = false;
356
+
357
+ if ( !isset( $topic_id ) )
358
+ $topic_id = $post->topic_id;
359
+
360
+ if ( empty( $post_text ) )
361
+ $post_text = $post->post_text;
362
 
363
+ if ( !isset( $post_time ) )
364
+ $post_time = $post->post_time;
365
+
366
+ if ( !isset( $post_position ) )
367
+ $post_position = $post->post_position;
368
+
369
+ return bb_insert_post( array( 'post_id' => $post_id, 'topic_id' => $topic_id, 'post_text' => stripslashes( $post_text ), 'post_time' => $post_time, 'poster_id' => $poster_id, 'poster_ip' => $poster_ip, 'post_status' => $post_status, 'post_position' => $post_position ) );
370
  }
371
 
372
  // List actions to clear super cached pages on, if super cache is installed
374
  add_action( 'bp_forums_new_topic', 'bp_core_clear_cache' );
375
  add_action( 'bp_forums_new_post', 'bp_core_clear_cache' );
376
 
377
+ function bp_forums_filter_caps( $allcaps ) {
378
+ global $bp, $wp_roles, $bb_table_prefix;
379
+
380
+ $bb_cap = get_usermeta( $bp->loggedin_user->id, $bb_table_prefix . 'capabilities' );
381
 
382
+ if ( empty( $bb_cap ) )
383
+ return $allcaps;
384
+
385
+ $bb_cap = array_keys($bb_cap);
386
+ $bb_cap = $wp_roles->get_role( $bb_cap[0] );
387
+ $bb_cap = $bb_cap->capabilities;
388
+
389
+ return array_merge( (array) $allcaps, (array) $bb_cap );
390
+ }
391
+ add_filter( 'user_has_cap', 'bp_forums_filter_caps' );
392
  ?>
bp-forums/bb-config.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /***
3
+ * *** IMPORTANT ****
4
+ * This file will stop people from accessing your bbPress installation directly.
5
+ * It is very important from a security standpoint that this file is not moved.
6
+ * Your actual bb-config.php file will be installed in the root of your WordPress
7
+ * installation once you set up the forums component in BuddyPress.
8
+ */
9
+
10
+ header("HTTP/1.0 403 Forbidden"); die;
11
+ ?>
bp-forums/bbpress-plugins/buddypress-enable.php DELETED
@@ -1,55 +0,0 @@
1
- <?php
2
- /*
3
- Plugin Name: BuddyPress Support Plugin
4
- Plugin URI: http://buddypress.org/
5
- Description: Modifies bbPress behaviour to provide better support for integration in BuddyPress.
6
- Author: Andy Peatling
7
- Version: 1.0-RC1
8
- Author URI: http://apeatling.wordpress.com/
9
- */
10
-
11
- function for_buddypress_strip_tags( $_post, $post ) {
12
-
13
- // Cast to an array
14
- $_post = (array) $post;
15
- // Set the URI
16
- $_post['post_uri'] = get_post_link( $_post['post_id'] );
17
- // Set readable times
18
- $_post['post_time_since'] = bb_since( $_post['post_time'] );
19
- // Set the display names
20
- $_post['poster_display_name'] = get_user_display_name( $_post['poster_id'] );
21
- // Remove some sensitive data
22
- unset(
23
- $_post['poster_ip'],
24
- $_post['pingback_queued']
25
- );
26
-
27
- return $_post;
28
- }
29
- add_filter( 'bb_xmlrpc_prepare_post', 'for_buddypress_strip_tags', 10, 2 );
30
-
31
- function for_buddypress_prepare_topic( $_topic, $topic ) {
32
- // Cast to an array
33
- $_topic = (array) $topic;
34
- // Set the URI
35
- $_topic['topic_uri'] = get_topic_link( $_topic['topic_id'] );
36
- // Set readable times
37
- $_topic['topic_start_time_since'] = bb_since( $_topic['topic_start_time'] );
38
- $_topic['topic_time_since'] = bb_since( $_topic['topic_time'] );
39
- // Set the display names
40
- $_topic['topic_poster_display_name'] = get_user_display_name( $_topic['topic_poster'] );
41
- $_topic['topic_last_poster_display_name'] = get_user_display_name( $_topic['topic_last_poster'] );
42
-
43
- return $_topic;
44
- }
45
- add_filter( 'bb_xmlrpc_prepare_topic', 'for_buddypress_prepare_topic', 10, 2 );
46
-
47
- function for_buddypress_pre_post( $post_text, $post_id, $topic_id ){
48
- $post_text = stripslashes( stripslashes_deep($post_text) );
49
- $post_text = html_entity_decode( $post_text, ENT_COMPAT, "UTF-8" );
50
-
51
- return $post_text;
52
- }
53
- add_filter( 'pre_post', 'for_buddypress_pre_post', 10, 3 );
54
-
55
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-forums/bbpress/bb-admin/admin-action.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ require_once('../bb-load.php');
3
+
4
+ bb_auth();
5
+ ?>
bp-forums/bbpress/bb-admin/admin-ajax.php ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ define( 'BB_IS_ADMIN', true );
4
+ define( 'DOING_AJAX', true );
5
+
6
+ require_once('../bb-load.php');
7
+
8
+ if ( !class_exists( 'WP_Ajax_Response' ) )
9
+ require_once( BACKPRESS_PATH . 'class.wp-ajax-response.php' );
10
+
11
+ require_once( BB_PATH . 'bb-admin/includes/functions.bb-admin.php' );
12
+
13
+ if ( !$bb_current_id = bb_get_current_user_info( 'id' ) )
14
+ die('-1');
15
+
16
+ function bb_grab_results() {
17
+ global $ajax_results;
18
+ $ajax_results = @ unserialize(func_get_arg(0));
19
+ if ( false === $ajax_results )
20
+ $ajax_results = func_get_args();
21
+ return;
22
+ }
23
+
24
+ $id = (int) @$_POST['id'];
25
+
26
+ switch ( $action = $_POST['action'] ) :
27
+ case 'add-tag' : // $id is topic_id
28
+ if ( !bb_current_user_can('edit_tag_by_on', $bb_current_id, $id) )
29
+ die('-1');
30
+
31
+ bb_check_ajax_referer( "add-tag_$id" );
32
+
33
+ global $tag, $topic;
34
+ add_action('bb_tag_added', 'bb_grab_results', 10, 3);
35
+ add_action('bb_already_tagged', 'bb_grab_results', 10, 3);
36
+ $tag_name = @$_POST['tag'];
37
+ $tag_name = stripslashes( $tag_name );
38
+
39
+ $topic = get_topic( $id );
40
+ if ( !$topic )
41
+ die('0');
42
+
43
+ $tag_name = rawurldecode($tag_name);
44
+ $x = new WP_Ajax_Response();
45
+ foreach ( bb_add_topic_tags( $id, $tag_name ) as $tag_id ) {
46
+ if ( !is_numeric($tag_id) || !$tag = bb_get_tag( (int) $tag_id, bb_get_current_user_info( 'id' ), $topic->topic_id ) ) {
47
+ if ( !$tag = bb_get_tag( $tag_id ) ) {
48
+ continue;
49
+ }
50
+ }
51
+ $tag->user_id = bb_get_current_user_info( 'id' );
52
+ $tag_id_val = $tag->tag_id . '_' . $tag->user_id;
53
+ $tag->raw_tag = esc_attr( $tag->raw_tag );
54
+ $x->add( array(
55
+ 'what' => 'tag',
56
+ 'id' => $tag_id_val,
57
+ 'data' => _bb_list_tag_item( $tag, array( 'list_id' => 'tags-list', 'format' => 'list' ) )
58
+ ) );
59
+ }
60
+ $x->send();
61
+ break;
62
+
63
+ case 'delete-tag' :
64
+ list($tag_id, $user_id) = explode('_', $_POST['id']);
65
+ $tag_id = (int) $tag_id;
66
+ $user_id = (int) $user_id;
67
+ $topic_id = (int) $_POST['topic_id'];
68
+
69
+ if ( !bb_current_user_can('edit_tag_by_on', $user_id, $topic_id) )
70
+ die('-1');
71
+
72
+ bb_check_ajax_referer( "remove-tag_$tag_id|$topic_id" );
73
+
74
+ add_action('bb_rpe_tag_removed', 'bb_grab_results', 10, 3);
75
+
76
+ $tag = bb_get_tag( $tag_id );
77
+ $user = bb_get_user( $user_id );
78
+ $topic = get_topic ( $topic_id );
79
+ if ( !$tag || !$topic )
80
+ die('0');
81
+ if ( false !== bb_remove_topic_tag( $tag_id, $user_id, $topic_id ) )
82
+ die('1');
83
+ break;
84
+
85
+ case 'dim-favorite' :
86
+ $user_id = bb_get_current_user_info( 'id' );
87
+
88
+ if ( !$topic = get_topic( $id ) )
89
+ die('0');
90
+
91
+ if ( !bb_current_user_can( 'edit_favorites_of', $user_id ) )
92
+ die('-1');
93
+
94
+ bb_check_ajax_referer( "toggle-favorite_$topic->topic_id" );
95
+
96
+ $is_fav = is_user_favorite( $user_id, $topic->topic_id );
97
+
98
+ if ( 1 == $is_fav ) {
99
+ if ( bb_remove_user_favorite( $user_id, $topic->topic_id ) )
100
+ die('1');
101
+ } elseif ( false === $is_fav ) {
102
+ if ( bb_add_user_favorite( $user_id, $topic->topic_id ) )
103
+ die('1');
104
+ }
105
+ break;
106
+
107
+ case 'delete-post' : // $id is post_id
108
+ if ( !bb_current_user_can( 'delete_post', $id ) )
109
+ die('-1');
110
+
111
+ bb_check_ajax_referer( "delete-post_$id" );
112
+
113
+ $status = (int) $_POST['status'];
114
+
115
+ if ( !$bb_post = bb_get_post( $id ) )
116
+ die('0');
117
+
118
+ if ( $status == $bb_post->post_status )
119
+ die('1'); // We're already there
120
+
121
+ if ( bb_delete_post( $id, $status ) )
122
+ die('1');
123
+ break;
124
+ /*
125
+ case 'add-post' : // Can put last_modified stuff back in later
126
+ bb_check_ajax_referer( $action );
127
+ $error = false;
128
+ $post_id = 0;
129
+ $topic_id = (int) $_POST['topic_id'];
130
+ $last_mod = (int) $_POST['last_mod'];
131
+ if ( !$post_content = trim($_POST['post_content']) )
132
+ $error = new WP_Error( 'no-content', __('You need to actually submit some content!') );
133
+ if ( !bb_current_user_can( 'write_post', $topic_id ) )
134
+ die('-1');
135
+ if ( !$topic = get_topic( $topic_id ) )
136
+ die('0');
137
+ if ( !topic_is_open( $topic_id ) )
138
+ $error = new WP_Error( 'topic-closed', __('This topic is closed.') );
139
+ if ( $throttle_time = bb_get_option( 'throttle_time' ) )
140
+ if ( isset($bb_current_user->data->last_posted) && time() < $bb_current_user->data->last_posted + $throttle_time && !bb_current_user_can('throttle') )
141
+ $error = new WP_Error( 'throttle-limit', sprintf( __('Slow down! You can only post every %d seconds.'), $throttle_time );
142
+
143
+ if ( !$error ) :
144
+ if ( !$post_id = bb_new_post( $topic_id, rawurldecode($_POST['post_content']) ) )
145
+ die('0');
146
+
147
+ $bb_post = bb_get_post( $post_id );
148
+
149
+ $new_page = bb_get_page_number( $bb_post->post_position );
150
+
151
+ ob_start();
152
+ echo "<li id='post-$post_id'>";
153
+ bb_post_template();
154
+ echo '</li>';
155
+ $data = ob_get_contents();
156
+ ob_end_clean();
157
+ endif;
158
+ $x = new WP_Ajax_Response( array(
159
+ 'what' => 'post',
160
+ 'id' => $post_id,
161
+ 'data' => is_wp_error($error) ? $error : $data
162
+ ) );
163
+ $x->send();
164
+ break;
165
+ */
166
+ case 'add-forum' :
167
+ if ( !bb_current_user_can( 'manage_forums' ) )
168
+ die('-1');
169
+
170
+ bb_check_ajax_referer( $action );
171
+
172
+ if ( !$forum_id = bb_new_forum( $_POST ) )
173
+ die('0');
174
+
175
+ global $forums_count;
176
+ $forums_count = 2; // Hack
177
+
178
+ $data = bb_forum_row( $forum_id, false, true );
179
+
180
+ $forum = bb_get_forum( $forum_id );
181
+ if ( $forum->forum_parent ) {
182
+ $siblings = bb_get_forums( $forum->forum_parent );
183
+ $last_sibling = array_pop( $siblings );
184
+ if ( $last_sibling->forum_id == $forum_id )
185
+ $last_sibling = array_pop( $siblings );
186
+ if ( $last_sibling ) {
187
+ $position = "forum-$last_sibling->forum_id";
188
+ } else {
189
+ $position = "+forum-$forum->forum_parent";
190
+ $data = "<ul id='forum-root-$forum->forum_parent' class='list-block holder'>$data</ul>";
191
+ }
192
+ } else {
193
+ $position = 1;
194
+ }
195
+
196
+ $x = new WP_Ajax_Response( array(
197
+ 'what' => 'forum',
198
+ 'id' => $forum_id,
199
+ 'data' => $data,
200
+ 'position' => $position,
201
+ 'supplemental' => array( 'name' => $forum->forum_name )
202
+ ) );
203
+ $x->send();
204
+ break;
205
+
206
+ case 'order-forums' :
207
+ if ( !bb_current_user_can( 'manage_forums' ) )
208
+ die('-1');
209
+
210
+ bb_check_ajax_referer( $action );
211
+
212
+ if ( !is_array($_POST['order']) )
213
+ die('0');
214
+
215
+ global $bbdb;
216
+
217
+ $forums = array();
218
+
219
+ bb_get_forums(); // cache
220
+
221
+ foreach ( $_POST['order'] as $pos => $forum_id ) :
222
+ $forum = $bbdb->escape_deep( get_object_vars( bb_get_forum( $forum_id ) ) );
223
+ $forum['forum_order'] = $pos;
224
+ $forums[(int) $forum_id] = $forum;
225
+ endforeach;
226
+
227
+ foreach ( $_POST['root'] as $root => $ids )
228
+ foreach ( $ids as $forum_id )
229
+ $forums[(int) $forum_id]['forum_parent'] = (int) $root;
230
+
231
+ foreach ( $forums as $forum )
232
+ bb_update_forum( $forum );
233
+
234
+ die('1');
235
+ break;
236
+
237
+ default :
238
+ do_action( 'bb_ajax_' . $_POST['action'] );
239
+ break;
240
+ endswitch;
241
+
242
+ die('0');
243
+ ?>
bp-forums/bbpress/bb-admin/admin-base.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once('admin.php');
3
+
4
+ do_action( $bb_admin_page . '_pre_head' );
5
+
6
+ bb_get_admin_header();
7
+ ?>
8
+
9
+ <div class="wrap">
10
+
11
+ <?php if ( is_callable($bb_admin_page) ) : call_user_func( $bb_admin_page ); else : ?>
12
+
13
+ <p><?php _e('Nothing to see here.'); ?><p>
14
+
15
+ <?php endif; ?>
16
+
17
+ </div>
18
+
19
+ <?php bb_get_admin_footer(); ?>
bp-forums/bbpress/bb-admin/admin-footer.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ </div>
2
+ <div class="clear"></div>
3
+ <!-- If you like showing off the fact that your server rocks -->
4
+ <!-- <p id="bbShowOff">
5
+ <?php
6
+ global $bbdb;
7
+ printf(
8
+ __( 'This page generated in %s seconds, using %d queries.' ),
9
+ bb_number_format_i18n( bb_timer_stop(), 2 ),
10
+ bb_number_format_i18n( $bbdb->num_queries )
11
+ );
12
+ ?>
13
+ </p> -->
14
+ <div class="clear"></div>
15
+ </div>
16
+ </div>
17
+ <div id="bbFoot">
18
+ <p id="bbThanks">
19
+ <?php
20
+ printf(
21
+ __( 'Thank you for using <a href="%s">bbPress</a>. | <a href="%s">Documentation</a> | <a href="%s">Feedback</a>' ),
22
+ 'http://bbpress.org/',
23
+ 'http://bbpress.org/documentation/',
24
+ 'http://bbpress.org/forums/forum/requests-and-feedback'
25
+ );
26
+ ?>
27
+ </p>
28
+ <p id="bbVersion"><?php printf( __( 'Version %s' ), bb_get_option( 'version' ) ); ?></p>
29
+ </div>
30
+
31
+ <?php do_action( 'bb_admin_footer' ); ?>
32
+ </body>
33
+ </html>
bp-forums/bbpress/bb-admin/admin-header.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml"<?php bb_language_attributes( '1.1' ); ?>>
3
+ <head>
4
+ <meta http-equiv="X-UA-Compatible" content="IE=8" />
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
+ <title><?php bb_admin_title() ?></title>
7
+ <link rel="stylesheet" href="<?php bb_uri('bb-admin/style.css', null, BB_URI_CONTEXT_LINK_STYLESHEET_HREF + BB_URI_CONTEXT_BB_ADMIN); ?>" type="text/css" />
8
+ <?php if ( 'rtl' == bb_get_option( 'text_direction' ) ) : ?>
9
+ <link rel="stylesheet" href="<?php bb_uri('bb-admin/style-rtl.css', null, BB_URI_CONTEXT_LINK_STYLESHEET_HREF + BB_URI_CONTEXT_BB_ADMIN); ?>" type="text/css" />
10
+ <?php endif; do_action('bb_admin_print_scripts'); ?>
11
+ <script type="text/javascript">
12
+ //<![CDATA[
13
+ addLoadEvent = function(func){if(typeof jQuery!="undefined")jQuery(document).ready(func);else if(typeof wpOnload!='function'){wpOnload=func;}else{var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}};
14
+ var userSettings = {'url':'<?php echo $bb->cookie_path; ?>','uid':'<?php if ( ! isset($bb_current_user) ) $bb_current_user = bb_get_current_user(); echo $bb_current_user->ID; ?>','time':'<?php echo time(); ?>'};
15
+ //]]>
16
+ </script>
17
+ <?php do_action( 'bb_admin_head' ); ?>
18
+ </head>
19
+
20
+ <?php
21
+ global $bb_admin_body_class;
22
+ if ( 'f' == bb_get_user_setting( 'fm' ) ) {
23
+ $bb_admin_body_class .= ' bb-menu-folded';
24
+ }
25
+ ?>
26
+
27
+ <body class="bb-admin no-js <?php echo trim( $bb_admin_body_class ); ?>">
28
+ <script type="text/javascript">
29
+ //<![CDATA[
30
+ (function(){
31
+ var c = document.body.className;
32
+ c = c.replace(/no-js/, 'js');
33
+ document.body.className = c;
34
+ })();
35
+ //]]>
36
+ </script>
37
+ <div id="bbWrap">
38
+ <div id="bbContent">
39
+ <div id="bbHead">
40
+ <h1><a href="<?php bb_uri(); ?>"><span><?php bb_option('name'); ?></span> <em><?php _e('Visit Site'); ?></em></a></h1>
41
+ <div id="bbUserInfo">
42
+ <p>
43
+ <?php printf( __('Howdy, %1$s'), bb_get_profile_link( array( 'text' => bb_get_current_user_info( 'name' ) ) ) );?>
44
+ | <?php bb_logout_link( array( 'redirect' => bb_get_uri( null, null, BB_URI_CONTEXT_HEADER ) ) ); ?>
45
+ </p>
46
+ </div>
47
+ </div>
48
+
49
+ <div id="bbBody">
50
+
51
+ <?php bb_admin_menu(); ?>
bp-forums/bbpress/bb-admin/admin.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ define( 'BB_IS_ADMIN', true );
3
+
4
+ require_once('../bb-load.php');
5
+
6
+ bb_ssl_redirect();
7
+
8
+ bb_auth();
9
+
10
+ if ( bb_get_option( 'bb_db_version' ) > bb_get_option_from_db( 'bb_db_version' ) ) {
11
+ bb_safe_redirect( 'upgrade.php' );
12
+ die();
13
+ }
14
+
15
+ require_once( BB_PATH . 'bb-admin/includes/functions.bb-admin.php' );
16
+
17
+ $bb_admin_page = bb_find_filename( $_SERVER['PHP_SELF'] );
18
+
19
+ if ( $bb_admin_page == 'admin-base.php' ) {
20
+ $bb_admin_page = $_GET['plugin'];
21
+ }
22
+
23
+ wp_enqueue_script( 'common' );
24
+
25
+ bb_user_settings();
26
+ if ( isset( $_GET['foldmenu'] ) ) {
27
+ if ( $_GET['foldmenu'] ) {
28
+ bb_update_user_setting( 'fm', 'f' );
29
+ } else {
30
+ bb_delete_user_setting( 'fm' );
31
+ }
32
+ bb_safe_redirect( remove_query_arg( 'foldmenu', stripslashes( $_SERVER['REQUEST_URI'] ) ) );
33
+ die;
34
+ }
35
+ bb_admin_menu_generator();
36
+ bb_get_current_admin_menu();
37
+ ?>
bp-forums/bbpress/bb-admin/bb-forum.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once('admin.php');
3
+
4
+ if ( !bb_current_user_can('manage_forums') )
5
+ bb_die(__("You don't have the authority to mess with the forums."));
6
+
7
+ if ( !isset($_POST['action']) ) {
8
+ wp_redirect( bb_get_uri('bb-admin/forums.php', null, BB_URI_CONTEXT_HEADER + BB_URI_CONTEXT_BB_ADMIN) );
9
+ exit;
10
+ }
11
+
12
+ $sent_from = wp_get_referer();
13
+
14
+ switch ( $_POST['action'] ) :
15
+ case 'add' :
16
+ if ( !isset($_POST['forum_name']) || '' === $_POST['forum_name'] )
17
+ bb_die(__('Bad forum name. Go back and try again.'));
18
+
19
+ bb_check_admin_referer( 'add-forum' );
20
+
21
+ if ( false !== bb_new_forum( $_POST ) ) :
22
+ bb_safe_redirect( $sent_from );
23
+ exit;
24
+ else :
25
+ bb_die(__('The forum was not added'));
26
+ endif;
27
+ break;
28
+ case 'update' :
29
+ bb_check_admin_referer( 'update-forum' );
30
+
31
+ if ( !$forums = bb_get_forums() )
32
+ bb_die(__('No forums to update!'));
33
+ if ( (int) $_POST['forum_id'] && isset($_POST['forum_name']) && '' !== $_POST['forum_name'] )
34
+ bb_update_forum( $_POST );
35
+ foreach ( array('action', 'id') as $arg )
36
+ $sent_from = remove_query_arg( $arg, $sent_from );
37
+ bb_safe_redirect( add_query_arg( 'message', 'updated', $sent_from ) );
38
+ exit;
39
+ break;
40
+ case 'delete' :
41
+ bb_check_admin_referer( 'delete-forums' );
42
+
43
+ $forum_id = (int) $_POST['forum_id'];
44
+ $move_topics_forum = (int) $_POST['move_topics_forum'];
45
+
46
+ if ( !bb_current_user_can( 'delete_forum', $forum_id ) )
47
+ bb_die(__("You don't have the authority to kill off the forums."));
48
+
49
+ if ( isset($_POST['move_topics']) && $_POST['move_topics'] != 'delete' )
50
+ bb_move_forum_topics( $forum_id, $move_topics_forum );
51
+
52
+ if ( !bb_delete_forum( $forum_id ) )
53
+ bb_die( __('Error occured while trying to delete forum') );
54
+
55
+ foreach ( array('action', 'id') as $arg )
56
+ $sent_from = remove_query_arg( $arg, $sent_from );
57
+ bb_safe_redirect( add_query_arg( 'message', 'deleted', $sent_from ) );
58
+ exit;
59
+ break;
60
+ endswitch;
61
+ ?>
bp-forums/bbpress/bb-admin/delete-post.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require('admin-action.php');
3
+
4
+ $post_id = (int) $_GET['id'];
5
+
6
+ if ( !bb_current_user_can( 'delete_post', $post_id ) ) {
7
+ wp_redirect( bb_get_uri(null, null, BB_URI_CONTEXT_HEADER) );
8
+ exit;
9
+ }
10
+
11
+ bb_check_admin_referer( 'delete-post_' . $post_id );
12
+
13
+ $status = (int) $_GET['status'];
14
+ $bb_post = bb_get_post ( $post_id );
15
+ $old_status = (int) $bb_post->post_status;
16
+
17
+ if ( !$bb_post )
18
+ bb_die(__('There is a problem with that post, pardner.'));
19
+
20
+ if ( 0 == $status && 0 != $bb_post->post_status ) // We're undeleting
21
+ add_filter('bb_delete_post', 'bb_topics_replied_on_undelete_post');
22
+
23
+ bb_delete_post( $post_id, $status );
24
+
25
+ $message = '';
26
+ switch ( $old_status ) {
27
+ case 0:
28
+ switch ( $status ) {
29
+ case 0:
30
+ break;
31
+ case 1:
32
+ $message = 'deleted';
33
+ break;
34
+ default:
35
+ $message = 'spammed';
36
+ break;
37
+ }
38
+ break;
39
+ case 1:
40
+ switch ( $status ) {
41
+ case 0:
42
+ $message = 'undeleted';
43
+ break;
44
+ case 1:
45
+ break;
46
+ default:
47
+ $message = 'spammed';
48
+ break;
49
+ }
50
+ break;
51
+ default:
52
+ switch ( $status ) {
53
+ case 0:
54
+ $message = 'unspammed-normal';
55
+ break;
56
+ case 1:
57
+ $message = 'unspammed-deleted';
58
+ break;
59
+ default:
60
+ break;
61
+ }
62
+ break;
63
+ }
64
+
65
+ $topic = get_topic( $bb_post->topic_id );
66
+
67
+ if ( $sendto = wp_get_referer() ) {
68
+ $sendto = remove_query_arg( 'message', $sendto );
69
+ $sendto = add_query_arg( 'message', $message, $sendto );
70
+ } elseif ( $topic->topic_posts == 0 ) {
71
+ $sendto = get_forum_link( $topic->forum_id );
72
+ } else {
73
+ $the_page = bb_get_page_number( $bb_post->post_position );
74
+ $sendto = get_topic_link( $bb_post->topic_id, $the_page );
75
+ }
76
+
77
+ bb_safe_redirect( $sendto );
78
+ exit;
bp-forums/bbpress/bb-admin/delete-topic.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require('admin-action.php');
3
+
4
+ $topic_id = (int) $_GET['id'];
5
+
6
+ if ( !bb_current_user_can( 'delete_topic', $topic_id ) ) {
7
+ wp_redirect( bb_get_uri(null, null, BB_URI_CONTEXT_HEADER) );
8
+ exit;
9
+ }
10
+
11
+ bb_check_admin_referer( 'delete-topic_' . $topic_id );
12
+
13
+ $topic = get_topic( $topic_id );
14
+ $old_status = (int) $topic->topic_status;
15
+
16
+ if ( !$topic )
17
+ bb_die(__('There is a problem with that topic, pardner.'));
18
+
19
+ $status = $topic->topic_status ? 0 : 1;
20
+ bb_delete_topic( $topic->topic_id, $status );
21
+
22
+ $message = '';
23
+ switch ( $old_status ) {
24
+ case 0:
25
+ switch ( $status ) {
26
+ case 0:
27
+ break;
28
+ case 1:
29
+ $message = 'deleted';
30
+ break;
31
+ }
32
+ break;
33
+ case 1:
34
+ switch ( $status ) {
35
+ case 0:
36
+ $message = 'undeleted';
37
+ break;
38
+ case 1:
39
+ break;
40
+ }
41
+ break;
42
+ }
43
+
44
+ if ( $sendto = wp_get_referer() ) {
45
+ $sendto = remove_query_arg( 'message', $sendto );
46
+ $sendto = add_query_arg( 'message', $message, $sendto );
47
+ } elseif ( 0 == $topic->topic_status )
48
+ $sendto = get_forum_link( $topic->forum_id );
49
+ else
50
+ $sendto = get_topic_link( $topic_id );
51
+
52
+ wp_redirect( $sendto );
53
+ exit;
bp-forums/bbpress/bb-admin/export.php ADDED
@@ -0,0 +1,306 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once( '../bb-load.php' );
4
+ require_once( BB_PATH . 'bb-admin/includes/functions.bb-admin.php' );
5
+
6
+ define('BB_EXPORT_USERS', 1);
7
+ define('BB_EXPORT_FORUMS', 2);
8
+ define('BB_EXPORT_TOPICS', 4);
9
+
10
+ // Some example usage of the bitwise export levels (can be defined in bb-config.php)
11
+ //define('BB_EXPORT_LEVEL', BB_EXPORT_USERS);
12
+ //define('BB_EXPORT_LEVEL', BB_EXPORT_USERS + BB_EXPORT_FORUMS);
13
+ //define('BB_EXPORT_LEVEL', BB_EXPORT_USERS + BB_EXPORT_FORUMS + BB_EXPORT_TOPICS);
14
+
15
+ if ( !defined('BB_EXPORT_LEVEL') )
16
+ define('BB_EXPORT_LEVEL', 0);
17
+
18
+ if ( !BB_EXPORT_LEVEL || !bb_current_user_can( 'import_export' ) )
19
+ bb_die( __('Either export is disabled or you are not allowed to export.') );
20
+
21
+ // See bb_export_user for syntax
22
+ function _bb_export_object( $object, $properties = null, $tabs = 1 ) {
23
+ $r = '';
24
+
25
+ if ( !$type = $object['type'] )
26
+ return;
27
+ unset($object['type']);
28
+
29
+ $atts = '';
30
+ $id = 0;
31
+ foreach ( $object as $att => $v ) {
32
+ if ( 'id' == $att ) {
33
+ $id = $v;
34
+ $v = $type . '_' . $v;
35
+ }
36
+ $atts .= " $att='$v'";
37
+ }
38
+ unset($att, $v);
39
+
40
+ $r .= str_repeat("\t", $tabs) . "<$type{$atts}>\n";
41
+
42
+ foreach ( (array) $properties as $k => $v ) {
43
+ if ( 'meta' == $k ) {
44
+ $data = '';
45
+ foreach ( $v as $mk => $mv )
46
+ $data .= str_repeat("\t", $tabs + 1) . "<meta key='$mk'><![CDATA[$mv]]></meta>\n";
47
+ } else {
48
+ if ( '!' == $k{0} ) {
49
+ $k = substr($k, 1);
50
+ $v = "<![CDATA[$v]]>";
51
+ }
52
+ $data = str_repeat("\t", $tabs + 1) . "<$k>$v</$k>\n";
53
+ }
54
+ $r .= $data;
55
+ }
56
+
57
+ $r .= apply_filters( 'in_bb_export_object_' . $type, '', $id );
58
+
59
+ $r .= str_repeat("\t", $tabs) . "</$type>\n\n";
60
+
61
+ return $r;
62
+ }
63
+
64
+ // See bb_export_user for syntax
65
+ function _bb_translate_for_export( $translate, &$data ) {
66
+ $r = array();
67
+ foreach ( $translate as $prop => $export ) {
68
+ if ( '?' == $export{0} ) {
69
+ $export = substr($export, 1);
70
+ if ( !$data[$prop] ) {
71
+ unset($data[$prop]);
72
+ continue;
73
+ }
74
+ }
75
+ if ( false === $export ) {
76
+ unset($data[$prop]);
77
+ continue;
78
+ }
79
+ $r[$export] = $data[$prop];
80
+ unset($data[$prop]);
81
+ }
82
+ unset($export, $prop);
83
+ return $r;
84
+ }
85
+
86
+ function bb_export_user( $user_id ) {
87
+ global $bbdb;
88
+ if ( !$_user = bb_get_user( $user_id ) )
89
+ return;
90
+
91
+ $_user = get_object_vars($_user);
92
+
93
+ $atts = array(
94
+ 'type' => 'user',
95
+ 'id' => $_user['ID']
96
+ );
97
+
98
+ // ?url means url is optional. Only include it in the export if it exists
99
+ // !title means the title should be wrapped in CDATA
100
+ // ?! is the correct order, not !?
101
+ $translate = array(
102
+ 'user_login' => 'login',
103
+ 'user_pass' => 'pass',
104
+ 'user_email' => 'email',
105
+ 'user_url' => '?url',
106
+ 'user_registered' => 'incept',
107
+ 'display_name' => '?!title',
108
+ 'user_nicename' => '?nicename',
109
+ 'user_status' => '?status',
110
+ 'ID' => false
111
+ );
112
+
113
+ $user = _bb_translate_for_export( $translate, $_user );
114
+
115
+ $meta = array();
116
+ foreach ( $_user as $k => $v ) {
117
+ if ( 0 !== strpos($k, $bbdb->prefix) && isset($_user[$bbdb->prefix . $k]) )
118
+ continue;
119
+ $meta[$k] = maybe_serialize($v);
120
+ }
121
+ unset($_user, $k, $v);
122
+
123
+ $user['meta'] = $meta;
124
+
125
+ return _bb_export_object( $atts, $user );
126
+ }
127
+
128
+ function bb_export_forum( $forum_id ) {
129
+ if ( !$_forum = bb_get_forum( $forum_id ) )
130
+ return;
131
+
132
+ $_forum = get_object_vars( $_forum );
133
+
134
+ $translate = array(
135
+ 'forum_name' => '!title',
136
+ 'forum_desc' => '?!content',
137
+ 'forum_parent' => '?parent'
138
+ );
139
+
140
+ $forum = _bb_translate_for_export( $translate, $_forum );
141
+
142
+ return _bb_export_object( array('type' => 'forum', 'id' => $_forum['forum_id']), $forum );
143
+ }
144
+
145
+ function bb_export_topic( $topic_id ) {
146
+ if ( !$_topic = get_topic( $topic_id ) )
147
+ return;
148
+
149
+ $_topic = get_object_vars( $_topic );
150
+
151
+ $atts = array(
152
+ 'type' => 'topic',
153
+ 'id' => $_topic['topic_id'],
154
+ 'author' => 'user_' . $_topic['topic_poster'],
155
+ 'in' => 'forum_' . $_topic['forum_id']
156
+ );
157
+
158
+ $translate = array(
159
+ 'topic_title' => '!title',
160
+ 'topic_start_time' => 'incept',
161
+ 'topic_status' => '?status',
162
+ 'topic_id' => false,
163
+ 'topic_poster' => false,
164
+ 'topic_poster_name' => false,
165
+ 'topic_last_poster' => false,
166
+ 'topic_last_poster_name' => false,
167
+ 'topic_time' => false,
168
+ 'forum_id' => false,
169
+ 'topic_last_post_id' => false,
170
+ 'topic_posts' => false,
171
+ 'tag_count' => false
172
+ );
173
+
174
+ $topic = _bb_translate_for_export( $translate, $_topic );
175
+
176
+ $meta = array();
177
+ foreach ( $_topic as $k => $v )
178
+ $meta[$k] = maybe_serialize($v);
179
+ unset($_topic, $k, $v);
180
+
181
+ $topic['meta'] = $meta;
182
+
183
+ return _bb_export_object( $atts, $topic );
184
+ }
185
+
186
+ function bb_export_post( $post_id ) {
187
+ if ( !$_post = bb_get_post( $post_id ) )
188
+ return;
189
+
190
+ $_post = get_object_vars($_post);
191
+
192
+ $atts = array(
193
+ 'type' => 'post',
194
+ 'id' => $_post['post_id'],
195
+ 'author' => 'user_' . $_post['poster_id']
196
+ );
197
+
198
+ $translate = array(
199
+ 'post_time' => 'incept',
200
+ 'post_text' => '!content',
201
+ 'post_status' => '?status',
202
+ 'post_id' => false,
203
+ 'poster_id' => false,
204
+ 'forum_id' => false,
205
+ 'topic_id' => false,
206
+ 'post_position' => false
207
+ );
208
+
209
+ $post = _bb_translate_for_export( $translate, $_post );
210
+
211
+ $post['meta'] = $_post;
212
+
213
+ return _bb_export_object( $atts, $post, 2 );
214
+ }
215
+
216
+ // One of these things is not like the others...
217
+ function bb_export_tag( $tag ) {
218
+ // id here is not numeric. does not currently preserve tagged_on
219
+ return "\t\t<tag author='user_$tag->user_id' id='tag_$tag->tag'><![CDATA[$tag->raw_tag]]></tag>\n";
220
+ }
221
+
222
+ function bb_export_topic_tags( $r, $topic_id ) {
223
+ global $topic_tag_cache;
224
+ if ( !get_topic( $topic_id ) )
225
+ return;
226
+
227
+ if ( !$tags = bb_get_topic_tags( $topic_id ) )
228
+ return $r;
229
+
230
+ $r .= "\n";
231
+
232
+ foreach ( (array) $tags as $tag )
233
+ $r .= bb_export_tag( $tag );
234
+ $topic_tag_cache = array();
235
+
236
+ return $r;
237
+ }
238
+
239
+ function bb_export_topic_posts( $r, $topic_id ) {
240
+ if ( !get_topic( $topic_id ) )
241
+ return;
242
+
243
+ $r .= "\n";
244
+
245
+ $page = 1;
246
+ while ( $posts = get_thread( $topic_id, $page++ ) ) {
247
+ foreach ( $posts as $post )
248
+ $r .= bb_export_post( $post->post_id );
249
+ }
250
+
251
+ return $r;
252
+ }
253
+
254
+ function bb_export() {
255
+ global $bb;
256
+
257
+ define( 'BB_EXPORTING', true );
258
+ do_action( 'bb_pre_export' );
259
+
260
+ $bb->use_cache = false; // Turn off hard cache
261
+ $bb->page_topics = 100;
262
+
263
+ echo "<forums-data version='0.75'>\n";
264
+
265
+ if (BB_EXPORT_LEVEL & BB_EXPORT_USERS) {
266
+ $page = 1;
267
+ while ( ( $users = bb_user_search( array('page' => $page++) ) ) && !is_wp_error( $users ) ) {
268
+ foreach ( $users as $user )
269
+ echo bb_export_user( $user->ID );
270
+ }
271
+ unset($users, $user, $page);
272
+ }
273
+
274
+ if (BB_EXPORT_LEVEL & BB_EXPORT_FORUMS) {
275
+ $forums = bb_get_forums();
276
+ foreach ( $forums as $forum )
277
+ echo bb_export_forum( $forum->forum_id );
278
+ unset($forums, $forum);
279
+ }
280
+
281
+ if (BB_EXPORT_LEVEL & BB_EXPORT_TOPICS) {
282
+ $page = 1;
283
+ while ( $topics = get_latest_topics( 0, $page++ ) ) {
284
+ foreach ( $topics as $topic )
285
+ echo bb_export_topic( $topic->topic_id );
286
+ }
287
+ unset($topics, $topic, $page);
288
+ }
289
+
290
+ do_action( 'bb_export' );
291
+
292
+ echo '</forums-data>';
293
+ }
294
+
295
+ add_filter( 'in_bb_export_object_topic', 'bb_export_topic_tags', 10, 2 );
296
+ add_filter( 'in_bb_export_object_topic', 'bb_export_topic_posts', 10, 2 );
297
+ add_filter( 'get_forum_where', 'bb_no_where', 9999 );
298
+ add_filter( 'get_forums_where', 'bb_no_where', 9999 );
299
+ add_filter( 'get_latest_topics_where', 'bb_no_where', 9999 );
300
+ add_filter( 'get_thread_where', 'bb_no_where', 9999 );
301
+ add_filter( 'get_user_where', 'bb_no_where', 9999 );
302
+ add_filter( 'cache_users_where', 'bb_no_where', 9999 );
303
+
304
+ bb_export();
305
+
306
+ ?>
bp-forums/bbpress/bb-admin/forums.php ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once('admin.php');
3
+
4
+ $forums = bb_get_forums();
5
+ $forums_count = $forums ? count($forums) : 0;
6
+
7
+ if ( isset($_GET['action']) && 'delete' == $_GET['action'] ) {
8
+ $forum_to_delete = (int) $_GET['id'];
9
+ $deleted_forum = bb_get_forum( $forum_to_delete );
10
+ if ( !$deleted_forum || $forums_count < 2 || !bb_current_user_can( 'delete_forum', $forum_to_delete ) ) {
11
+ bb_safe_redirect( add_query_arg( array('action' => false, 'id' => false) ) );
12
+ exit;
13
+ }
14
+ }
15
+
16
+ if ( isset($_GET['message']) ) {
17
+ switch ( $_GET['message'] ) :
18
+ case 'updated' :
19
+ bb_admin_notice( __( '<strong>Forum Updated.</strong>' ) );
20
+ break;
21
+ case 'deleted' :
22
+ bb_admin_notice( sprintf(
23
+ __( '<strong>Forum deleted.</strong> You should <a href="%s">recount your site information</a>.' ),
24
+ bb_get_uri('bb-admin/tools-recount.php', null, BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN)
25
+ ) );
26
+ break;
27
+ endswitch;
28
+ }
29
+
30
+ if ( !isset($_GET['action']) )
31
+ wp_enqueue_script( 'admin-forums' );
32
+ elseif ( 'delete' == @$_GET['action'] )
33
+ bb_admin_notice( sprintf( __( 'Are you sure you want to delete the "<strong>%s</strong>" forum?' ), $deleted_forum->forum_name ) );
34
+
35
+ $bb_admin_body_class = ' bb-admin-forums';
36
+
37
+ bb_get_admin_header();
38
+ ?>
39
+
40
+ <div class="wrap">
41
+
42
+ <h2><?php _e('Forums'); ?></h2>
43
+ <?php do_action( 'bb_admin_notices' ); ?>
44
+ <?php switch ( @$_GET['action'] ) : ?>
45
+ <?php case 'edit' : ?>
46
+ <?php bb_forum_form( (int) $_GET['id'] ); ?>
47
+ <?php break; case 'delete' : ?>
48
+
49
+ <form class="settings" method="post" id="delete-forums" action="<?php bb_uri('bb-admin/bb-forum.php', null, BB_URI_CONTEXT_FORM_ACTION + BB_URI_CONTEXT_BB_ADMIN); ?>">
50
+ <fieldset>
51
+ <legend><?php _e('Delete Forum'); ?></legend>
52
+ <p><?php _e('This forum contains:'); ?></p>
53
+ <ul>
54
+ <li><?php printf(__ngettext('%d topic', '%d topics', $deleted_forum->topics), $deleted_forum->topics); ?></li>
55
+ <li><?php printf(__ngettext('%d post', '%d posts', $deleted_forum->posts), $deleted_forum->posts); ?></li>
56
+ </ul>
57
+ <div id="option-forum-delete-contents">
58
+ <div class="label"><?php _e( 'Action' ); ?></div>
59
+ <div class="inputs">
60
+ <label class="radios">
61
+ <input type="radio" name="move_topics" id="move-topics-delete" value="delete" /> <?php _e('Delete all topics and posts in this forum. <em>This can never be undone.</em>'); ?>
62
+ </label>
63
+ <label class="radios">
64
+ <input type="radio" name="move_topics" id="move-topics-move" value="move" checked="checked" /> <?php _e('Move topics from this forum into the replacement forum below.'); ?>
65
+ </label>
66
+ </div>
67
+ </div>
68
+ <div id="option-forum-delete-contents">
69
+ <label for="move-topics-forum"><?php _e( 'Replacement forum' ); ?></label>
70
+ <div class="inputs">
71
+ <?php bb_forum_dropdown( array('id' => 'move_topics_forum', 'callback' => 'strcmp', 'callback_args' => array($deleted_forum->forum_id), 'selected' => $deleted_forum->forum_parent) ); ?>
72
+ </div>
73
+ </div>
74
+ </fieldset>
75
+ <fieldset class="submit">
76
+ <?php bb_nonce_field( 'delete-forums' ); ?>
77
+ <input type="hidden" name="action" value="delete" />
78
+ <input type="hidden" name="forum_id" value="<?php echo $deleted_forum->forum_id; ?>" />
79
+ <a href="<?php bb_uri('bb-admin/forums.php', null, BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN); ?>" class="cancel"><?php _e('Cancel') ?></a>
80
+ <input class="submit delete" type="submit" name="submit" value="<?php _e('Delete Forum') ?>" />
81
+ </fieldset>
82
+ </form>
83
+
84
+ <?php break; default : ?>
85
+
86
+
87
+ <?php if ( bb_forums( 'type=list&walker=BB_Walker_ForumAdminlistitems' ) ) : ?>
88
+ <ul id="forum-list" class="list:forum list-block holder">
89
+ <li class="thead list-block"><?php _e('Forum'); ?></li>
90
+ <?php while ( bb_forum() ) : ?>
91
+ <?php bb_forum_row(); ?>
92
+ <?php endwhile; ?>
93
+ </ul>
94
+ <?php endif; // bb_forums() ?>
95
+
96
+ <hr class="settings" />
97
+
98
+ <?php bb_forum_form(); ?>
99
+
100
+ <?php break; endswitch; // action ?>
101
+
102
+ <div id="ajax-response"></div>
103
+
104
+ </div>
105
+
106
+ <?php bb_get_admin_footer(); ?>
bp-forums/bbpress/bb-admin/images/admin-header-logo.gif ADDED
Binary file
bp-forums/bbpress/bb-admin/images/bbpress-logo.png ADDED
Binary file
bp-forums/bbpress/bb-admin/images/blank.gif ADDED
Binary file
bp-forums/bbpress/bb-admin/images/button-grad.png ADDED
Binary file
bp-forums/bbpress/bb-admin/images/drag.gif ADDED
Binary file
bp-forums/bbpress/bb-admin/images/gray-grad.png ADDED
Binary file
bp-forums/bbpress/bb-admin/images/icons32.png ADDED
Binary file
bp-forums/bbpress/bb-admin/images/input-lock.png ADDED
Binary file
bp-forums/bbpress/bb-admin/images/menu-arrows.gif ADDED
Binary file
bp-forums/bbpress/bb-admin/images/menu-bits-rtl.gif ADDED
Binary file
bp-forums/bbpress/bb-admin/images/menu-bits.gif ADDED
Binary file
bp-forums/bbpress/bb-admin/images/menu-dark-rtl.gif ADDED
Binary file
bp-forums/bbpress/bb-admin/images/menu-dark.gif ADDED
Binary file
bp-forums/bbpress/bb-admin/images/menu.png ADDED
Binary file
bp-forums/bbpress/bb-admin/images/visit-site-button-grad.gif ADDED
Binary file
bp-forums/bbpress/bb-admin/images/white-grad-active.png ADDED
Binary file
bp-forums/bbpress/bb-admin/images/white-grad.png ADDED
Binary file
bp-forums/bbpress/bb-admin/includes/class.bb-install.php ADDED
@@ -0,0 +1,2763 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * bbPress Installation class
4
+ *
5
+ * @since 0.9
6
+ */
7
+ class BB_Install
8
+ {
9
+ /**
10
+ * The file where the class was instantiated
11
+ *
12
+ * @var string
13
+ */
14
+ var $caller;
15
+
16
+ /**
17
+ * Whether or not we need to load some of the includes normally loaded by bb-settings.php
18
+ *
19
+ * @var boolean
20
+ */
21
+ var $load_includes = false;
22
+
23
+ /**
24
+ * An array of available languages to use in the installer
25
+ *
26
+ * @var array
27
+ */
28
+ var $languages = array( 'en_US' => 'en_US' );
29
+
30
+ /**
31
+ * The currently selected language for the installer
32
+ *
33
+ * @var string
34
+ */
35
+ var $language = 'en_US';
36
+
37
+ /**
38
+ * The current step in the install process
39
+ *
40
+ * @var integer
41
+ */
42
+ var $step;
43
+
44
+ /**
45
+ * Info about config files and their locations
46
+ *
47
+ * @var array
48
+ */
49
+ var $configs = array(
50
+ 'writable' => false,
51
+ 'bb-config.php' => false,
52
+ 'config.php' => false
53
+ );
54
+
55
+ /**
56
+ * An array of the current status of each step
57
+ *
58
+ * @var array
59
+ */
60
+ var $step_status = array(
61
+ 0 => 'incomplete',
62
+ 1 => 'incomplete',
63
+ 2 => 'incomplete',
64
+ 3 => 'incomplete',
65
+ 4 => 'incomplete'
66
+ );
67
+
68
+ /**
69
+ * An array of most strings in use, including errors
70
+ *
71
+ * @var array
72
+ */
73
+ var $strings = array();
74
+
75
+ /**
76
+ * The data being manipulated as we go through the forms
77
+ *
78
+ * @var array
79
+ */
80
+ var $data = array();
81
+
82
+ /**
83
+ * A boolean that can get flagged to stop posting of a form getting processed
84
+ *
85
+ * @var boolean
86
+ */
87
+ var $stop_process = false;
88
+
89
+ /**
90
+ * Keeps track of where the tabindex is up to
91
+ *
92
+ * @var integer
93
+ */
94
+ var $tabindex = 0;
95
+
96
+ /**
97
+ * Constructor
98
+ *
99
+ * Loads everything we might need to do the business
100
+ *
101
+ * @param string $caller The full path of the file that instantiated the class
102
+ * @return boolean Always returns true
103
+ */
104
+ function BB_Install( $caller )
105
+ {
106
+ $this->caller = $caller;
107
+
108
+ $this->set_initial_step();
109
+ $this->define_paths();
110
+
111
+ // We need to load these when bb-settings.php isn't loaded
112
+ if ( $this->load_includes ) {
113
+ require_once( BACKPRESS_PATH . 'functions.core.php' );
114
+ require_once( BACKPRESS_PATH . 'functions.compat.php' );
115
+ require_once( BACKPRESS_PATH . 'functions.formatting.php' );
116
+ require_once( BACKPRESS_PATH . 'functions.plugin-api.php' );
117
+ require_once( BACKPRESS_PATH . 'class.wp-error.php' );
118
+ require_once( BB_PATH . BB_INC . 'functions.bb-core.php' );
119
+ require_once( BB_PATH . BB_INC . 'functions.bb-meta.php' );
120
+ require_once( BB_PATH . BB_INC . 'class.bp-options.php' );
121
+ require_once( BACKPRESS_PATH . 'functions.bp-options.php' );
122
+ require_once( BACKPRESS_PATH . 'functions.kses.php' );
123
+ require_once( BB_PATH . BB_INC . 'functions.bb-l10n.php' );
124
+ require_once( BB_PATH . BB_INC . 'functions.bb-template.php' );
125
+ }
126
+
127
+ $this->get_languages();
128
+ $this->set_language();
129
+
130
+ if ( $this->language ) {
131
+ global $locale;
132
+ global $l10n;
133
+ $locale = $this->language;
134
+ unset( $l10n['default'] );
135
+
136
+ if ( !class_exists( 'MO' ) ) {
137
+ require_once( BACKPRESS_PATH . 'pomo/mo.php' );
138
+ }
139
+ }
140
+
141
+ // Load the default text localization domain. Doing this twice doesn't hurt too much.
142
+ bb_load_default_textdomain();
143
+
144
+ // Pull in locale data after loading text domain.
145
+ if ( $this->load_includes ) {
146
+ require_once( BB_PATH . BB_INC . 'class.bb-locale.php' );
147
+ }
148
+ global $bb_locale;
149
+ $bb_locale = new BB_Locale();
150
+
151
+ $this->prepare_strings();
152
+ $this->check_prerequisites();
153
+ $this->check_configs();
154
+
155
+ if ( $this->step > -1 ) {
156
+ $this->set_step();
157
+ $this->prepare_data();
158
+ $this->process_form();
159
+ }
160
+
161
+ return true;
162
+ }
163
+
164
+ /**
165
+ * Set initial step
166
+ *
167
+ * Sets the step from the post data and keeps it within range
168
+ *
169
+ * @return integer The calculated step
170
+ */
171
+ function set_initial_step()
172
+ {
173
+ // Set the step based on the $_POST value or 0
174
+ $this->step = $_POST['step'] ? (integer) $_POST['step'] : 0;
175
+
176
+ // Make sure the requested step is from 0-4
177
+ if ( 0 > $this->step || 4 < $this->step ) {
178
+ $this->step = 0;
179
+ }
180
+ return $this->step;
181
+ }
182
+
183
+ /**
184
+ * Prepare text strings
185
+ *
186
+ * Sets up many of the strings to be used by the class that may
187
+ * be later subject to change due to processing of the forms
188
+ */
189
+ function prepare_strings()
190
+ {
191
+ $this->strings = array(
192
+ -1 => array(
193
+ 'title' => __( 'bbPress &rsaquo; Error' ),
194
+ 'h1' => __( 'Oh dear!' ),
195
+ 'messages' => array()
196
+ ),
197
+ 0 => array(
198
+ 'title' => sprintf( __( '%1$s &rsaquo; %2$s' ), __( 'bbPress installer' ), __( 'Welcome' ) ),
199
+ 'h2' => __( 'Welcome to the bbPress installer' ),
200
+ 'status' => '',
201
+ 'messages' => array(),
202
+ 'intro' => array(
203
+ __( 'We\'re now going to go through a few steps to get you up and running.' ),
204
+ __( 'Ready? Then let\'s get started!' )
205
+ )
206
+ ),
207
+ 1 => array(
208
+ 'title' => sprintf( __( '%1$s &rsaquo; %2$s' ), __( 'bbPress installer' ), __( 'Step 1' ) ),
209
+ 'h2' => sprintf( __( '%1$s - %2$s' ), __( 'Step 1' ), __( 'Database configuration' ) ),
210
+ 'status' => '',
211
+ 'intro' => array(
212
+ __( 'In this step you need to enter your database connection details. The installer will attempt to create a file called <code>bb-config.php</code> in the root directory of your bbPress installation.' ),
213
+ __( 'If you\'re not sure what to put here, contact your web hosting provider.' )
214
+ ),
215
+ 'messages' => array()
216
+ ),
217
+ 2 => array(
218
+ 'title' => sprintf( __( '%1$s &rsaquo; %2$s' ), __( 'bbPress installer' ), __( 'Step 2' ) ),
219
+ 'h2' => sprintf( __( '%1$s - %2$s' ), __( 'Step 2' ), __( 'WordPress integration (optional)' ) ),
220
+ 'status' => __( '&laquo; skipped' ),
221
+ 'intro' => array(
222
+ __( 'bbPress can integrate login and user data seamlessly with WordPress. You can safely skip this step if you do not wish to integrate with an existing WordPress install.' )
223
+ ),
224
+ 'messages' => array(),
225
+ 'form_errors' => array()
226
+ ),
227
+ 3 => array(
228
+ 'title' => sprintf( __( '%1$s &rsaquo; %2$s' ), __( 'bbPress installer' ), __( 'Step 3' ) ),
229
+ 'h2' => sprintf( __( '%1$s - %2$s' ), __( 'Step 3' ), __( 'Site settings' ) ),
230
+ 'status' => '',
231
+ 'intro' => array(
232
+ __( 'Finalize your installation by adding a name, your first user and your first forum.' )
233
+ ),
234
+ 'messages' => array(),
235
+ 'form_errors' => array(),
236
+ 'scripts' => array()
237
+ ),
238
+ 4 => array(
239
+ 'title' => sprintf( __( '%1$s &rsaquo; %2$s' ), __( 'bbPress installer' ), __( 'Finished' ) ),
240
+ 'h2' => __( 'Installation complete!' ),
241
+ 'messages' => array()
242
+ )
243
+ );
244
+ }
245
+
246
+ /**
247
+ * Check installation pre-requisites
248
+ *
249
+ * Checks for appropriate PHP extensions.
250
+ *
251
+ * @return boolean False if any pre-requisites are not met, otherwise true
252
+ */
253
+ function check_prerequisites()
254
+ {
255
+ // BPDB wants the MySQL extension - this is also checked when BPDB is initialised so may be a bit redundant here
256
+ if ( !extension_loaded( 'mysql' ) ) {
257
+ $this->strings[-1]['messages']['error'][] = __( 'Your PHP installation appears to be missing the MySQL extension which is required for bbPress' );
258
+ $this->step = -1;
259
+ }
260
+
261
+ if ( defined( 'BB_IS_WP_LOADED' ) && BB_IS_WP_LOADED ) {
262
+ $this->strings[-1]['messages']['error'][] = __( 'Please complete your installation before attempting to include WordPress within bbPress' );
263
+ $this->step = -1;
264
+ }
265
+
266
+ if ( $this->step === -1 ) {
267
+ return false;
268
+ }
269
+
270
+ return true;
271
+ }
272
+
273
+ /**
274
+ * Define path constants
275
+ *
276
+ * Sets some bbPress constants if they are not otherwise available based
277
+ * on the classes initiating file path.
278
+ *
279
+ * @return boolean False if no path was supplied, otherwise always true
280
+ */
281
+ function define_paths()
282
+ {
283
+ if ( !$this->caller ) {
284
+ return false;
285
+ }
286
+
287
+ if ( !defined( 'BACKPRESS_PATH' ) ) {
288
+ // Define BACKPRESS_PATH
289
+ // Tell us to load includes because bb-settings.php was not loaded
290
+ // bb-settings.php is generally not loaded on steps -1, 0 and 1 but
291
+ // there are exceptions, so this is safer than just reading the step
292
+ $this->load_includes = true;
293
+ define( 'BACKPRESS_PATH', BB_PATH . BB_INC . 'backpress/' );
294
+ }
295
+
296
+ // Define the language file directory
297
+ if ( !defined( 'BB_LANG_DIR' ) ) {
298
+ define( 'BB_LANG_DIR', BB_PATH . 'my-languages/' );
299
+ }
300
+
301
+ return true;
302
+ }
303
+
304
+ /**
305
+ * Gets an array of available languages form the language directory
306
+ *
307
+ * @return array
308
+ */
309
+ function get_languages()
310
+ {
311
+ foreach ( bb_glob( BB_LANG_DIR . '*.mo' ) as $language ) {
312
+ $language = str_replace( '.mo', '', basename( $language ) );
313
+ $this->languages[$language] = $language;
314
+ }
315
+
316
+ return $this->languages;
317
+ }
318
+
319
+ /**
320
+ * Returns a language selector for switching installation languages
321
+ *
322
+ * @return string|false Either the html for the selector or false if there are no languages
323
+ */
324
+ function get_language_selector()
325
+ {
326
+ // Don't provide a selection if there is only english
327
+ if ( 2 > count( $this->languages ) ) {
328
+ return false;
329
+ }
330
+
331
+ $r = '<script type="text/javascript" charset="utf-8">' . "\n";
332
+ $r .= "\t" . 'function changeLanguage(selectObj) {' . "\n";
333
+ $r .= "\t\t" . 'var selectedLanguage = selectObj.options[selectObj.selectedIndex].value;' . "\n";
334
+ $r .= "\t\t" . 'location.href = "install.php?language=" + selectedLanguage;' . "\n";
335
+ $r .= "\t" . '}' . "\n";
336
+ $r .= '</script>' . "\n";
337
+ //$r .= '<form id="lang" action="install.php">' . "\n";
338
+ $r .= "\t" . '<fieldset>' . "\n";
339
+ $r .= "\t\t" . '<label class="has-note has-label for-select">' . "\n";
340
+ $r .= "\t\t\t" . '<span>' . __( 'Installation language' ) . '</span>' . "\n";
341
+ $this->tabindex++;
342
+ $r .= "\t\t\t" . '<select class="has-note" onchange="changeLanguage(this);" name="language" tabindex="' . $this->tabindex . '">' . "\n";
343
+ foreach ( $this->languages as $language ) {
344
+ $selected = '';
345
+ if ( $language == $this->language ) {
346
+ $selected = ' selected="selected"';
347
+ }
348
+ $r .= "\t\t\t\t" . '<option value="' . $language . '"' . $selected . '>' . $language . '</option>' . "\n";
349
+ }
350
+ $r .= "\t\t\t" . '</select>' . "\n";
351
+ $r .= "\t\t\t" . '<a class="note-toggle" href="javascript:void(0);" onclick="toggleNote(\'note-language\');">?</a>' . "\n";
352
+ $r .= "\t\t\t" . '<p id="note-language" class="note" style="display:none">' . __( 'Sets the language to be used during the installation process only.' ) . '</p>' . "\n";
353
+ $r .= "\t\t\t" . '<div class="clear"></div>' . "\n";
354
+ $r .= "\t\t" . '</label>' . "\n";
355
+ $r .= "\t" . '</fieldset>' . "\n";
356
+ //$r .= '</form>' . "\n";
357
+
358
+ echo $r;
359
+ }
360
+
361
+ /**
362
+ * Sets the current installation language
363
+ *
364
+ * @return string The currently set language
365
+ */
366
+ function set_language()
367
+ {
368
+ if ( isset( $_COOKIE['bb_install_language'] ) && 1 < count( $this->languages ) ) {
369
+ if ( in_array( $_COOKIE['bb_install_language'], $this->languages ) ) {
370
+ $this->language = $_COOKIE['bb_install_language'];
371
+ }
372
+ }
373
+
374
+ $language_requested = false;
375
+ if ( isset( $_POST['language'] ) && $_POST['language'] ) {
376
+ $language_requested = (string) $_POST['language'];
377
+ } elseif ( isset( $_GET['language'] ) && $_GET['language'] ) {
378
+ $language_requested = (string) $_GET['language'];
379
+ }
380
+
381
+ if ( $language_requested && 1 < count( $this->languages ) ) {
382
+ if ( in_array( $language_requested, $this->languages ) ) {
383
+ $this->language = $language_requested;
384
+ setcookie( 'bb_install_language', $this->language );
385
+ }
386
+ }
387
+
388
+ if ( !$this->language || 'en_US' === $this->language ) {
389
+ $this->language = 'en_US';
390
+ setcookie( 'bb_install_language', ' ', time() - 31536000 );
391
+ }
392
+
393
+ return $this->language;
394
+ }
395
+
396
+ /**
397
+ * Tests whether database tables exist
398
+ *
399
+ * Checks for the existence of the forum table in the database that is
400
+ * currently configured.
401
+ *
402
+ * @return boolean False if the table isn't found, otherwise true
403
+ */
404
+ function database_tables_are_installed()
405
+ {
406
+ global $bbdb;
407
+ $bbdb->suppress_errors();
408
+ $installed = (boolean) $bbdb->get_results( 'DESCRIBE `' . $bbdb->forums . '`;', ARRAY_A );
409
+ $bbdb->suppress_errors( false );
410
+ return $installed;
411
+ }
412
+
413
+ /**
414
+ * Tests whether an option is set in the database
415
+ *
416
+ * @return boolean False if the option isn't set, otherwise true
417
+ */
418
+ function bb_options_are_set()
419
+ {
420
+ if ( $this->load_includes ) {
421
+ return false;
422
+ }
423
+ if ( !bb_get_option( 'uri' ) ) {
424
+ return false;
425
+ }
426
+ return true;
427
+ }
428
+
429
+ /**
430
+ * Tests whether bbPress is installed
431
+ *
432
+ * @return boolean False if bbPress isn't installed, otherwise true
433
+ */
434
+ function is_installed()
435
+ {
436
+ if ( !$this->database_tables_are_installed() ) {
437
+ return false;
438
+ }
439
+ if ( !$this->bb_options_are_set() ) {
440
+ return false;
441
+ }
442
+ return true;
443
+ }
444
+
445
+ /**
446
+ * Checks for configs and sets variables describing current install state
447
+ *
448
+ * @return integer The current step we should be on based on the existence of the config file
449
+ */
450
+ function check_configs()
451
+ {
452
+ // Check for a config file
453
+ if ( file_exists( BB_PATH . 'bb-config.php' ) ) {
454
+ $this->configs['bb-config.php'] = BB_PATH . 'bb-config.php';
455
+ } elseif ( file_exists( dirname( BB_PATH ) . '/bb-config.php' ) ) {
456
+ $this->configs['bb-config.php'] = dirname( BB_PATH ) . '/bb-config.php';
457
+ }
458
+
459
+ // Check for an old config file
460
+ if ( file_exists( BB_PATH . 'config.php' ) ) {
461
+ $this->configs['config.php'] = BB_PATH . 'config.php';
462
+ } elseif ( file_exists( dirname( BB_PATH ) . '/config.php' ) ) {
463
+ $this->configs['config.php'] = dirname( BB_PATH ) . '/config.php';
464
+ }
465
+
466
+ if ( $this->configs['config.php'] && !$this->configs['bb-config.php'] ) {
467
+ // There is an old school config file
468
+ // Step -1 is where we send fatal errors from any screen
469
+ $this->strings[-1]['messages']['error'][] = __( 'An old <code>config.php</code> file has been detected in your installation. You should remove it and run the <a href="install.php">installer</a> again. You can use the same database connection details if you do.' );
470
+ $this->step = -1;
471
+ return $this->step;
472
+ }
473
+
474
+ // Check if bbPress is already installed
475
+ // Is there a current config file
476
+ if ( $this->configs['bb-config.php'] ) {
477
+
478
+ // Is it valid
479
+ if ( $this->validate_current_config() ) {
480
+ // Step 1 is complete
481
+ $this->step_status[1] = 'complete';
482
+ $this->strings[1]['status'] = __( '&laquo; completed' );
483
+
484
+ // On step 1 we want to report that the file is good and allow the user to continue
485
+ if ( $this->step === 1 ) {
486
+ // Stop form processing if it is posted
487
+ $this->stop_process = true;
488
+
489
+ // Display a nice message saying the config file exists
490
+ $this->strings[1]['messages']['message'][] = __( 'A valid configuration file was found at <code>bb-config.php</code><br />You may continue to the next step.' );
491
+ return $this->step;
492
+ }
493
+ } else {
494
+ // Invalid config files on any step cause us to exit to step 0
495
+ $this->strings[-1]['messages']['error'][] = __( 'An invalid configuration file was found at <code>bb-config.php</code><br />The installation cannot continue.' );
496
+ $this->strings[-1]['messages'][0][] = __( 'Usually this is caused by one of the database connection settings being incorrect. Make sure that the specified user has appropriate permission to access the database.' );
497
+ $this->step = -1;
498
+ }
499
+
500
+ // If we have made it this far, then we can check if the database tables exist and have content
501
+ if ( $this->is_installed() ) {
502
+ // The database is installed
503
+ // The following standard functions should be available
504
+ if ( bb_get_option( 'bb_db_version' ) > bb_get_option_from_db( 'bb_db_version' ) ) {
505
+ // The database needs upgrading
506
+ $this->strings[-1]['messages'][0][] = __( 'bbPress is already installed, but appears to require an upgrade.' );
507
+ } else {
508
+ $this->strings[-1]['messages'][0][] = __( 'bbPress is already installed.' );
509
+ }
510
+ $this->strings[-1]['messages'][0][] = sprintf(
511
+ __( 'Perhaps you meant to run the <a href="%s">upgrade script</a> instead?' ),
512
+ bb_get_uri( 'bb-admin/upgrade.php', null, BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN )
513
+ );
514
+ $this->step = -1;
515
+ }
516
+
517
+ } else {
518
+
519
+ if ( 2 > $this->step && !file_exists( BB_PATH . 'bb-config-sample.php' ) ) {
520
+ // There is no sample config file
521
+ $this->strings[0]['messages']['error'][] = __( 'I could not find the file <code>bb-config-sample.php</code><br />Please upload it to the root directory of your bbPress installation.' );
522
+ $this->step = 0;
523
+ }
524
+
525
+ if ( 1 !== $this->step ) {
526
+ // There is no config file, go back to the beginning
527
+ $this->strings[0]['messages']['message'][] = __( 'There doesn\'t seem to be a <code>bb-config.php</code> file. This usually means that you want to install bbPress.' );
528
+ $this->step = 0;
529
+ }
530
+
531
+ }
532
+
533
+ // Check if the config file path is writable
534
+ if ( file_exists( $this->configs['bb-config.php'] ) ) {
535
+ if ( is_writable( $this->configs['bb-config.php'] ) ) {
536
+ $this->configs['writable'] = true;
537
+ }
538
+ } elseif ( is_writable( BB_PATH ) ) {
539
+ $this->configs['writable'] = true;
540
+ }
541
+
542
+ return $this->step;
543
+ }
544
+
545
+ /**
546
+ * Determines if the current config is valid
547
+ *
548
+ * @return boolean False if the config is bad, otherwise true
549
+ */
550
+ function validate_current_config()
551
+ {
552
+ // If we are validating then the config file has already been included
553
+ // So we can just check for valid constants
554
+
555
+ // The required constants for a valid config file
556
+ $required_constants = array(
557
+ 'BBDB_NAME',
558
+ 'BBDB_USER',
559
+ 'BBDB_PASSWORD',
560
+ 'BBDB_HOST'
561
+ );
562
+
563
+ // Check the required constants are defined
564
+ foreach ( $required_constants as $required_constant ) {
565
+ if ( !defined( $required_constant ) ) {
566
+ return false;
567
+ }
568
+ }
569
+
570
+ global $bb_table_prefix;
571
+
572
+ if ( !isset( $bb_table_prefix ) ) {
573
+ return false;
574
+ }
575
+
576
+ // Everthing is OK so far, validate the connection as well
577
+ return $this->validate_current_database();
578
+ }
579
+
580
+ /**
581
+ * Validates the current database settings
582
+ *
583
+ * @return boolean False if the current database isn't valid, otherwise true
584
+ */
585
+ function validate_current_database()
586
+ {
587
+ global $bbdb;
588
+ $db = $bbdb->db_connect( "SELECT * FROM $bbdb->forums LIMIT 1" );
589
+
590
+ if ( !is_resource( $db ) ) {
591
+ return false;
592
+ }
593
+
594
+ return true;
595
+ }
596
+
597
+ /**
598
+ * Sets up default values for input data as well as labels and notes
599
+ *
600
+ * @return void
601
+ */
602
+ function prepare_data()
603
+ {
604
+ /**
605
+ * Should be exactly the same as the default value of the KEYS in bb-config-sample.php
606
+ * @since 1.0
607
+ */
608
+ $_bb_default_secret_key = 'put your unique phrase here';
609
+
610
+ $this->data = array(
611
+ 0 => array(
612
+ 'form' => array(
613
+ 'forward_0_0' => array(
614
+ 'value' => __( 'Go to step 1' )
615
+ )
616
+ )
617
+ ),
618
+ 1 => array(
619
+ 'form' => array(
620
+ 'bbdb_name' => array(
621
+ 'value' => '',
622
+ 'label' => __( 'Database name' ),
623
+ 'note' => __( 'The name of the database in which you want to run bbPress.' )
624
+ ),
625
+ 'bbdb_user' => array(
626
+ 'value' => '',
627
+ 'label' => __( 'Database user' ),
628
+ 'note' => __( 'The database user that has access to that database.' ),
629
+ 'autocomplete' => 'off'
630
+ ),
631
+ 'bbdb_password' => array(
632
+ 'type' => 'password',
633
+ 'value' => '',
634
+ 'label' => __( 'Database password' ),
635
+ 'note' => __( 'That database user\'s password.' ),
636
+ 'autocomplete' => 'off'
637
+ ),
638
+ 'bb_lang' => array(
639
+ 'value' => '',
640
+ 'label' => __( 'Language' ),
641
+ 'note' => sprintf( __( 'The language which bbPress will be presented in once installed. Your current installer language choice (%s) will be the same for the rest of the install process.' ), $this->language )
642
+ ),
643
+ 'toggle_1' => array(
644
+ 'value' => 0,
645
+ 'label' => __( 'Show advanced settings' ),
646
+ 'note' => __( 'These settings usually do not have to be changed.' ),
647
+ 'checked' => '',
648
+ 'display' => 'none'
649
+ ),
650
+ 'bbdb_host' => array(
651
+ 'value' => 'localhost',
652
+ 'label' => __( 'Database host' ),
653
+ 'note' => __( 'The domain name or IP address of the server where the database is located. If the database is on the same server as the web site, then this probably should remain <strong>localhost</strong>.' ),
654
+ 'prerequisite' => 'toggle_1'
655
+ ),
656
+ 'bbdb_charset' => array(
657
+ 'value' => 'utf8',
658
+ 'label' => __( 'Database character set' ),
659
+ 'note' => __( 'The best choice is <strong>utf8</strong>, but you will need to match the character set which you created the database with.' ),
660
+ 'prerequisite' => 'toggle_1'
661
+ ),
662
+ 'bbdb_collate' => array(
663
+ 'value' => '',
664
+ 'label' => __( 'Database character collation' ),
665
+ 'note' => __( 'The character collation value set when the database was created.' ),
666
+ 'prerequisite' => 'toggle_1'
667
+ ),
668
+ /*
669
+ 'bb_auth_key' => array(
670
+ 'value' => $_bb_default_secret_key,
671
+ 'label' => __( 'bbPress "auth" cookie key' ),
672
+ 'note' => __( 'This should be a unique and secret phrase, it will be used to make your bbPress "auth" cookie unique and harder for an attacker to decipher.' ),
673
+ 'prerequisite' => 'toggle_1'
674
+ ),
675
+ 'bb_secure_auth_key' => array(
676
+ 'value' => $_bb_default_secret_key,
677
+ 'label' => __( 'bbPress "secure auth" cookie key' ),
678
+ 'note' => __( 'This should be a unique and secret phrase, it will be used to make your bbPress "secure auth" cookie unique and harder for an attacker to decipher.' ),
679
+ 'prerequisite' => 'toggle_1'
680
+ ),
681
+ 'bb_logged_in_key' => array(
682
+ 'value' => $_bb_default_secret_key,
683
+ 'label' => __( 'bbPress "logged in" cookie key' ),
684
+ 'note' => __( 'This should be a unique and secret phrase, it will be used to make your bbPress "logged in" cookie unique and harder for an attacker to decipher.' ),
685
+ 'prerequisite' => 'toggle_1'
686
+ ),
687
+ 'bb_nonce_key' => array(
688
+ 'value' => $_bb_default_secret_key,
689
+ 'label' => __( 'bbPress "nonce" key' ),
690
+ 'note' => __( 'This should be a unique and secret phrase, it will be used to make form submission harder for an attacker to spoof.' ),
691
+ 'prerequisite' => 'toggle_1'
692
+ ),
693
+ */
694
+ 'bb_table_prefix' => array(
695
+ 'value' => 'bb_',
696
+ 'label' => __( 'Table name prefix' ),
697
+ 'note' => __( 'If you are running multiple bbPress sites in a single database, you will probably want to change this.' ),
698
+ 'prerequisite' => 'toggle_1'
699
+ ),
700
+ 'config' => array(
701
+ 'value' => '',
702
+ 'label' => __( 'Contents for <code>bb-config.php</code>' ),
703
+ 'note' => __( 'Once you have created the configuration file, you can check for it below.' )
704
+ ),
705
+ 'forward_1_0' => array(
706
+ 'value' => __( 'Save database configuration file' )
707
+ ),
708
+ 'back_1_1' => array(
709
+ 'value' => __( '&laquo; Go back' )
710
+ ),
711
+ 'forward_1_1' => array(
712
+ 'value' => __( 'Check for configuration file' )
713
+ ),
714
+ 'forward_1_2' => array(
715
+ 'value' => __( 'Go to step 2' )
716
+ )
717
+ )
718
+ ),
719
+
720
+ 2 => array(
721
+ 'form' => array(
722
+ 'toggle_2_0' => array(
723
+ 'value' => 0,
724
+ 'label' => __( 'Add integration settings' ),
725
+ 'note' => __( 'If you want to integrate bbPress with an existing WordPress site.' ),
726
+ 'checked' => '',
727
+ 'display' => 'none',
728
+ 'toggle_value' => array(
729
+ 'target' => 'forward_2_0',
730
+ 'off_value' => __( 'Skip WordPress integration' ),
731
+ 'on_value' => __( 'Save WordPress integration settings' )
732
+ )
733
+ ),
734
+ 'toggle_2_1' => array(
735
+ 'value' => 0,
736
+ 'label' => __( 'Add cookie integration settings' ),
737
+ 'note' => __( 'If you want to allow shared logins with an existing WordPress site.' ),
738
+ 'checked' => '',
739
+ 'display' => 'none',
740
+ 'prerequisite' => 'toggle_2_0'
741
+ ),
742
+ 'wp_siteurl' => array(
743
+ 'value' => '',
744
+ 'label' => __( 'WordPress address (URL)' ),
745
+ 'note' => __( 'This value should exactly match the <strong>WordPress address (URL)</strong> setting in your WordPress general settings.' ),
746
+ 'prerequisite' => 'toggle_2_1'
747
+ ),
748
+ 'wp_home' => array(
749
+ 'value' => '',
750
+ 'label' => __( 'Blog address (URL)' ),
751
+ 'note' => __( 'This value should exactly match the <strong>Blog address (URL)</strong> setting in your WordPress general settings.' ),
752
+ 'prerequisite' => 'toggle_2_1'
753
+ ),
754
+ 'wp_auth_key' => array(
755
+ 'value' => '',
756
+ 'label' => __( 'WordPress "auth" cookie key' ),
757
+ 'note' => __( 'This value must match the value of the constant named "AUTH_KEY" in your WordPress <code>wp-config.php</code> file. This will replace the bbPress "auth" cookie key set in the first step.' ),
758
+ 'prerequisite' => 'toggle_2_1',
759
+ 'autocomplete' => 'off'
760
+ ),
761
+ 'wp_auth_salt' => array(
762
+ 'value' => '',
763
+ 'label' => __( 'WordPress "auth" cookie salt' ),
764
+ 'note' => __( 'This must match the value of the WordPress setting named "auth_salt" in your WordPress site. Look for the option labeled "auth_salt" in <a href="#" id="getAuthSaltOption" onclick="window.open(this.href); return false;">this WordPress admin page</a>. If you leave this blank the installer will try to fetch the value based on your WordPress database integration settings.' ),
765
+ 'prerequisite' => 'toggle_2_1',
766
+ 'autocomplete' => 'off'
767
+ ),
768
+ 'wp_secure_auth_key' => array(
769
+ 'value' => '',
770
+ 'label' => __( 'WordPress "secure auth" cookie key' ),
771
+ 'note' => __( 'This value must match the value of the constant named "SECURE_AUTH_KEY" in your WordPress <code>wp-config.php</code> file. This will replace the bbPress "secure auth" cookie key set in the first step.' ),
772
+ 'prerequisite' => 'toggle_2_1',
773
+ 'autocomplete' => 'off'
774
+ ),
775
+ 'wp_secure_auth_salt' => array(
776
+ 'value' => '',
777
+ 'label' => __( 'WordPress "secure auth" cookie salt' ),
778
+ 'note' => __( 'This must match the value of the WordPress setting named "secure_auth_salt" in your WordPress site. Look for the option labeled "secure_auth_salt" in <a href="#" id="getSecureAuthSaltOption" onclick="window.open(this.href); return false;">this WordPress admin page</a>. If you leave this blank the installer will try to fetch the value based on your WordPress database integration settings. Sometimes this value is not set in WordPress, in that case you can leave this setting blank as well.' ),
779
+ 'prerequisite' => 'toggle_2_1',
780
+ 'autocomplete' => 'off'
781
+ ),
782
+ 'wp_logged_in_key' => array(
783
+ 'value' => '',
784
+ 'label' => __( 'WordPress "logged in" cookie key' ),
785
+ 'note' => __( 'This value must match the value of the constant named "LOGGED_IN_KEY" in your WordPress <code>wp-config.php</code> file. This will replace the bbPress "logged in" cookie key set in the first step.' ),
786
+ 'prerequisite' => 'toggle_2_1',
787
+ 'autocomplete' => 'off'
788
+ ),
789
+ 'wp_logged_in_salt' => array(
790
+ 'value' => '',
791
+ 'label' => __( 'WordPress "logged in" cookie salt' ),
792
+ 'note' => __( 'This must match the value of the WordPress setting named "logged_in_salt" in your WordPress site. Look for the option labeled "logged_in_salt" in <a href="#" id="getLoggedInSaltOption" onclick="window.open(this.href); return false;">this WordPress admin page</a>. If you leave this blank the installer will try to fetch the value based on your WordPress database integration settings.' ),
793
+ 'prerequisite' => 'toggle_2_1',
794
+ 'autocomplete' => 'off'
795
+ ),
796
+ 'toggle_2_2' => array(
797
+ 'value' => 0,
798
+ 'label' => __( 'Add user database integration settings' ),
799
+ 'note' => __( 'If you want to share user data with an existing WordPress site.' ),
800
+ 'checked' => '',
801
+ 'display' => 'none',
802
+ 'prerequisite' => 'toggle_2_0'
803
+ ),
804
+ 'wp_table_prefix' => array(
805
+ 'value' => 'wp_',
806
+ 'default_value' => '', // Used when setting is ignored
807
+ 'label' => __( 'User database table prefix' ),
808
+ 'note' => __( 'If your bbPress and WordPress sites share the same database, then this is the same value as <code>$table_prefix</code> in your WordPress <code>wp-config.php</code> file. It is usually <strong>wp_</strong>.' ),
809
+ 'prerequisite' => 'toggle_2_2'
810
+ ),
811
+ 'wordpress_mu_primary_blog_id' => array(
812
+ 'value' => '',
813
+ 'default_value' => '',
814
+ 'label' => __( 'WordPress MU primary blog ID' ),
815
+ 'note' => __( 'If you are integrating with a WordPress MU site you need to specify the primary blog ID for that site. It is usually <strong>1</strong>. You should probably leave this blank if you are integrating with a standard WordPress site' ),
816
+ 'prerequisite' => 'toggle_2_2'
817
+ ),
818
+ 'toggle_2_3' => array(
819
+ 'value' => 0,
820
+ 'label' => __( 'Show advanced database settings' ),
821
+ 'note' => __( 'If your bbPress and WordPress site do not share the same database, then you will need to add advanced settings.' ),
822
+ 'checked' => '',
823
+ 'display' => 'none',
824
+ 'prerequisite' => 'toggle_2_2'
825
+ ),
826
+ 'user_bbdb_name' => array(
827
+ 'value' => '',
828
+ 'label' => __( 'User database name' ),
829
+ 'note' => __( 'The name of the database in which your user tables reside.' ),
830
+ 'prerequisite' => 'toggle_2_3'
831
+ ),
832
+ 'user_bbdb_user' => array(
833
+ 'value' => '',
834
+ 'label' => __( 'User database user' ),
835
+ 'note' => __( 'The database user that has access to that database.' ),
836
+ 'prerequisite' => 'toggle_2_3',
837
+ 'autocomplete' => 'off'
838
+ ),
839
+ 'user_bbdb_password' => array(
840
+ 'type' => 'password',
841
+ 'value' => '',
842
+ 'label' => __( 'User database password' ),
843
+ 'note' => __( 'That database user\'s password.' ),
844
+ 'prerequisite' => 'toggle_2_3',
845
+ 'autocomplete' => 'off'
846
+ ),
847
+ 'user_bbdb_host' => array(
848
+ 'value' => '',
849
+ 'label' => __( 'User database host' ),
850
+ 'note' => __( 'The domain name or IP address of the server where the database is located. If the database is on the same server as the web site, then this probably should be <strong>localhost</strong>.' ),
851
+ 'prerequisite' => 'toggle_2_3'
852
+ ),
853
+ 'user_bbdb_charset' => array(
854
+ 'value' => '',
855
+ 'label' => __( 'User database character set' ),
856
+ 'note' => __( 'The best choice is <strong>utf8</strong>, but you will need to match the character set which you created the database with.' ),
857
+ 'prerequisite' => 'toggle_2_3'
858
+ ),
859
+ 'user_bbdb_collate' => array(
860
+ 'value' => '',
861
+ 'label' => __( 'User database character collation' ),
862
+ 'note' => __( 'The character collation value set when the user database was created.' ),
863
+ 'prerequisite' => 'toggle_2_3'
864
+ ),
865
+ 'custom_user_table' => array(
866
+ 'value' => '',
867
+ 'label' => __( 'User database "user" table' ),
868
+ 'note' => __( 'The complete table name, including any prefix.' ),
869
+ 'prerequisite' => 'toggle_2_3'
870
+ ),
871
+ 'custom_user_meta_table' => array(
872
+ 'value' => '',
873
+ 'label' => __( 'User database "user meta" table' ),
874
+ 'note' => __( 'The complete table name, including any prefix.' ),
875
+ 'prerequisite' => 'toggle_2_3'
876
+ ),
877
+ 'forward_2_0' => array(
878
+ 'value' => __( 'Skip WordPress integration' )
879
+ ),
880
+ 'back_2_1' => array(
881
+ 'value' => __( '&laquo; Go back' )
882
+ ),
883
+ 'forward_2_1' => array(
884
+ 'value' => __( 'Go to step 3' )
885
+ )
886
+ )
887
+ ),
888
+
889
+ 3 => array(
890
+ 'form' => array(
891
+ 'name' => array(
892
+ 'value' => '',
893
+ 'label' => __( 'Site name' ),
894
+ 'note' => __( 'This is what you are going to call your bbPress site.' )
895
+ ),
896
+ 'uri' => array(
897
+ 'value' => $this->guess_uri(),
898
+ 'label' => __( 'Site address (URL)' ),
899
+ 'note' => __( 'We have attempted to guess this, it\'s usually correct, but change it here if you wish.' )
900
+ ),
901
+ 'keymaster_user_login' => array(
902
+ 'value' => '',
903
+ 'maxlength' => 60,
904
+ 'label' => __( '"Key Master" Username' ),
905
+ 'note' => __( 'This is the user login for the initial bbPress administrator (known as a "Key Master").' ),
906
+ 'autocomplete' => 'off'
907
+ ),
908
+ 'keymaster_user_email' => array(
909
+ 'value' => '',
910
+ 'maxlength' => 100,
911
+ 'label' => __( '"Key Master" Email address' ),
912
+ 'note' => __( 'The login details will be emailed to this address.' ),
913
+ 'autocomplete' => 'off'
914
+ ),
915
+ 'keymaster_user_type' => array(
916
+ 'value' => 'new'
917
+ ),
918
+ 'forum_name' => array(
919
+ 'value' => '',
920
+ 'maxlength' => 150,
921
+ 'label' => __( 'First forum name' ),
922
+ 'note' => __( 'This can be changed after installation, so don\'t worry about it too much.' )
923
+ ),
924
+ 'forward_3_0' => array(
925
+ 'value' => __( 'Save site settings' )
926
+ ),
927
+ 'back_3_1' => array(
928
+ 'value' => __( '&laquo; Go back' )
929
+ ),
930
+ 'forward_3_1' => array(
931
+ 'value' => __( 'Complete the installation' )
932
+ )
933
+ )
934
+ ),
935
+
936
+ 4 => array(
937
+ 'form' => array(
938
+ 'toggle_4' => array(
939
+ 'value' => 0,
940
+ 'label' => __( 'Show installation messages' )
941
+ ),
942
+ 'error_log' => array(
943
+ 'value' => '',
944
+ 'label' => __( 'Installation errors' )
945
+ ),
946
+ 'installation_log' => array(
947
+ 'value' => '',
948
+ 'label' => __( 'Installation log' )
949
+ )
950
+ )
951
+ )
952
+ );
953
+ }
954
+
955
+ /**
956
+ * Guesses the final installed URI based on the location of the install script
957
+ *
958
+ * @return string The guessed URI
959
+ */
960
+ function guess_uri()
961
+ {
962
+ global $bb;
963
+
964
+ if ( $bb->uri ) {
965
+ $uri = $bb->uri;
966
+ } else {
967
+ $schema = 'http://';
968
+ if ( isset( $_SERVER['HTTPS'] ) && strtolower( $_SERVER['HTTPS'] ) == 'on' ) {
969
+ $schema = 'https://';
970
+ }
971
+ $uri = preg_replace( '|/bb-admin/.*|i', '/', $schema . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
972
+ }
973
+
974
+ return rtrim( $uri, " \t\n\r\0\x0B/" ) . '/';
975
+ }
976
+
977
+ /**
978
+ * Writes the given alterations to file
979
+ *
980
+ * @param $file_source string The full path to the file to be read from
981
+ * @param $file_target string The full path to the file to be written to
982
+ * @param $alterations array An array of arrays containing alterations to be made
983
+ * @return void
984
+ */
985
+ function write_lines_to_file( $file_source, $file_target, $alterations )
986
+ {
987
+ if ( !$file_source || !file_exists( $file_source ) || !is_file( $file_source ) ) {
988
+ return -1;
989
+ }
990
+
991
+ if ( !$file_target ) {
992
+ $file_target = $file_source;
993
+ }
994
+
995
+ if ( !$alterations || !is_array( $alterations ) ) {
996
+ return -2;
997
+ }
998
+
999
+ /*
1000
+ Alterations array takes the form
1001
+ array(
1002
+ '1st 20 chars of line' => array( 'Search string', 'Replacement string' ),
1003
+ '1st 20 chars of line' => array( 'Search string', 'Replacement string' )
1004
+ );
1005
+ */
1006
+
1007
+ // Get the existing lines in the file
1008
+ $lines = file( $file_source );
1009
+
1010
+ // Initialise an array to store the modified lines
1011
+ $modified_lines = array();
1012
+
1013
+ // Loop through the lines and modify them
1014
+ foreach ( $lines as $line ) {
1015
+ if ( isset( $alterations[substr( $line, 0, 20 )] ) ) {
1016
+ $alteration = $alterations[substr( $line, 0, 20 )];
1017
+ $modified_lines[] = str_replace( $alteration[0], $alteration[1], $line );
1018
+ } else {
1019
+ $modified_lines[] = $line;
1020
+ }
1021
+ }
1022
+
1023
+ $writable = true;
1024
+ if ( file_exists( $file_target ) ) {
1025
+ if ( !is_writable( $file_target ) ) {
1026
+ $writable = false;
1027
+ }
1028
+ } else {
1029
+ $dir_target = dirname( $file_target );
1030
+ if ( file_exists( $dir_target ) ) {
1031
+ if ( !is_writable( $dir_target ) || !is_dir( $dir_target ) ) {
1032
+ $writable = false;
1033
+ }
1034
+ } else {
1035
+ $writable = false;
1036
+ }
1037
+ }
1038
+
1039
+ if ( !$writable ) {
1040
+ return trim( join( null, $modified_lines ) );
1041
+ }
1042
+
1043
+ // Open the file for writing - rewrites the whole file
1044
+ $file_handle = fopen( $file_target, 'w' );
1045
+
1046
+ // Write lines one by one to avoid OS specific newline hassles
1047
+ foreach ( $modified_lines as $modified_line ) {
1048
+ if ( false !== strpos( $modified_line, '?>' ) ) {
1049
+ $modified_line = '?>';
1050
+ }
1051
+ fwrite( $file_handle, $modified_line );
1052
+ if ( $modified_line == '?>' ) {
1053
+ break;
1054
+ }
1055
+ }
1056
+
1057
+ // Close the config file
1058
+ fclose( $file_handle );
1059
+
1060
+ @chmod( $file_target, 0666 );
1061
+
1062
+ return 1;
1063
+ }
1064
+
1065
+ /**
1066
+ * Reports whether the request method is post or not
1067
+ *
1068
+ * @return boolean True if the page was posted, otherwise false
1069
+ */
1070
+ function is_posted()
1071
+ {
1072
+ if ( 'post' === strtolower( $_SERVER['REQUEST_METHOD'] ) ) {
1073
+ return true;
1074
+ }
1075
+ return false;
1076
+ }
1077
+
1078
+ /**
1079
+ * Determines which step the installer is on based on user input
1080
+ *
1081
+ * @return boolean Always returns true
1082
+ **/
1083
+ function set_step()
1084
+ {
1085
+ if ( $this->is_posted() ) {
1086
+ switch ( $this->step ) {
1087
+ case 1:
1088
+ $this->set_language();
1089
+ if ( $_POST['forward_0_0'] ) {
1090
+ $this->stop_process = 1;
1091
+ }
1092
+ break;
1093
+
1094
+ case 2:
1095
+ if ( $_POST['forward_1_2'] ) {
1096
+ $this->stop_process = 1;
1097
+ }
1098
+ break;
1099
+
1100
+ case 3:
1101
+ // If this is actually a request to go back to step 2
1102
+ if ( $_POST['back_2_1'] ) {
1103
+ $this->step = 2;
1104
+ break;
1105
+ }
1106
+
1107
+ // If we have come forward from step 2 then don't process form 3
1108
+ if ( $_POST['forward_2_1'] ) {
1109
+ $this->stop_process = true;
1110
+ }
1111
+
1112
+ // Determine what the status of the previous step was based on input
1113
+ if ( $_POST['toggle_2_0'] ) {
1114
+ $this->strings[2]['status'] = __( '&laquo; completed' );
1115
+ $this->step_status[2] = 'complete';
1116
+ }
1117
+ break;
1118
+
1119
+ case 4:
1120
+ // Determine what the status of the previous step was based on input
1121
+ if ( $_POST['toggle_2_0'] ) {
1122
+ $this->strings[2]['status'] = __( '&laquo; completed' );
1123
+ $this->step_status[2] = 'complete';
1124
+ }
1125
+
1126
+ // If this is actually a request to go back to step 3
1127
+ if ( $_POST['back_3_1'] ) {
1128
+ $this->step = 3;
1129
+ break;
1130
+ }
1131
+
1132
+ // We have to have come forward from step 3
1133
+ if ( $_POST['forward_3_1'] ) {
1134
+ $this->strings[3]['status'] = __( '&laquo; completed' );
1135
+ $this->step_status[3] = 'complete';
1136
+ } else {
1137
+ $this->step = 2;
1138
+ }
1139
+ break;
1140
+ }
1141
+ }
1142
+ return true;
1143
+ }
1144
+
1145
+ /**
1146
+ * Sanitizes all data stored in the data array
1147
+ *
1148
+ * @return boolean Always returns true
1149
+ **/
1150
+ function sanitize_form_data()
1151
+ {
1152
+ foreach ( $this->data as $step => $data ) {
1153
+ if ( isset( $data['form'] ) && is_array( $data['form'] ) ) {
1154
+ foreach ( $data['form'] as $key => $value ) {
1155
+ $this->data[$step]['form'][$key]['value'] = esc_attr( $value['value'] );
1156
+ }
1157
+ }
1158
+ }
1159
+ return true;
1160
+ }
1161
+
1162
+ /**
1163
+ * Directs processing of the form data based on the current step
1164
+ *
1165
+ * @return boolean Always returns true
1166
+ **/
1167
+ function process_form()
1168
+ {
1169
+ if ( $this->is_posted() && !$this->stop_process ) {
1170
+ switch ( $this->step ) {
1171
+ case 1:
1172
+ $this->process_form_config_file();
1173
+ break;
1174
+
1175
+ case 2:
1176
+ $this->process_form_wordpress_integration();
1177
+ break;
1178
+
1179
+ case 3:
1180
+ $this->process_form_site_options();
1181
+ break;
1182
+
1183
+ case 4:
1184
+ $this->process_form_finalise_installation();
1185
+ break;
1186
+ }
1187
+ }
1188
+ return true;
1189
+ }
1190
+
1191
+ /**
1192
+ * Takes inputted form data and injects it into the data array
1193
+ *
1194
+ * @param integer $step Which steps data to process
1195
+ * @return boolean Always returns true
1196
+ **/
1197
+ function inject_form_values_into_data( $step )
1198
+ {
1199
+ $data =& $this->data[$step]['form'];
1200
+
1201
+ foreach ( $data as $key => $value ) {
1202
+ if ( 'forward_' !== substr( $key, 0, 8 ) && 'back_' !== substr( $key, 0, 5 ) ) {
1203
+ if ( isset( $data[$key]['prerequisite'] ) && !$_POST[$data[$key]['prerequisite']] ) {
1204
+ if ( isset( $data[$key]['default_value'] ) ) {
1205
+ $data[$key]['value'] = $data[$key]['default_value'];
1206
+ }
1207
+ // do nothing - keep the default value
1208
+ } else {
1209
+ $data[$key]['value'] = stripslashes_deep( trim( $_POST[$key] ) );
1210
+ }
1211
+ }
1212
+ }
1213
+
1214
+ return true;
1215
+ }
1216
+
1217
+ /**
1218
+ * Validates the supplied config file data and writes it to the config file.
1219
+ *
1220
+ * @return void
1221
+ **/
1222
+ function process_form_config_file()
1223
+ {
1224
+ $this->inject_form_values_into_data( 1 );
1225
+
1226
+ $data =& $this->data[1]['form'];
1227
+
1228
+ if ( 'en_US' == $data['bb_lang']['value'] ) {
1229
+ $data['bb_lang']['value'] = '';
1230
+ }
1231
+
1232
+ if ( $data['toggle_1']['value'] ) {
1233
+ $data['toggle_1']['checked'] = 'checked="checked"';
1234
+ $data['toggle_1']['display'] = 'block';
1235
+
1236
+ // Deal with slashes in the keys
1237
+ //$data['bb_auth_key']['value'] = addslashes( stripslashes( $data['bb_auth_key']['value'] ) );
1238
+ //$data['bb_secure_auth_key']['value'] = addslashes( stripslashes( $data['bb_secure_auth_key']['value'] ) );
1239
+ //$data['bb_logged_in_key']['value'] = addslashes( stripslashes( $data['bb_logged_in_key']['value'] ) );
1240
+ //$data['bb_nonce_key']['value'] = addslashes( stripslashes( $data['bb_nonce_key']['value'] ) );
1241
+ }
1242
+
1243
+ $requested_prefix = $data['bb_table_prefix']['value'];
1244
+ $data['bb_table_prefix']['value'] = preg_replace( '/[^0-9a-zA-Z_]/', '', $data['bb_table_prefix']['value'] );
1245
+ if ( $requested_prefix !== $data['bb_table_prefix']['value'] ) {
1246
+ $data['toggle_1']['checked'] = 'checked="checked"';
1247
+ $data['toggle_1']['display'] = 'block';
1248
+ $this->step_status[1] = 'incomplete';
1249
+ $this->strings[1]['messages']['error'][] = __( 'The table prefix can only contain letters, numbers and underscores.<br />Please review the suggestion below.' );
1250
+ $this->strings[1]['form_errors']['bb_table_prefix'][] = __( '&bull; Based on your input the following prefix is suggested.' );
1251
+ return 'incomplete';
1252
+ }
1253
+ if ( empty( $data['bb_table_prefix']['value'] ) ) {
1254
+ $data['bb_table_prefix']['value'] = 'bb_';
1255
+ $data['toggle_1']['checked'] = 'checked="checked"';
1256
+ $data['toggle_1']['display'] = 'block';
1257
+ $this->step_status[1] = 'incomplete';
1258
+ $this->strings[1]['messages']['error'][] = __( 'The table prefix can not be blank.<br />Please review the suggestion below.' );
1259
+ $this->strings[1]['form_errors']['bb_table_prefix'][] = __( '&bull; The default prefix has been inserted.' );
1260
+ return 'incomplete';
1261
+ }
1262
+
1263
+ // Stop here if we are going backwards
1264
+ if ( $_POST['back_1_1'] ) {
1265
+ $this->step_status[1] = 'incomplete';
1266
+ return 'incomplete';
1267
+ }
1268
+
1269
+ // Test the db connection.
1270
+ define( 'BBDB_NAME', $data['bbdb_name']['value'] );
1271
+ define( 'BBDB_USER', $data['bbdb_user']['value'] );
1272
+ define( 'BBDB_PASSWORD', $data['bbdb_password']['value'] );
1273
+ define( 'BBDB_HOST', $data['bbdb_host']['value'] );
1274
+ define( 'BBDB_CHARSET', $data['bbdb_charset']['value'] );
1275
+ define( 'BBDB_COLLATE', $data['bbdb_collate']['value'] );
1276
+
1277
+ // We'll fail here if the values are no good.
1278
+ require_once( BACKPRESS_PATH . 'class.bpdb-multi.php' );
1279
+
1280
+ $bbdb =& new BPDB_Multi( array(
1281
+ 'name' => BBDB_NAME,
1282
+ 'user' => BBDB_USER,
1283
+ 'password' => BBDB_PASSWORD,
1284
+ 'host' => BBDB_HOST,
1285
+ 'charset' => defined( 'BBDB_CHARSET' ) ? BBDB_CHARSET : false,
1286
+ 'collate' => defined( 'BBDB_COLLATE' ) ? BBDB_COLLATE : false,
1287
+ 'errors' => 'suppress'
1288
+ ) );
1289
+
1290
+ if ( !$bbdb->db_connect( 'SHOW TABLES;' ) ) {
1291
+ $bbdb->suppress_errors( false );
1292
+ $this->step_status[1] = 'incomplete';
1293
+ $this->strings[1]['messages']['error'][] = __( 'There was a problem connecting to the database you specified.<br />Please check the settings, then try again.' );
1294
+ return 'error';
1295
+ }
1296
+ $bbdb->suppress_errors( false );
1297
+
1298
+ $config_result = $this->write_lines_to_file(
1299
+ BB_PATH . 'bb-config-sample.php',
1300
+ BB_PATH . 'bb-config.php',
1301
+ array(
1302
+ "define( 'BBDB_NAME'," => array( "'bbpress'", "'" . $data['bbdb_name']['value'] . "'" ),
1303
+ "define( 'BBDB_USER'," => array( "'username'", "'" . $data['bbdb_user']['value'] . "'" ),
1304
+ "define( 'BBDB_PASSWO" => array( "'password'", "'" . $data['bbdb_password']['value'] . "'" ),
1305
+ "define( 'BBDB_HOST'," => array( "'localhost'", "'" . $data['bbdb_host']['value'] . "'" ),
1306
+ "define( 'BBDB_CHARSE" => array( "'utf8'", "'" . $data['bbdb_charset']['value'] . "'" ),
1307
+ "define( 'BBDB_COLLAT" => array( "''", "'" . $data['bbdb_collate']['value'] . "'" ),
1308
+ //"define( 'BB_AUTH_KEY" => array( "'put your unique phrase here'", "'" . $data['bb_auth_key']['value'] . "'" ),
1309
+ //"define( 'BB_SECURE_A" => array( "'put your unique phrase here'", "'" . $data['bb_secure_auth_key']['value'] . "'" ),
1310
+ //"define( 'BB_LOGGED_I" => array( "'put your unique phrase here'", "'" . $data['bb_logged_in_key']['value'] . "'" ),
1311
+ //"define( 'BB_NONCE_KE" => array( "'put your unique phrase here'", "'" . $data['bb_nonce_key']['value'] . "'" ),
1312
+ "\$bb_table_prefix = '" => array( "'bb_'", "'" . $data['bb_table_prefix']['value'] . "'" ),
1313
+ "define( 'BB_LANG', '" => array( "''", "'" . $data['bb_lang']['value'] . "'" )
1314
+ )
1315
+ );
1316
+
1317
+ switch ( $config_result ) {
1318
+ case -1:
1319
+ $this->step_status[1] = 'error';
1320
+ $this->strings[1]['messages']['error'][] = __( 'I could not find the file <code>bb-config-sample.php</code><br />Please upload it to the root directory of your bbPress installation.' );
1321
+ return 'error';
1322
+ break;
1323
+ case 1:
1324
+ $this->configs['bb-config.php'] = BB_PATH . 'bb-config.php';
1325
+ $this->step_status[1] = 'complete';
1326
+ $this->strings[1]['messages']['message'][] = __( 'Your settings have been saved to the file <code>bb-config.php</code><br />You can now continue to the next step.' );
1327
+ break;
1328
+ default:
1329
+ // Just write the contents to screen
1330
+ $this->data[1]['form']['config']['value'] = $config_result;
1331
+
1332
+ $this->step_status[1] = 'manual';
1333
+ $this->strings[1]['messages']['error'][] = __( 'Your settings could not be saved to a configuration file. You will need to save the text shown below into a file named <code>bb-config.php</code> in the root directory of your bbPress installation before you can continue.' );
1334
+ break;
1335
+ }
1336
+ }
1337
+
1338
+ /**
1339
+ * Validates the WordPress integration settings
1340
+ *
1341
+ * @return void
1342
+ **/
1343
+ function process_form_wordpress_integration()
1344
+ {
1345
+ // Check the referer
1346
+ bb_check_admin_referer( 'bbpress-installer' );
1347
+
1348
+ $this->inject_form_values_into_data( 2 );
1349
+
1350
+ $data =& $this->data[2]['form'];
1351
+
1352
+ // If there are no settings then goto step 3
1353
+ if ( !$data['toggle_2_0']['value'] && !$_POST['back_2_1'] ) {
1354
+ $this->step_status[2] = 'complete';
1355
+ $this->strings[2]['messages']['message'][] = __( 'You have chosen to skip the WordPress integration step. You can always integrate WordPress later from within the admin area of bbPress.' );
1356
+ return 'complete';
1357
+ }
1358
+
1359
+ // If integration is selected
1360
+ if ( $data['toggle_2_0']['value'] ) {
1361
+ $data['toggle_2_0']['checked'] = 'checked="checked"';
1362
+ $data['toggle_2_0']['display'] = 'block';
1363
+ $data['forward_2_0']['value'] = $data['toggle_2_0']['toggle_value']['on_value'];
1364
+
1365
+ if ( $data['toggle_2_1']['value'] ) {
1366
+ $data['toggle_2_1']['checked'] = 'checked="checked"';
1367
+ $data['toggle_2_1']['display'] = 'block';
1368
+
1369
+ // Check the wp_siteurl URL for errors
1370
+ $data['wp_siteurl']['value'] = $data['wp_siteurl']['value'] ? rtrim( $data['wp_siteurl']['value'], " \t\n\r\0\x0B/" ) . '/' : '';
1371
+ $this->strings[2]['form_errors']['wp_siteurl'][] = empty( $data['wp_siteurl']['value'] ) ? 'empty' : false;
1372
+ if ( $parsed = parse_url( $data['wp_siteurl']['value'] ) ) {
1373
+ $this->strings[2]['form_errors']['wp_siteurl'][] = preg_match( '/https?/i', $parsed['scheme'] ) ? false : 'urlscheme';
1374
+ $this->strings[2]['form_errors']['wp_siteurl'][] = empty( $parsed['host'] ) ? 'urlhost' : false;
1375
+ } else {
1376
+ $this->strings[2]['form_errors']['wp_siteurl'][] = 'urlparse';
1377
+ }
1378
+
1379
+ // Check the wp_home URL for errors
1380
+ $data['wp_home']['value'] = $data['wp_home']['value'] ? rtrim( $data['wp_home']['value'], " \t\n\r\0\x0B/" ) . '/' : '';
1381
+ $this->strings[2]['form_errors']['wp_home'][] = empty( $data['wp_home']['value'] ) ? 'empty' : false;
1382
+ if ( $parsed = parse_url( $data['wp_home']['value'] ) ) {
1383
+ $this->strings[2]['form_errors']['wp_home'][] = preg_match( '/https?/i', $parsed['scheme'] ) ? false : 'urlscheme';
1384
+ $this->strings[2]['form_errors']['wp_home'][] = empty( $parsed['host'] ) ? 'urlhost' : false;
1385
+ } else {
1386
+ $this->strings[2]['form_errors']['wp_home'][] = 'urlparse';
1387
+ }
1388
+
1389
+ // Deal with slashes in the keys
1390
+ $data['wp_auth_key']['value'] = addslashes( stripslashes( $data['wp_auth_key']['value'] ) );
1391
+ $data['wp_auth_salt']['value'] = addslashes( stripslashes( $data['wp_auth_salt']['value'] ) );
1392
+ $data['wp_secure_auth_key']['value'] = addslashes( stripslashes( $data['wp_secure_auth_key']['value'] ) );
1393
+ $data['wp_secure_auth_salt']['value'] = addslashes( stripslashes( $data['wp_secure_auth_salt']['value'] ) );
1394
+ $data['wp_logged_in_key']['value'] = addslashes( stripslashes( $data['wp_logged_in_key']['value'] ) );
1395
+ $data['wp_logged_in_salt']['value'] = addslashes( stripslashes( $data['wp_logged_in_salt']['value'] ) );
1396
+
1397
+ // Check the keys for errors
1398
+ $this->strings[2]['form_errors']['wp_auth_key'][] = empty( $data['wp_auth_key']['value'] ) ? 'empty' : false;
1399
+ $this->strings[2]['form_errors']['wp_secure_auth_key'][] = empty( $data['wp_secure_auth_key']['value'] ) ? 'empty' : false;
1400
+ $this->strings[2]['form_errors']['wp_logged_in_key'][] = empty( $data['wp_logged_in_key']['value'] ) ? 'empty' : false;
1401
+
1402
+ // Salts can be taken from the database if specified
1403
+ if ( !$data['toggle_2_2']['value'] ) {
1404
+ $this->strings[2]['form_errors']['wp_auth_salt'][] = empty( $data['wp_auth_salt']['value'] ) ? 'empty' : false;
1405
+ // NB; secure_auth_salt is not always set in WordPress
1406
+ $this->strings[2]['form_errors']['wp_logged_in_salt'][] = empty( $data['wp_logged_in_salt']['value'] ) ? 'empty' : false;
1407
+ }
1408
+ }
1409
+
1410
+ // If database integration is selected
1411
+ if ( $data['toggle_2_2']['value'] ) {
1412
+ $data['toggle_2_2']['checked'] = 'checked="checked"';
1413
+ $data['toggle_2_2']['display'] = 'block';
1414
+
1415
+ // Make the wp_table_prefix valid
1416
+ $data['wp_table_prefix']['value'] = preg_replace( '/[^0-9a-zA-Z_]/', '', $data['wp_table_prefix']['value'] );
1417
+ $data['wp_table_prefix']['value'] = empty( $data['wp_table_prefix']['value'] ) ? 'wp_' : $data['wp_table_prefix']['value'];
1418
+
1419
+ // Make the wordpress_mu_primary_blog_id valid
1420
+ $data['wordpress_mu_primary_blog_id']['value'] = preg_replace( '/[^0-9]/', '', $data['wordpress_mu_primary_blog_id']['value'] );
1421
+
1422
+ // If advanced database integration is selected
1423
+ if ( $data['toggle_2_3']['value'] ) {
1424
+ $data['toggle_2_3']['checked'] = 'checked="checked"';
1425
+ $data['toggle_2_3']['display'] = 'block';
1426
+ }
1427
+ }
1428
+
1429
+ if ( !$data['toggle_2_1']['value'] && !$data['toggle_2_2']['value'] ) {
1430
+ $this->step_status[2] = 'incomplete';
1431
+ $this->strings[2]['messages']['error'][] = __( 'You must enter your settings for integration setup to complete. Choose which integration settings you wish to enter from the options below.' );
1432
+ $this->strings[2]['form_errors']['toggle_2_1'][] = true;
1433
+ $this->strings[2]['form_errors']['toggle_2_2'][] = true;
1434
+ return 'incomplete';
1435
+ }
1436
+
1437
+ // Remove empty values from the error array
1438
+ foreach ( $this->strings[2]['form_errors'] as $input => $types) {
1439
+ $types = array_filter( $types);
1440
+ if ( !count( $types ) ) {
1441
+ unset( $this->strings[2]['form_errors'][$input] );
1442
+ }
1443
+ }
1444
+
1445
+ // Check for errors and build error messages
1446
+ if ( count( $this->strings[2]['form_errors'] ) ) {
1447
+
1448
+ $this->step_status[2] = 'incomplete';
1449
+ $this->strings[2]['messages']['error'][] = __( 'Your integration settings have not been processed due to errors with the items marked below.' );
1450
+
1451
+ foreach ( $this->strings[2]['form_errors'] as $input => $types ) {
1452
+ $errors = array();
1453
+
1454
+ foreach ( $types as $type ) {
1455
+ switch ( $type ) {
1456
+ case 'empty':
1457
+ // Only return this error when empty
1458
+ $errors = array( __( '&bull; This value is required to continue.' ) );
1459
+ break(2);
1460
+ case 'urlparse':
1461
+ $errors[] = __( '&bull; This does not appear to be a valid URL.' );
1462
+ break;
1463
+ case 'urlscheme':
1464
+ $errors[] = __( '&bull; The URL must begin with "http" or "https".' );
1465
+ break;
1466
+ case 'urlhost':
1467
+ $errors[] = __( '&bull; The URL does not contain a host name.' );
1468
+ break;
1469
+ }
1470
+ }
1471
+
1472
+ $this->strings[2]['form_errors'][$input] = $errors;
1473
+ }
1474
+
1475
+ return 'incomplete';
1476
+ }
1477
+
1478
+ // If database integration is selected
1479
+ if ( $data['toggle_2_2']['value'] ) {
1480
+
1481
+ // Test the db connection.
1482
+
1483
+ // Setup variables and constants if available
1484
+ global $bb;
1485
+ $bb->wp_table_prefix = $data['wp_table_prefix']['value'];
1486
+ if ( $data['toggle_2_3']['value'] ) {
1487
+ // These may be empty at this particular stage
1488
+ if ( !empty( $data['user_bbdb_name']['value'] ) ) {
1489
+ $bb->user_bbdb_name = $data['user_bbdb_name']['value'];
1490
+ }
1491
+ if ( !empty( $data['user_bbdb_user']['value'] ) ) {
1492
+ $bb->user_bbdb_user = $data['user_bbdb_user']['value'];
1493
+ }
1494
+ if ( !empty( $data['user_bbdb_password']['value'] ) ) {
1495
+ $bb->user_bbdb_password = $data['user_bbdb_password']['value'];
1496
+ }
1497
+ if ( !empty( $data['user_bbdb_host']['value'] ) ) {
1498
+ $bb->user_bbdb_host = $data['user_bbdb_host']['value'];
1499
+ }
1500
+ if ( !empty( $data['user_bbdb_charset']['value'] ) ) {
1501
+ $bb->user_bbdb_charset = preg_replace( '/[^a-z0-9_-]/i', '', $data['user_bbdb_charset']['value'] );
1502
+ }
1503
+ if ( !empty( $data['user_bbdb_collate']['value'] ) ) {
1504
+ $bb->user_bbdb_collate = preg_replace( '/[^a-z0-9_-]/i', '', $data['user_bbdb_collate']['value'] );
1505
+ }
1506
+ if ( !empty( $data['custom_user_table']['value'] ) ) {
1507
+ $bb->custom_user_table = preg_replace( '/[^a-z0-9_-]/i', '', $data['custom_user_table']['value'] );
1508
+ }
1509
+ if ( !empty( $data['custom_user_meta_table']['value'] ) ) {
1510
+ $bb->custom_user_meta_table = preg_replace( '/[^a-z0-9_-]/i', '', $data['custom_user_meta_table']['value'] );
1511
+ }
1512
+ }
1513
+
1514
+ // Bring in the database object
1515
+ global $bbdb;
1516
+ global $bb_table_prefix;
1517
+
1518
+ // Resolve the custom user tables for bpdb
1519
+ bb_set_custom_user_tables();
1520
+
1521
+ if ( isset( $bb->custom_databases) && isset( $bb->custom_databases['user'] ) ) {
1522
+ $bbdb->add_db_server( 'user', $bb->custom_databases['user'] );
1523
+ }
1524
+
1525
+ // Add custom tables if required
1526
+ if ( isset( $bb->custom_tables['users'] ) || isset( $bb->custom_tables['usermeta'] ) ) {
1527
+ $bbdb->tables = array_merge( $bbdb->tables, $bb->custom_tables );
1528
+ if ( is_wp_error( $bbdb->set_prefix( $bb_table_prefix ) ) ) {
1529
+ die( __( 'Your user table prefix may only contain letters, numbers and underscores.' ) );
1530
+ }
1531
+ }
1532
+
1533
+ // Hide errors for the test
1534
+ $bbdb->hide_errors();
1535
+
1536
+ $result = $bbdb->query( 'DESCRIBE ' . $bbdb->users . ';' );
1537
+ $result_error = $bbdb->get_error();
1538
+
1539
+ // Select from the user table (may fail if there are no records in the table)
1540
+ if ( !$result && $result_error ) {
1541
+ // We couldn't connect to the database at all
1542
+
1543
+ // Turn errors back on
1544
+ $bbdb->show_errors();
1545
+
1546
+ // Set the status
1547
+ $this->step_status[2] = 'incomplete';
1548
+ if ( !empty( $data['user_bbdb_name']['value'] ) ) {
1549
+ $this->strings[2]['form_errors']['user_bbdb_name'][] = true;
1550
+ }
1551
+ if ( !empty( $data['user_bbdb_user']['value'] ) ) {
1552
+ $this->strings[2]['form_errors']['user_bbdb_user'][] = true;
1553
+ }
1554
+ if ( !empty( $data['user_bbdb_password']['value'] ) ) {
1555
+ $this->strings[2]['form_errors']['user_bbdb_password'][] = true;
1556
+ }
1557
+ if ( !empty( $data['user_bbdb_host']['value'] ) ) {
1558
+ $this->strings[2]['form_errors']['user_bbdb_host'][] = true;
1559
+ }
1560
+ if ( !empty( $data['custom_user_table']['value'] ) ) {
1561
+ $this->strings[2]['form_errors']['custom_user_table'][] = true;
1562
+ }
1563
+ if ( !empty( $data['custom_user_meta_table']['value'] ) ) {
1564
+ $this->strings[2]['form_errors']['custom_user_meta_table'][] = true;
1565
+ }
1566
+ $this->strings[2]['messages']['error'][] = __( 'There was a problem connecting to the WordPress user database you specified. Please check the settings, then try again.' );
1567
+ return 'incomplete';
1568
+ }
1569
+
1570
+ if ( $result_error ) {
1571
+ // The result is an error, presumably telling us the table doesn't exist
1572
+
1573
+ // Turn errors back on
1574
+ $bbdb->show_errors();
1575
+
1576
+ // Set the status
1577
+ $this->step_status[2] = 'incomplete';
1578
+
1579
+ if ( $data['toggle_2_3']['value'] ) {
1580
+ $this->strings[2]['messages']['error'][] = __( 'Existing WordPress user tables could not be found in the WordPress database you specified.' );
1581
+ } else {
1582
+ $this->strings[2]['messages']['error'][] = __( 'Existing WordPress user tables could not be found in the bbPress database you specified in step 1.<br /><br />This is probably because the database does not already contain working WordPress tables. You may need to specify advanced database settings or leave integration until after installation.' );
1583
+ }
1584
+ $this->strings[2]['form_errors']['wp_table_prefix'][] = __( '&bull; This may not be a valid user table prefix.' );
1585
+ return 'incomplete';
1586
+ }
1587
+
1588
+ // Turn errors back on
1589
+ $bbdb->show_errors();
1590
+ }
1591
+ }
1592
+
1593
+ // Stop here if we are going backwards
1594
+ if ( $_POST['back_2_1'] ) {
1595
+ $this->step_status[2] = 'incomplete';
1596
+ return 'incomplete';
1597
+ }
1598
+
1599
+ // If we make it this may we are complete, so set the status to complete
1600
+ $this->step_status[2] = 'complete';
1601
+ $this->strings[2]['messages']['message'][] = __( 'Your WordPress integration cookie and database settings have been successfully validated. They will be saved after the next step.<br /><br />Once you have finished installing, you should visit the WordPress integration section of the bbPress admin area for further options and integration instructions, including user mapping and the correct cookie settings to add to your WordPress configuration file.' );
1602
+ return 'complete';
1603
+ }
1604
+
1605
+ /**
1606
+ * Validates the site options.
1607
+ *
1608
+ * @return void
1609
+ **/
1610
+ function process_form_site_options()
1611
+ {
1612
+ // Check the referer
1613
+ bb_check_admin_referer( 'bbpress-installer' );
1614
+
1615
+ $this->inject_form_values_into_data( 2 );
1616
+ $this->inject_form_values_into_data( 3 );
1617
+
1618
+ $data =& $this->data[3]['form'];
1619
+
1620
+ $this->strings[3]['form_errors']['name'][] = empty( $data['name']['value'] ) ? 'empty' : false;
1621
+
1622
+ $data['uri']['value'] = $data['uri']['value'] ? rtrim( $data['uri']['value'], " \t\n\r\0\x0B/" ) . '/' : '';
1623
+ $this->strings[3]['form_errors']['uri'][] = empty( $data['uri']['value'] ) ? 'empty' : false;
1624
+ if ( $parsed = parse_url( $data['uri']['value'] ) ) {
1625
+ $this->strings[3]['form_errors']['uri'][] = preg_match( '/https?/i', $parsed['scheme'] ) ? false : 'urlscheme';
1626
+ $this->strings[3]['form_errors']['uri'][] = empty( $parsed['host'] ) ? 'urlhost' : false;
1627
+ } else {
1628
+ $this->strings[3]['form_errors']['uri'][] = 'urlparse';
1629
+ }
1630
+
1631
+ $this->strings[3]['form_errors']['keymaster_user_login'][] = empty( $data['keymaster_user_login']['value'] ) ? 'empty' : false;
1632
+ if ( $data['keymaster_user_login']['value'] != sanitize_user( $data['keymaster_user_login']['value'], true ) ) {
1633
+ $this->strings[3]['form_errors']['keymaster_user_login'][] = 'userlogin';
1634
+ }
1635
+ $data['keymaster_user_login']['value'] = sanitize_user( $data['keymaster_user_login']['value'], true );
1636
+
1637
+ // Check for a valid email
1638
+ $this->strings[3]['form_errors']['keymaster_user_email'][] = empty( $data['keymaster_user_email']['value'] ) ? 'empty' : false;
1639
+ $this->strings[3]['form_errors']['keymaster_user_email'][] = !is_email( $data['keymaster_user_email']['value'] ) ? 'email' : false;
1640
+
1641
+ // Check for a forum name
1642
+ if ( !$this->database_tables_are_installed() ) {
1643
+ $this->strings[3]['form_errors']['forum_name'][] = empty( $data['forum_name']['value'] ) ? 'empty' : false;
1644
+ }
1645
+
1646
+ // Remove empty values from the error array
1647
+ foreach ( $this->strings[3]['form_errors'] as $input => $types ) {
1648
+ $types = array_filter( $types );
1649
+ if ( !count( $types ) ) {
1650
+ unset( $this->strings[3]['form_errors'][$input] );
1651
+ }
1652
+ }
1653
+
1654
+ // Check for errors and build error messages
1655
+ if ( count( $this->strings[3]['form_errors'] ) ) {
1656
+
1657
+ $this->step_status[3] = 'incomplete';
1658
+ $this->strings[3]['messages']['error'][] = __( 'Your site settings have not been processed due to errors with the items marked below.' );
1659
+
1660
+ foreach ( $this->strings[3]['form_errors'] as $input => $types ) {
1661
+ $errors = array();
1662
+
1663
+ foreach ( $types as $type ) {
1664
+ switch ( $type ) {
1665
+ case 'empty':
1666
+ // Only return this error when empty
1667
+ $errors = array( __( '&bull; This value is required to continue.' ) );
1668
+ break(2);
1669
+ case 'urlparse':
1670
+ $errors[] = __( '&bull; This does not appear to be a valid URL.' );
1671
+ break;
1672
+ case 'urlscheme':
1673
+ $errors[] = __( '&bull; The URL must begin with "http" or "https".' );
1674
+ break;
1675
+ case 'urlhost':
1676
+ $errors[] = __( '&bull; The URL does not contain a host name.' );
1677
+ break;
1678
+ case 'userlogin':
1679
+ $errors[] = __( '&bull; Contains disallowed characters which have been removed.' );
1680
+ break;
1681
+ case 'email':
1682
+ $errors[] = __( '&bull; The user email address appears to be invalid.' );
1683
+ break;
1684
+ }
1685
+ }
1686
+
1687
+ $this->strings[3]['form_errors'][$input] = $errors;
1688
+ }
1689
+
1690
+ return 'incomplete';
1691
+ }
1692
+
1693
+ // Stop here if we are going backwards
1694
+ if ( $_POST['back_3_1'] ) {
1695
+ $this->step_status[3] = 'incomplete';
1696
+ return 'incomplete';
1697
+ }
1698
+
1699
+ // If we make it this far we are good to go
1700
+ $this->step_status[3] = 'complete';
1701
+ $this->strings[3]['messages']['message'][] = __( 'Your site settings have been saved and we are now ready to complete the installation. So what are you waiting for?' );
1702
+ return 'complete';
1703
+ }
1704
+
1705
+ /**
1706
+ * Finalises the installation by creating the database and writing all the supplied data to the database.
1707
+ *
1708
+ * @return void
1709
+ **/
1710
+ function process_form_finalise_installation()
1711
+ {
1712
+ require_once( BB_PATH . 'bb-admin/includes/functions.bb-upgrade.php' );
1713
+ require_once( BB_PATH . 'bb-admin/includes/functions.bb-admin.php' );
1714
+
1715
+ $this->inject_form_values_into_data( 2 );
1716
+ $this->inject_form_values_into_data( 3 );
1717
+
1718
+ $data2 =& $this->data[2]['form'];
1719
+ $data3 =& $this->data[3]['form'];
1720
+ $data4 =& $this->data[4]['form'];
1721
+
1722
+ $error_log = array();
1723
+ $installation_log = array();
1724
+
1725
+ // Check the referer
1726
+ bb_check_admin_referer( 'bbpress-installer' );
1727
+ $installation_log[] = __( 'Referrer is OK, beginning installation&hellip;' );
1728
+
1729
+ global $bbdb;
1730
+
1731
+ // Setup user table variables and constants if available
1732
+ if ( $data2['toggle_2_2']['value'] ) {
1733
+
1734
+ $installation_log[] = '>>> ' . __( 'Setting up custom user table constants' );
1735
+
1736
+ global $bb;
1737
+ global $bb_table_prefix;
1738
+
1739
+ if ( !empty( $data2['wp_table_prefix']['value'] ) ) {
1740
+ $bb->wp_table_prefix = $data2['wp_table_prefix']['value'];
1741
+ }
1742
+ if ( !empty( $data2['user_bbdb_name']['value'] ) ) {
1743
+ $bb->user_bbdb_name = $data2['user_bbdb_name']['value'];
1744
+ }
1745
+ if ( !empty( $data2['user_bbdb_user']['value'] ) ) {
1746
+ $bb->user_bbdb_user = $data2['user_bbdb_user']['value'];
1747
+ }
1748
+ if ( !empty( $data2['user_bbdb_password']['value'] ) ) {
1749
+ $bb->user_bbdb_password = $data2['user_bbdb_password']['value'];
1750
+ }
1751
+ if ( !empty( $data2['user_bbdb_host']['value'] ) ) {
1752
+ $bb->user_bbdb_host = $data2['user_bbdb_host']['value'];
1753
+ }
1754
+ if ( !empty( $data2['user_bbdb_charset']['value'] ) ) {
1755
+ $bb->user_bbdb_charset = preg_replace( '/[^a-z0-9_-]/i', '', $data2['user_bbdb_charset']['value'] );
1756
+ }
1757
+ if ( !empty( $data2['user_bbdb_collate']['value'] ) ) {
1758
+ $bb->user_bbdb_collate = preg_replace( '/[^a-z0-9_-]/i', '', $data2['user_bbdb_collate']['value'] );
1759
+ }
1760
+
1761
+ bb_set_custom_user_tables();
1762
+
1763
+ // Add custom user database if required
1764
+ if ( isset( $bb->custom_databases['user'] ) ) {
1765
+ $bbdb->add_db_server( 'user', $bb->custom_databases['user'] );
1766
+ }
1767
+
1768
+ // Add custom tables if required
1769
+ if ( isset( $bb->custom_tables ) ) {
1770
+ $bbdb->tables = array_merge( $bbdb->tables, $bb->custom_tables );
1771
+ if ( is_wp_error( $bbdb->set_prefix( $bb_table_prefix ) ) )
1772
+ die( __( 'Your user table prefix may only contain letters, numbers and underscores.' ) );
1773
+ }
1774
+ }
1775
+
1776
+ // Create the database
1777
+ $installation_log[] = "\n" . __( 'Step 1 - Creating database tables' );
1778
+
1779
+ if ( !$this->database_tables_are_installed() ) {
1780
+ // Hide db errors
1781
+ $bbdb->hide_errors();
1782
+ // Install the database
1783
+ $alterations = bb_install();
1784
+ // Show db errors
1785
+ $bbdb->show_errors();
1786
+
1787
+ if ( isset( $alterations['errors'] ) && is_array( $alterations['errors'] ) ) {
1788
+ $error_log = array_merge( $error_log, $alterations['errors'] );
1789
+ }
1790
+ if ( isset( $alterations['messages'] ) && is_array( $alterations['messages'] ) ) {
1791
+ $installation_log = array_merge( $installation_log, $alterations['messages'] );
1792
+ }
1793
+
1794
+ if ( !$this->database_tables_are_installed() ) {
1795
+ $installation_log[] = '>>> ' . __( 'Database installation failed!!!' );
1796
+ $installation_log[] = '>>>>>> ' . __( 'Halting installation!' );
1797
+ $error_log[] = __( 'Database installation failed!!!' );
1798
+
1799
+ $this->step_status[4] = 'incomplete';
1800
+ $this->strings[4]['h2'] = __( 'Installation failed!' );
1801
+ $this->strings[4]['messages']['error'][] = __( 'The database failed to install. You may need to replace bbPress with a fresh copy and start again.' );
1802
+
1803
+ $data4['installation_log']['value'] = join( "\n", $installation_log );
1804
+ $data4['error_log']['value'] = join( "\n", $error_log );
1805
+
1806
+ return 'incomplete';
1807
+ }
1808
+ } else {
1809
+ $installation_log[] = '>>> ' . __( 'Database is already installed!!!' );
1810
+ }
1811
+
1812
+ // Integration settings passed from step 2
1813
+ // These are already validated provided that the referer checks out
1814
+ $installation_log[] = "\n" . __( 'Step 2 - WordPress integration (optional)' );
1815
+ if ( $data2['toggle_2_0']['value'] ) {
1816
+ if ( $data2['toggle_2_1']['value'] ) {
1817
+ bb_update_option( 'wp_siteurl', $data2['wp_siteurl']['value'] );
1818
+ $installation_log[] = '>>> ' . __( 'WordPress address (URL):' ) . ' ' . $data2['wp_siteurl']['value'];
1819
+
1820
+ bb_update_option( 'wp_home', $data2['wp_home']['value'] );
1821
+ $installation_log[] = '>>> ' . __( 'Blog address (URL):' ) . ' ' . $data2['wp_home']['value'];
1822
+
1823
+ $config_result = $this->write_lines_to_file(
1824
+ BB_PATH . 'bb-config.php',
1825
+ false,
1826
+ array(
1827
+ "define( 'BB_AUTH_KEY" => array( "'" . BB_AUTH_KEY . "'", "'" . $data2['wp_auth_key']['value'] . "'" ),
1828
+ "define( 'BB_SECURE_A" => array( "'" . BB_SECURE_AUTH_KEY . "'", "'" . $data2['wp_secure_auth_key']['value'] . "'" ),
1829
+ "define( 'BB_LOGGED_I" => array( "'" . BB_LOGGED_IN_KEY . "'", "'" . $data2['wp_logged_in_key']['value'] . "'" ),
1830
+ )
1831
+ );
1832
+
1833
+ switch ( $config_result ) {
1834
+ case 1:
1835
+ $installation_log[] = '>>> ' . __( 'WordPress cookie keys set.' );
1836
+ break;
1837
+ default:
1838
+ $error_log[] = '>>> ' . __( 'WordPress cookie keys not set.' );
1839
+ $error_log[] = '>>>>>> ' . __( 'Your "bb-config.php" file was not writable.' );
1840
+ $error_log[] = '>>>>>> ' . __( 'You will need to manually re-define "BB_AUTH_KEY", "BB_SECURE_AUTH_KEY" and "BB_LOGGED_IN_KEY" in your "bb-config.php" file.' );
1841
+ $installation_log[] = '>>> ' . __( 'WordPress cookie keys not set.' );
1842
+ break;
1843
+ }
1844
+
1845
+ if ( !empty( $data2['wp_auth_salt']['value'] ) ) {
1846
+ bb_update_option( 'bb_auth_salt', $data2['wp_auth_salt']['value'] );
1847
+ $installation_log[] = '>>> ' . __( 'WordPress "auth" cookie salt set from input.' );
1848
+ }
1849
+
1850
+ if ( !empty( $data2['wp_secure_auth_salt']['value'] ) ) {
1851
+ bb_update_option( 'bb_secure_auth_salt', $data2['wp_secure_auth_salt']['value'] );
1852
+ $installation_log[] = '>>> ' . __( 'WordPress "secure auth" cookie salt set from input.' );
1853
+ }
1854
+
1855
+ if ( !empty( $data2['wp_logged_in_salt']['value'] ) ) {
1856
+ bb_update_option( 'bb_logged_in_salt', $data2['wp_logged_in_salt']['value'] );
1857
+ $installation_log[] = '>>> ' . __( 'WordPress "logged in" cookie salt set from input.' );
1858
+ }
1859
+ }
1860
+
1861
+ if ( $data2['toggle_2_2']['value'] ) {
1862
+ if (
1863
+ !bb_get_option( 'bb_auth_salt' ) ||
1864
+ !bb_get_option( 'bb_secure_auth_salt' ) ||
1865
+ !bb_get_option( 'bb_logged_in_salt' )
1866
+ ) {
1867
+ $installation_log[] = '>>> ' . __( 'Fetching missing WordPress cookie salts.' );
1868
+
1869
+ $_prefix = $bb->wp_table_prefix;
1870
+ if ( !empty( $data2['wordpress_mu_primary_blog_id']['value'] ) ) {
1871
+ $_prefix .= $data2['wordpress_mu_primary_blog_id']['value'] . '_';
1872
+ }
1873
+
1874
+ if ( isset( $bb->custom_databases['user'] ) ) {
1875
+ $bbdb->tables['options'] = array( 'user', $_prefix . 'options' );
1876
+ } else {
1877
+ $bbdb->tables['options'] = $_prefix . 'options';
1878
+ }
1879
+
1880
+ unset( $_prefix );
1881
+
1882
+ $bbdb->set_prefix( $bb_table_prefix );
1883
+
1884
+ if ( !bb_get_option( 'bb_auth_salt' ) ) {
1885
+ $wp_auth_salt = $bbdb->get_var( "SELECT `option_value` FROM $bbdb->options WHERE `option_name` = 'auth_salt' LIMIT 1" );
1886
+ if ( $wp_auth_salt ) {
1887
+ bb_update_option( 'bb_auth_salt', $wp_auth_salt );
1888
+ $installation_log[] = '>>>>>> ' . __( 'WordPress "auth" cookie salt set.' );
1889
+ } else {
1890
+ $error_log[] = '>>> ' . __( 'WordPress "auth" cookie salt not set.' );
1891
+ $error_log[] = '>>>>>> ' . __( 'Could not fetch "auth" cookie salt from the WordPress options table.' );
1892
+ $error_log[] = '>>>>>> ' . __( 'You will need to manually define the "auth" cookie salt in your database.' );
1893
+ $installation_log[] = '>>>>>> ' . __( 'WordPress "auth" cookie salt not set.' );
1894
+ }
1895
+ }
1896
+
1897
+ if ( !bb_get_option( 'bb_secure_auth_salt' ) ) {
1898
+ $wp_secure_auth_salt = $bbdb->get_var( "SELECT `option_value` FROM $bbdb->options WHERE `option_name` = 'secure_auth_salt' LIMIT 1" );
1899
+ if ( $wp_secure_auth_salt ) {
1900
+ bb_update_option( 'bb_secure_auth_salt', $wp_secure_auth_salt );
1901
+ $installation_log[] = '>>>>>> ' . __( 'WordPress "secure auth" cookie salt set.' );
1902
+ } else {
1903
+ // This cookie salt is sometimes empty so don't error
1904
+ $installation_log[] = '>>>>>> ' . __( 'WordPress "secure auth" cookie salt not set.' );
1905
+ }
1906
+ }
1907
+
1908
+ if ( !bb_get_option( 'bb_logged_in_salt' ) ) {
1909
+ $wp_logged_in_salt = $bbdb->get_var( "SELECT `option_value` FROM $bbdb->options WHERE `option_name` = 'logged_in_salt' LIMIT 1" );
1910
+ if ( $wp_logged_in_salt ) {
1911
+ bb_update_option( 'bb_logged_in_salt', $wp_logged_in_salt );
1912
+ $installation_log[] = '>>>>>> ' . __( 'WordPress "logged in" cookie salt set.' );
1913
+ } else {
1914
+ $error_log[] = '>>> ' . __( 'WordPress "logged in" cookie salt not set.' );
1915
+ $error_log[] = '>>>>>> ' . __( 'Could not fetch "logged in" cookie salt from the WordPress options table.' );
1916
+ $error_log[] = '>>>>>> ' . __( 'You will need to manually define the "logged in" cookie salt in your database.' );
1917
+ $installation_log[] = '>>>>>> ' . __( 'WordPress "logged in" cookie salt not set.' );
1918
+ }
1919
+ }
1920
+ }
1921
+
1922
+ if ( !empty( $data2['wp_table_prefix']['value'] ) ) {
1923
+ bb_update_option( 'wp_table_prefix', $data2['wp_table_prefix']['value'] );
1924
+ $installation_log[] = '>>> ' . __( 'User database table prefix:' ) . ' ' . $data2['wp_table_prefix']['value'];
1925
+ }
1926
+
1927
+ if ( !empty( $data2['wordpress_mu_primary_blog_id']['value'] ) ) {
1928
+ bb_update_option( 'wordpress_mu_primary_blog_id', $data2['wordpress_mu_primary_blog_id']['value'] );
1929
+ $installation_log[] = '>>> ' . __( 'WordPress MU primary blog ID:' ) . ' ' . $data2['wordpress_mu_primary_blog_id']['value'];
1930
+ }
1931
+
1932
+ if ( $data2['toggle_2_3']['value'] ) {
1933
+ if ( !empty( $data2['user_bbdb_name']['value'] ) ) {
1934
+ bb_update_option( 'user_bbdb_name', $data2['user_bbdb_name']['value'] );
1935
+ $installation_log[] = '>>> ' . __( 'User database name:' ) . ' ' . $data2['user_bbdb_name']['value'];
1936
+ }
1937
+ if ( !empty( $data2['user_bbdb_user']['value'] ) ) {
1938
+ bb_update_option( 'user_bbdb_user', $data2['user_bbdb_user']['value'] );
1939
+ $installation_log[] = '>>> ' . __( 'User database user:' ) . ' ' . $data2['user_bbdb_user']['value'];
1940
+ }
1941
+ if ( !empty( $data2['user_bbdb_password']['value'] ) ) {
1942
+ bb_update_option( 'user_bbdb_password', $data2['user_bbdb_password']['value'] );
1943
+ $installation_log[] = '>>> ' . __( 'User database password:' ) . ' ' . $data2['user_bbdb_password']['value'];
1944
+ }
1945
+ if ( !empty( $data2['user_bbdb_host']['value'] ) ) {
1946
+ bb_update_option( 'user_bbdb_host', $data2['user_bbdb_host']['value'] );
1947
+ $installation_log[] = '>>> ' . __( 'User database host:' ) . ' ' . $data2['user_bbdb_host']['value'];
1948
+ }
1949
+ if ( !empty( $data2['user_bbdb_charset']['value'] ) ) {
1950
+ bb_update_option( 'user_bbdb_charset', $data2['user_bbdb_charset']['value'] );
1951
+ $installation_log[] = '>>> ' . __( 'User database character set:' ) . ' ' . $data2['user_bbdb_charset']['value'];
1952
+ }
1953
+ if ( !empty( $data2['user_bbdb_collate']['value'] ) ) {
1954
+ bb_update_option( 'user_bbdb_collate', $data2['user_bbdb_collate']['value'] );
1955
+ $installation_log[] = '>>> ' . __( 'User database collation:' ) . ' ' . $data2['user_bbdb_collate']['value'];
1956
+ }
1957
+ if ( !empty( $data2['custom_user_table']['value'] ) ) {
1958
+ bb_update_option( 'custom_user_table', $data2['custom_user_table']['value'] );
1959
+ $installation_log[] = '>>> ' . __( 'User database "user" table:' ) . ' ' . $data2['custom_user_table']['value'];
1960
+ }
1961
+ if ( !empty( $data2['custom_user_meta_table']['value'] ) ) {
1962
+ bb_update_option( 'custom_user_meta_table', $data2['custom_user_meta_table']['value'] );
1963
+ $installation_log[] = '>>> ' . __( 'User database "user meta" table:' ) . ' ' . $data2['custom_user_meta_table']['value'];
1964
+ }
1965
+ }
1966
+ }
1967
+ } else {
1968
+ $installation_log[] = '>>> ' . __( 'Integration not enabled' );
1969
+ }
1970
+
1971
+ // Site settings passed from step 3
1972
+ // These are already validated provided that the referer checks out
1973
+ $installation_log[] = "\n" . __( 'Step 3 - Site settings' );
1974
+ bb_update_option( 'name', $data3['name']['value'] );
1975
+ $installation_log[] = '>>> ' . __( 'Site name:' ) . ' ' . $data3['name']['value'];
1976
+ bb_update_option( 'uri', $data3['uri']['value'] );
1977
+ $installation_log[] = '>>> ' . __( 'Site address (URL):' ) . ' ' . $data3['uri']['value'];
1978
+ bb_update_option( 'from_email', $data3['keymaster_user_email']['value'] );
1979
+ $installation_log[] = '>>> ' . __( 'From email address:' ) . ' ' . $data3['keymaster_user_email']['value'];
1980
+
1981
+ // Create the key master
1982
+ $keymaster_created = false;
1983
+
1984
+ switch ( $data3['keymaster_user_type']['value'] ) {
1985
+ case 'new':
1986
+
1987
+ // Check to see if the user login already exists
1988
+ if ( $keymaster_user = bb_get_user( $data3['keymaster_user_login']['value'], array( 'by' => 'login' ) ) ) {
1989
+ // The keymaster is an existing bbPress user
1990
+ $installation_log[] = '>>> ' . __( 'Key master could not be created!' );
1991
+ $installation_log[] = '>>>>>> ' . __( 'That login is already taken!' );
1992
+ $error_log[] = __( 'Key master could not be created!' );
1993
+
1994
+ if ( $keymaster_user->bb_capabilities['keymaster'] ) {
1995
+ // The existing user is a key master - continue
1996
+ $bb_current_user = bb_set_current_user( $keymaster_user->ID );
1997
+ $installation_log[] = '>>>>>> ' . __( 'Existing key master entered!' );
1998
+ $data4['keymaster_user_password']['value'] = __( 'Your bbPress password' );
1999
+ $data3['keymaster_user_email']['value'] = $keymaster_user->user_email;
2000
+ bb_update_option( 'from_email', $keymaster_user->user_email);
2001
+ $installation_log[] = '>>>>>> ' . __( 'Re-setting admin email address.' );
2002
+ $keymaster_created = true;
2003
+ } else {
2004
+ // The existing user is a non-key master user - halt installation
2005
+ $installation_log[] = '>>>>>> ' . __( 'Existing user without key master role entered!' );
2006
+ $installation_log[] = '>>>>>>>>> ' . __( 'Halting installation!' );
2007
+ $this->step_status[4] = 'incomplete';
2008
+ $this->strings[4]['h2'] = __( 'Installation failed!' );
2009
+ $this->strings[4]['messages']['error'][] = __( 'The key master could not be created. An existing user was found with that user login.' );
2010
+
2011
+ $data4['installation_log']['value'] = join( "\n", $installation_log );
2012
+ $data4['error_log']['value'] = join( "\n", $error_log );
2013
+
2014
+ return 'incomplete';
2015
+ }
2016
+
2017
+ break;
2018
+ }
2019
+
2020
+ // Helper function to let us know the password that was created
2021
+ global $keymaster_password;
2022
+ function bb_get_keymaster_password( $user_id, $pass ) {
2023
+ global $keymaster_password;
2024
+ $keymaster_password = $pass;
2025
+ }
2026
+ add_action( 'bb_new_user', 'bb_get_keymaster_password', 10, 2 );
2027
+
2028
+ // Create the new user (automattically given key master role when BB_INSTALLING is true)
2029
+ if ( $keymaster_user_id = bb_new_user( $data3['keymaster_user_login']['value'], $data3['keymaster_user_email']['value'], '' ) ) {
2030
+ $bb_current_user = bb_set_current_user( $keymaster_user_id );
2031
+ $data4['keymaster_user_password']['value'] = $keymaster_password;
2032
+ $installation_log[] = '>>> ' . __( 'Key master created' );
2033
+ $installation_log[] = '>>>>>> ' . __( 'Username:' ) . ' ' . $data3['keymaster_user_login']['value'];
2034
+ $installation_log[] = '>>>>>> ' . __( 'Email address:' ) . ' ' . $data3['keymaster_user_email']['value'];
2035
+ $installation_log[] = '>>>>>> ' . __( 'Password:' ) . ' ' . $data4['keymaster_user_password']['value'];
2036
+ $keymaster_created = true;
2037
+ } else {
2038
+ $installation_log[] = '>>> ' . __( 'Key master could not be created!' );
2039
+ $installation_log[] = '>>>>>> ' . __( 'Halting installation!' );
2040
+ $error_log[] = __( 'Key master could not be created!' );
2041
+ $this->step_status[4] = 'incomplete';
2042
+ $this->strings[4]['h2'] = __( 'Installation failed!' );
2043
+ $this->strings[4]['messages']['error'][] = __( 'The key master could not be created. You may need to replace bbPress with a fresh copy and start again.' );
2044
+
2045
+ $data4['installation_log']['value'] = join( "\n", $installation_log );
2046
+ $data4['error_log']['value'] = join( "\n", $error_log );
2047
+
2048
+ return 'incomplete';
2049
+ }
2050
+ break;
2051
+
2052
+ case 'old':
2053
+ if ( $keymaster_user = bb_get_user( $data3['keymaster_user_login']['value'], array( 'by' => 'login' ) ) ) {
2054
+ // The keymaster is an existing bbPress or WordPress user
2055
+ $bb_current_user = bb_set_current_user( $keymaster_user->ID );
2056
+ $bb_current_user->set_role( 'keymaster' );
2057
+ $data4['keymaster_user_password']['value'] = __( 'Your existing password' );
2058
+ $installation_log[] = '>>> ' . __( 'Key master role assigned to existing user' );
2059
+ $installation_log[] = '>>>>>> ' . __( 'Username:' ) . ' ' . $data3['keymaster_user_login']['value'];
2060
+ $installation_log[] = '>>>>>> ' . __( 'Email address:' ) . ' ' . $data3['keymaster_user_email']['value'];
2061
+ $installation_log[] = '>>>>>> ' . __( 'Password:' ) . ' ' . $data4['keymaster_user_password']['value'];
2062
+ $keymaster_created = true;
2063
+ } else {
2064
+ $installation_log[] = '>>> ' . __( 'Key master role could not be assigned to existing user!' );
2065
+ $installation_log[] = '>>>>>> ' . __( 'Halting installation!' );
2066
+ $error_log[] = __( 'Key master could not be created!' );
2067
+ $this->step_status[4] = 'incomplete';
2068
+ $this->strings[4]['h2'] = __( 'Installation failed!' );
2069
+ $this->strings[4]['messages']['error'][] = __( 'The key master could not be assigned. You may need to replace bbPress with a fresh copy and start again.' );
2070
+
2071
+ $data4['installation_log']['value'] = join( "\n", $installation_log );
2072
+ $data4['error_log']['value'] = join( "\n", $error_log );
2073
+
2074
+ return 'incomplete';
2075
+ }
2076
+ break;
2077
+ }
2078
+
2079
+ // Don't create an initial forum if any forums already exist
2080
+ if (!$bbdb->get_results( 'SELECT `forum_id` FROM `' . $bbdb->forums . '` LIMIT 1;' ) ) {
2081
+ if ( $this->language != BB_LANG) {
2082
+ global $locale, $l10n;
2083
+ $locale = BB_LANG;
2084
+ unset( $l10n['default'] );
2085
+ bb_load_default_textdomain();
2086
+ }
2087
+
2088
+ $description = __( 'Just another bbPress community' );
2089
+ bb_update_option( 'description', $description);
2090
+
2091
+ if ( $this->language != BB_LANG) {
2092
+ $locale = $this->language;
2093
+ unset( $l10n['default'] );
2094
+ bb_load_default_textdomain();
2095
+ }
2096
+
2097
+ $installation_log[] = '>>> ' . __( 'Description:' ) . ' ' . $description;
2098
+
2099
+ if ( $forum_id = bb_new_forum( array( 'forum_name' => $data3['forum_name']['value'] ) ) ) {
2100
+ $installation_log[] = '>>> ' . __( 'Forum name:' ) . ' ' . $data3['forum_name']['value'];
2101
+
2102
+ if ( $this->language != BB_LANG) {
2103
+ $locale = BB_LANG;
2104
+ unset( $l10n['default'] );
2105
+ bb_load_default_textdomain();
2106
+ }
2107
+
2108
+ $topic_title = __( 'Your first topic' );
2109
+ $topic_id = bb_insert_topic(
2110
+ array(
2111
+ 'topic_title' => $topic_title,
2112
+ 'forum_id' => $forum_id,
2113
+ 'tags' => 'bbPress'
2114
+ )
2115
+ );
2116
+ $post_text = __( 'First Post! w00t.' );
2117
+ bb_insert_post(
2118
+ array(
2119
+ 'topic_id' => $topic_id,
2120
+ 'post_text' => $post_text
2121
+ )
2122
+ );
2123
+
2124
+ if ( $this->language != BB_LANG ) {
2125
+ $locale = $this->language;
2126
+ unset( $l10n['default'] );
2127
+ bb_load_default_textdomain();
2128
+ }
2129
+
2130
+ $installation_log[] = '>>>>>> ' . __( 'Topic:' ) . ' ' . $topic_title;
2131
+ $installation_log[] = '>>>>>>>>> ' . __( 'Post:' ) . ' ' . $post_text;
2132
+ } else {
2133
+ $installation_log[] = '>>> ' . __( 'Forum could not be created!' );
2134
+ $error_log[] = __( 'Forum could not be created!' );
2135
+ }
2136
+ } else {
2137
+ $installation_log[] = '>>> ' . __( 'There are existing forums in this database.' );
2138
+ $installation_log[] = '>>>>>> ' . __( 'No new forum created.' );
2139
+ $error_log[] = __( 'Forums already exist!' );
2140
+ }
2141
+
2142
+ if ( defined( 'BB_PLUGIN_DIR' ) && BB_PLUGIN_DIR && !file_exists( BB_PLUGIN_DIR ) ) {
2143
+ // Just suppress errors as this is not critical
2144
+ if ( @mkdir( BB_PLUGIN_DIR, 0750 ) ) {
2145
+ $installation_log[] = '>>> ' . sprintf( __( 'Making plugin directory at %s.' ), BB_PLUGIN_DIR );
2146
+ }
2147
+ }
2148
+
2149
+ if ( defined( 'BB_THEME_DIR' ) && BB_THEME_DIR && !file_exists( BB_THEME_DIR ) ) {
2150
+ // Just suppress errors as this is not critical
2151
+ if ( @mkdir( BB_THEME_DIR, 0750 ) ) {
2152
+ $installation_log[] = '>>> ' . sprintf( __( 'Making theme directory at %s.' ), BB_THEME_DIR );
2153
+ }
2154
+ }
2155
+
2156
+ if ( $keymaster_created ) {
2157
+ $keymaster_email_message = sprintf(
2158
+ __( "Your new bbPress site has been successfully set up at:\n\n%1\$s\n\nYou can log in to the key master account with the following information:\n\nUsername: %2\$s\nPassword: %3\$s\n\nWe hope you enjoy your new forums. Thanks!\n\n--The bbPress Team\nhttp://bbpress.org/" ),
2159
+ bb_get_uri( null, null, BB_URI_CONTEXT_TEXT ),
2160
+ $data3['keymaster_user_login']['value'],
2161
+ $data4['keymaster_user_password']['value']
2162
+ );
2163
+
2164
+ if ( bb_mail( $data3['keymaster_user_email']['value'], __( 'New bbPress installation' ), $keymaster_email_message ) ) {
2165
+ $installation_log[] = '>>> ' . __( 'Key master email sent' );
2166
+ } else {
2167
+ $installation_log[] = '>>> ' . __( 'Key master email not sent!' );
2168
+ $error_log[] = __( 'Key master email not sent!' );
2169
+ }
2170
+ }
2171
+
2172
+ if ( count( $error_log ) ) {
2173
+ $this->strings[4]['h2'] = __( 'Installation completed with some errors!' );
2174
+ $this->strings[4]['messages']['error'][] = __( 'Your installation completed with some minor errors. See the error log below for more specific information.' );
2175
+ $installation_log[] = "\n" . __( 'There were some errors encountered during installation!' );
2176
+ } else {
2177
+ $this->strings[4]['messages']['message'][] = __( 'Your installation completed successfully.' );
2178
+ $installation_log[] = "\n" . __( 'Installation complete!' );
2179
+ }
2180
+
2181
+ $this->step_status[4] = 'complete';
2182
+
2183
+ $data4['installation_log']['value'] = join( "\n", $installation_log );
2184
+ $data4['error_log']['value'] = join( "\n", $error_log );
2185
+
2186
+ return 'complete';
2187
+ }
2188
+
2189
+ /**
2190
+ * Prints a text input form element.
2191
+ *
2192
+ * @param $key string The key of the data to populate the element with.
2193
+ * @param $direction string Optional. The text direction, only 'ltr' or 'rtl' are acceptable.
2194
+ * @return void
2195
+ **/
2196
+ function input_text( $key, $direction = false )
2197
+ {
2198
+ $data = $this->data[$this->step]['form'][$key];
2199
+
2200
+ $class = '';
2201
+ $classes = array();
2202
+ if ( isset( $data['note'] ) ) {
2203
+ $classes[] = 'has-note';
2204
+ }
2205
+ if ( isset( $data['label'] ) ) {
2206
+ $classes[] = 'has-label';
2207
+ }
2208
+
2209
+ if ( isset( $this->data[$this->step]['form'][$key]['type'] ) ) {
2210
+ $type = $this->data[$this->step]['form'][$key]['type'];
2211
+ } else {
2212
+ $type = 'text';
2213
+ }
2214
+ $classes[] = 'for-input-' . $type;
2215
+
2216
+ if ( isset( $this->strings[$this->step]['form_errors'][$key] ) ) {
2217
+ $classes[] = 'error';
2218
+ }
2219
+ if ( count( $classes ) ) {
2220
+ $class = ' class="' . join( ' ', $classes ) . '"';
2221
+ }
2222
+
2223
+ $r = "\t" . '<label id="label-' . esc_attr( $key ) . '" for="' . esc_attr( $key ) . '"' . $class . '>' . "\n";
2224
+
2225
+ if ( isset( $data['label'] ) ) {
2226
+ $r .= "\t\t" . '<span>' . $data['label'] . '</span>' . "\n";
2227
+ }
2228
+
2229
+ if ( isset( $this->strings[$this->step]['form_errors'][$key] ) ) {
2230
+ foreach ( $this->strings[$this->step]['form_errors'][$key] as $error ) {
2231
+ if ( !is_bool( $error ) ) {
2232
+ $r .= "\t\t" . '<span class="error">' . $error . '</span>' . "\n";
2233
+ }
2234
+ }
2235
+ }
2236
+
2237
+ if ( isset( $data['maxlength'] ) && is_integer( $data['maxlength'] ) ) {
2238
+ $maxlength = ' maxlength="' . esc_attr( $data['maxlength'] ) . '"';
2239
+ }
2240
+
2241
+ if ( $direction && in_array( strtolower( $direction ), array( 'ltr', 'rtl' ) ) ) {
2242
+ $direction = ' dir="' . esc_attr( strtolower( $direction ) ) . '"';
2243
+ }
2244
+
2245
+ if ( isset( $data['autocomplete'] ) ) {
2246
+ $autocomplete = ' autocomplete="' . esc_attr( $data['autocomplete'] ) . '"';
2247
+ } else {
2248
+ $autocomplete = '';
2249
+ }
2250
+
2251
+ $this->tabindex++;
2252
+ $r .= "\t\t" . '<input' . $direction . ' type="' . esc_attr( $type ) . '" id="' . esc_attr( $key ) . '" name="' . esc_attr( $key ) . '" class="text' . $has_note_class . '" value="' . esc_attr( $data['value'] ) . '"' . $maxlength . $autocomplete . ' tabindex="' . $this->tabindex . '" />' . "\n";
2253
+
2254
+ if ( isset( $data['note'] ) ) {
2255
+ $r .= "\t\t" . '<a class="note-toggle" href="javascript:void(0);" onclick="toggleNote(\'note-' . esc_attr( $key ) . '\');">?</a>' . "\n";
2256
+ $r .= "\t\t" . '<p id="note-' . esc_attr( $key ) . '" class="note" style="display:none">' . $data['note'] . '</p>' . "\n";
2257
+ }
2258
+
2259
+ $r .= "\t\t" . '<div class="clear"></div>' . "\n";
2260
+ $r .= "\t" . '</label>' . "\n";
2261
+
2262
+ echo $r;
2263
+ }
2264
+
2265
+ /**
2266
+ * Prints a hidden input form element.
2267
+ *
2268
+ * @param $key string The key of the data to populate the element with.
2269
+ * @return void
2270
+ **/
2271
+ function input_hidden( $key )
2272
+ {
2273
+ $r = "\t" . '<input type="hidden" id="' . esc_attr( $key ) . '" name="' . esc_attr( $key ) . '" value="' . esc_attr( $this->data[$this->step]['form'][$key]['value'] ) . '" />' . "\n";
2274
+
2275
+ echo $r;
2276
+ }
2277
+
2278
+ /**
2279
+ * Prints a textarea form element.
2280
+ *
2281
+ * @param $key string The key of the data to populate the element with.
2282
+ * @param $direction string Optional. The text direction, only 'ltr' or 'rtl' are acceptable.
2283
+ * @return void
2284
+ **/
2285
+ function textarea( $key, $direction = false)
2286
+ {
2287
+ $data = $this->data[$this->step]['form'][$key];
2288
+
2289
+ $class = '';
2290
+ $classes = array( 'for-textarea' );
2291
+ if ( isset( $data['note'] ) ) {
2292
+ $classes[] = 'has-note';
2293
+ }
2294
+ if ( isset( $data['label'] ) ) {
2295
+ $classes[] = 'has-label';
2296
+ }
2297
+ if ( count( $classes ) ) {
2298
+ $class = ' class="' . join( ' ', $classes ) . '"';
2299
+ }
2300
+
2301
+ $r = "\t" . '<label id="label-' . esc_attr( $key ) . '"' . $class . ' for="' . esc_attr( $key ) . '">' . "\n";
2302
+
2303
+ if ( isset( $data['label'] ) ) {
2304
+ $r .= "\t\t" . '<span>' . $data['label'] . '</span>' . "\n";
2305
+ }
2306
+
2307
+ if ( isset( $data['note'] ) ) {
2308
+ $r .= "\t\t" . '<a class="note-toggle" href="javascript:void(0);" onclick="toggleNote(\'note-' . esc_attr( $key ) . '\');">?</a>' . "\n";
2309
+ $r .= "\t\t" . '<p id="note-' . esc_attr( $key ) . '" class="note" style="display:none">' . $data['note'] . '</p>' . "\n";
2310
+ }
2311
+
2312
+ if ( $direction && in_array( strtolower( $direction ), array( 'ltr', 'rtl' ) ) ) {
2313
+ $direction = ' dir="' . esc_attr( strtolower( $direction ) ) . '"';
2314
+ }
2315
+
2316
+ $this->tabindex++;
2317
+ $r .= "\t\t" . '<textarea id="' . esc_attr( $key ) . '" rows="5" cols="30"' . $direction . ' tabindex="' . $this->tabindex . '">' . esc_html( $data['value'] ) . '</textarea>' . "\n";
2318
+
2319
+ $r .= "\t" . '</label>' . "\n";
2320
+
2321
+ echo $r;
2322
+ }
2323
+
2324
+ /**
2325
+ * Prints a select form element populated with options.
2326
+ *
2327
+ * @param $key string The key of the data to populate the element with.
2328
+ * @return void
2329
+ **/
2330
+ function select( $key )
2331
+ {
2332
+ $data = $this->data[$this->step]['form'][$key];
2333
+
2334
+ $class = '';
2335
+ $classes = array( 'for-select' );
2336
+ if ( isset( $data['note'] ) ) {
2337
+ $classes[] = 'has-note';
2338
+ }
2339
+ if ( isset( $data['label'] ) ) {
2340
+ $classes[] = 'has-label';
2341
+ }
2342
+ if ( count( $classes ) ) {
2343
+ $class = ' class="' . join( ' ', $classes ) . '"';
2344
+ }
2345
+
2346
+ $r = "\t" . '<label id="label-' . esc_attr( $key ) . '"' . $class . ' for="' . esc_attr( $key ) . '">' . "\n";
2347
+
2348
+ if ( isset( $data['label'] ) ) {
2349
+ $r .= "\t\t" . '<span>' . $data['label'] . '</span>' . "\n";
2350
+ }
2351
+
2352
+ if ( isset( $data['options'] ) ) {
2353
+ $r .= "\t\t" . '<select id="' . esc_attr( $key ) . '" name="' . esc_attr( $key ) . '"';
2354
+ if ( isset( $data['onchange'] ) ) {
2355
+ $r .= ' onchange="' . esc_attr( $data['onchange'] ) . '"';
2356
+ }
2357
+ $this->tabindex++;
2358
+ $r .= ' tabindex="' . $this->tabindex . '">' . "\n";
2359
+
2360
+ foreach ( $data['options'] as $value => $display ) {
2361
+ if ( $data['value'] == $value ) {
2362
+ $selected = ' selected="selected"';
2363
+ } else {
2364
+ $selected = '';
2365
+ }
2366
+
2367
+ $r .= "\t\t\t" . '<option value="' . esc_attr( $value ) . '"' . $selected . '>' . esc_html( $display ) . '</option>' . "\n";
2368
+ }
2369
+
2370
+ $r .= "\t\t" . '</select>';
2371
+ }
2372
+
2373
+ if ( isset( $data['note'] ) ) {
2374
+ $r .= "\t\t" . '<a class="note-toggle" href="javascript:void(0);" onclick="toggleNote(\'note-' . esc_attr( $key ) . '\');">?</a>' . "\n";
2375
+ $r .= "\t\t" . '<p id="note-' . esc_attr( $key ) . '" class="note" style="display:none">' . $data['note'] . '</p>' . "\n";
2376
+ }
2377
+
2378
+ $r .= "\t\t" . '<div class="clear"></div>' . "\n";
2379
+ $r .= "\t" . '</label>' . "\n";
2380
+
2381
+ echo $r;
2382
+ }
2383
+
2384
+ /**
2385
+ * Prints an appropriate language selection form element if there are any available.
2386
+ *
2387
+ * @return void
2388
+ **/
2389
+ function select_language()
2390
+ {
2391
+ if ( count( $this->languages ) > 1 ) {
2392
+ $this->data[1]['form']['bb_lang']['value'] = $this->language;
2393
+ $this->data[1]['form']['bb_lang']['options'] = $this->languages;
2394
+ $this->select( 'bb_lang' );
2395
+ } else {
2396
+ $this->data[1]['form']['bb_lang']['value'] = 'en_US';
2397
+ $this->input_hidden( 'bb_lang' );
2398
+ }
2399
+ }
2400
+
2401
+ /**
2402
+ * Prints an input checkbox which controls display of an optional section of settings.
2403
+ *
2404
+ * @param string $key The identifier of the area to be toggled.
2405
+ * @return void
2406
+ **/
2407
+ function input_toggle( $key )
2408
+ {
2409
+ $data = $this->data[$this->step]['form'][$key];
2410
+
2411
+ $class = '';
2412
+ $classes = array( 'for-toggle' );
2413
+ if ( isset( $data['note'] ) ) {
2414
+ $classes[] = 'has-note';
2415
+ }
2416
+ if ( isset( $data['label'] ) ) {
2417
+ $classes[] = 'has-label';
2418
+ }
2419
+
2420
+ $onclick = 'toggleBlock(this, \'' . esc_js( $key . '_target' ) . '\' );';
2421
+ if ( isset( $data['toggle_value'] ) ) {
2422
+ $onclick .= ' toggleValue(this, \'' . esc_js( $data['toggle_value']['target'] ) . '\', \'' . esc_js( $data['toggle_value']['off_value'] ) . '\', \'' . esc_js( $data['toggle_value']['on_value'] ) . '\' );';
2423
+ }
2424
+
2425
+ $checked = $data['checked'] ? ' ' . trim( $data['checked'] ) : '';
2426
+
2427
+ if ( isset( $this->strings[$this->step]['form_errors'][$key] ) ) {
2428
+ $classes[] = 'error';
2429
+ }
2430
+ if ( count( $classes ) ) {
2431
+ $class = ' class="' . join( ' ', $classes ) . '"';
2432
+ }
2433
+
2434
+ $r = "\t" . '<label id="label-' . esc_attr( $key ) . '"' . $class . ' for="' . esc_attr( $key ) . '">' . "\n";
2435
+
2436
+ $r .= "\t\t" . '<span>' . "\n";
2437
+ $this->tabindex++;
2438
+ $r .= "\t\t\t" . '<input type="checkbox" id="' . esc_attr( $key ) . '" name="' . esc_attr( $key ) . '" class="checkbox" onclick="' . esc_attr( $onclick ) . '"' . $checked . ' value="1" tabindex="' . $this->tabindex . '" />' . "\n";
2439
+ if ( isset( $data['label'] ) ) {
2440
+ $r .= "\t\t\t" . $data['label'] . "\n";
2441
+ }
2442
+ $r .= "\t\t" . '</span>' . "\n";
2443
+
2444
+ if ( isset( $data['note'] ) ) {
2445
+ $r .= "\t\t" . '<a class="note-toggle" href="javascript:void(0);" onclick="toggleNote(\'note-' . esc_attr( $key ) . '\');">?</a>' . "\n";
2446
+ $r .= "\t\t" . '<p id="note-' . esc_attr( $key ) . '" class="note" style="display:none">' . $data['note'] . '</p>' . "\n";
2447
+ }
2448
+
2449
+ $r .= "\t\t" . '<div class="clear"></div>' . "\n";
2450
+ $r .= "\t" . '</label>' . "\n";
2451
+
2452
+ echo $r;
2453
+ }
2454
+
2455
+ /**
2456
+ * Prints the input buttons which post each step and optionally go back a step.
2457
+ *
2458
+ * @param string $forward The HTML element ID of the forward button.
2459
+ * @param string $back Optional. The HTML element ID of the back button.
2460
+ * @return void
2461
+ **/
2462
+ function input_buttons( $forward, $back = false, $step = false )
2463
+ {
2464
+ $data_back = $back ? $this->data[$this->step]['form'][$back] : false;
2465
+ $data_forward = $this->data[$this->step]['form'][$forward];
2466
+
2467
+ $r = '<fieldset class="buttons">' . "\n";
2468
+
2469
+ if ( !$step ) {
2470
+ $step = $this->step;
2471
+ }
2472
+ $r .= "\t" . '<input type="hidden" id="step" name="step" value="' . (int) $step . '" />' . "\n";
2473
+
2474
+ if ( $back) {
2475
+ $r .= "\t" . '<label id="label-' . esc_attr( $back ) . '" for="' . esc_attr( $back ) . '" class="back">' . "\n";
2476
+ $this->tabindex++;
2477
+ $r .= "\t\t" . '<input type="submit" id="' . esc_attr( $back ) . '" name="' . esc_attr( $back ) . '" class="button" value="' . esc_attr( $data_back['value'] ) . '" tabindex="' . $this->tabindex . '" />' . "\n";
2478
+ $r .= "\t" . '</label>' . "\n";
2479
+ }
2480
+
2481
+ $r .= "\t" . '<label id="label-' . esc_attr( $forward ) . '" for="' . esc_attr( $forward ) . '" class="forward">' . "\n";
2482
+ $this->tabindex++;
2483
+ $r .= "\t\t" . '<input type="submit" id="' . esc_attr( $forward ) . '" name="' . esc_attr( $forward ) . '" class="button" value="' . esc_attr( $data_forward['value'] ) . '" tabindex="' . $this->tabindex . '" />' . "\n";
2484
+ $r .= "\t" . '</label>' . "\n";
2485
+
2486
+ $r .= '</fieldset>' . "\n";
2487
+
2488
+ echo $r;
2489
+ }
2490
+
2491
+ /**
2492
+ * Prints hidden input elements containing the data inputted in a given step.
2493
+ *
2494
+ * @param integer $step Optional. The number of the step whose hidden inputs should be printed.
2495
+ * @return void
2496
+ **/
2497
+ function hidden_step_inputs( $step = false )
2498
+ {
2499
+ if ( !$step ) {
2500
+ $step = $this->step;
2501
+ } elseif ( $step !== $this->step ) {
2502
+ $this->inject_form_values_into_data( $step );
2503
+ }
2504
+
2505
+ $data = $this->data[$step]['form'];
2506
+
2507
+ $r = '<fieldset>' . "\n";
2508
+
2509
+ foreach ( $data as $key => $value ) {
2510
+ if ( 'forward_' !== substr( $key, 0, 8 ) && 'back_' !== substr( $key, 0, 5 ) ) {
2511
+ $r .= "\t" . '<input type="hidden" name="' . esc_attr( $key ) . '" value="' . esc_attr( $value['value'] ) . '" />' . "\n";
2512
+ }
2513
+ }
2514
+
2515
+ $r .= '</fieldset>' . "\n";
2516
+
2517
+ echo $r;
2518
+ }
2519
+
2520
+ /**
2521
+ * Rewrites the admin user input into a select element containing existing WordPress administrators.
2522
+ *
2523
+ * @return boolean True if the select element was created, otherwise false.
2524
+ **/
2525
+ function populate_keymaster_user_login_from_user_tables()
2526
+ {
2527
+ $data =& $this->data[3]['form']['keymaster_user_login'];
2528
+
2529
+ // Get the existing WordPress admin users
2530
+
2531
+ // Setup variables and constants if available
2532
+ global $bb;
2533
+ if ( !empty( $this->data[2]['form']['wp_table_prefix']['value'] ) ) {
2534
+ $bb->wp_table_prefix = $this->data[2]['form']['wp_table_prefix']['value'];
2535
+ }
2536
+ if ( !empty( $this->data[2]['form']['user_bbdb_name']['value'] ) ) {
2537
+ $bb->user_bbdb_name = $this->data[2]['form']['user_bbdb_name']['value'];
2538
+ }
2539
+ if ( !empty( $this->data[2]['form']['user_bbdb_user']['value'] ) ) {
2540
+ $bb->user_bbdb_user = $this->data[2]['form']['user_bbdb_user']['value'];
2541
+ }
2542
+ if ( !empty( $this->data[2]['form']['user_bbdb_password']['value'] ) ) {
2543
+ $bb->user_bbdb_password = $this->data[2]['form']['user_bbdb_password']['value'];
2544
+ }
2545
+ if ( !empty( $this->data[2]['form']['user_bbdb_host']['value'] ) ) {
2546
+ $bb->user_bbdb_host = $this->data[2]['form']['user_bbdb_host']['value'];
2547
+ }
2548
+ if ( !empty( $this->data[2]['form']['user_bbdb_charset']['value'] ) ) {
2549
+ $bb->user_bbdb_charset = preg_replace( '/[^a-z0-9_-]/i', '', $this->data[2]['form']['user_bbdb_charset']['value'] );
2550
+ }
2551
+ if ( !empty( $this->data[2]['form']['user_bbdb_collate']['value'] ) ) {
2552
+ $bb->user_bbdb_charset = preg_replace( '/[^a-z0-9_-]/i', '', $this->data[2]['form']['user_bbdb_collate']['value'] );
2553
+ }
2554
+ if ( !empty( $this->data[2]['form']['custom_user_table']['value'] ) ) {
2555
+ $bb->custom_user_table = preg_replace( '/[^a-z0-9_-]/i', '', $this->data[2]['form']['custom_user_table']['value'] );
2556
+ }
2557
+ if ( !empty( $this->data[2]['form']['custom_user_meta_table']['value'] ) ) {
2558
+ $bb->custom_user_meta_table = preg_replace( '/[^a-z0-9_-]/i', '', $this->data[2]['form']['custom_user_meta_table']['value'] );
2559
+ }
2560
+
2561
+ global $bbdb;
2562
+ global $bb_table_prefix;
2563
+
2564
+ // Resolve the custom user tables for bpdb
2565
+ bb_set_custom_user_tables();
2566
+
2567
+ if ( isset( $bb->custom_databases ) && isset( $bb->custom_databases['user'] ) ) {
2568
+ $bbdb->add_db_server( 'user', $bb->custom_databases['user'] );
2569
+ }
2570
+
2571
+ // Add custom tables if required
2572
+ if ( isset( $bb->custom_tables['users'] ) || isset( $bb->custom_tables['usermeta'] ) ) {
2573
+ $bbdb->tables = array_merge( $bbdb->tables, $bb->custom_tables );
2574
+ if ( is_wp_error( $bbdb->set_prefix( $bb_table_prefix ) ) ) {
2575
+ die( __( 'Your user table prefix may only contain letters, numbers and underscores.' ) );
2576
+ }
2577
+ }
2578
+
2579
+ $bb_keymaster_meta_key = $bbdb->escape( $bb_table_prefix . 'capabilities' );
2580
+ $wp_administrator_meta_key = $bbdb->escape( $bb->wp_table_prefix . 'capabilities' );
2581
+ if ( !empty( $this->data[2]['form']['wordpress_mu_primary_blog_id']['value'] ) ) {
2582
+ $wp_administrator_meta_key = $bb->wp_table_prefix . $this->data[2]['form']['wordpress_mu_primary_blog_id']['value'] . '_capabilities';
2583
+ }
2584
+
2585
+ $keymaster_query = <<<EOQ
2586
+ SELECT
2587
+ user_login, user_email, display_name
2588
+ FROM
2589
+ $bbdb->users
2590
+ LEFT JOIN
2591
+ $bbdb->usermeta ON
2592
+ $bbdb->users.ID = $bbdb->usermeta.user_id
2593
+ WHERE
2594
+ (
2595
+ (
2596
+ meta_key = '$wp_administrator_meta_key' AND
2597
+ meta_value LIKE '%administrator%'
2598
+ ) OR
2599
+ (
2600
+ meta_key = '$bb_keymaster_meta_key' AND
2601
+ meta_value LIKE '%keymaster%'
2602
+ )
2603
+ ) AND
2604
+ user_email IS NOT NULL AND
2605
+ user_email != ''
2606
+ ORDER BY
2607
+ user_login;
2608
+ EOQ;
2609
+ $bbdb->suppress_errors();
2610
+
2611
+ if ( $keymasters = $bbdb->get_results( $keymaster_query, ARRAY_A ) ) {
2612
+
2613
+ $bbdb->suppress_errors( false );
2614
+
2615
+ if ( count( $keymasters ) ) {
2616
+ $email_maps = '';
2617
+ $data['options'] = array();
2618
+ $data['onchange'] = 'changeKeymasterEmail( this, \'keymaster_user_email\' );';
2619
+ $data['note'] = __( 'Please select an existing bbPress Keymaster or WordPress administrator.' );
2620
+
2621
+ $data['options'][''] = '';
2622
+ foreach ( $keymasters as $keymaster ) {
2623
+ $email_maps .= 'emailMap[\'' . $keymaster['user_login'] . '\'] = \'' . $keymaster['user_email'] . '\';' . "\n\t\t\t\t\t\t\t\t";
2624
+ if ( $keymaster['display_name'] ) {
2625
+ $data['options'][$keymaster['user_login']] = $keymaster['user_login'] . ' (' . $keymaster['display_name'] . ')';
2626
+ } else {
2627
+ $data['options'][$keymaster['user_login']] = $keymaster['user_login'];
2628
+ }
2629
+ }
2630
+
2631
+ $this->strings[3]['scripts']['changeKeymasterEmail'] = <<<EOS
2632
+ <script type="text/javascript" charset="utf-8">
2633
+ function changeKeymasterEmail( selectObj, target ) {
2634
+ var emailMap = new Array;
2635
+ emailMap[''] = '';
2636
+ $email_maps
2637
+ var targetObj = document.getElementById( target );
2638
+ var selectedAdmin = selectObj.options[selectObj.selectedIndex].value;
2639
+ targetObj.value = emailMap[selectedAdmin];
2640
+ }
2641
+ </script>
2642
+ EOS;
2643
+
2644
+ $this->data[3]['form']['keymaster_user_type']['value'] = 'old';
2645
+
2646
+ return true;
2647
+ }
2648
+ }
2649
+
2650
+ $bbdb->suppress_errors( false );
2651
+
2652
+ return false;
2653
+ }
2654
+
2655
+ /**
2656
+ * Sends HTTP headers and prints the page header.
2657
+ *
2658
+ * @return void
2659
+ **/
2660
+ function header()
2661
+ {
2662
+ nocache_headers();
2663
+
2664
+ bb_install_header( $this->strings[$this->step]['title'], $this->strings[$this->step]['h1'], true );
2665
+ }
2666
+
2667
+ /**
2668
+ * Prints the page footer.
2669
+ *
2670
+ * @return void
2671
+ **/
2672
+ function footer()
2673
+ {
2674
+ bb_install_footer();
2675
+ }
2676
+
2677
+ /**
2678
+ * Prints the returned messages for the current step.
2679
+ *
2680
+ * @return void
2681
+ **/
2682
+ function messages()
2683
+ {
2684
+ if ( isset( $this->strings[$this->step]['messages'] ) ) {
2685
+ $messages = $this->strings[$this->step]['messages'];
2686
+
2687
+ // This count works as long as $messages is only two-dimensional
2688
+ $count = ( count( $messages, COUNT_RECURSIVE ) - count( $messages ) );
2689
+ $i = 0;
2690
+ $r = '';
2691
+ foreach ( $messages as $type => $paragraphs ) {
2692
+ $class = $type ? $type : '';
2693
+
2694
+ foreach ( $paragraphs as $paragraph ) {
2695
+ $i++;
2696
+ $class = ( $i === $count ) ? ( $class . ' last' ) : $class;
2697
+ $r .= '<p class="' . esc_attr( $class ) . '">' . $paragraph . '</p>' . "\n";
2698
+ }
2699
+ }
2700
+ echo $r;
2701
+ }
2702
+ }
2703
+
2704
+ /**
2705
+ * Prints the introduction paragraphs for the current step.
2706
+ *
2707
+ * @return void
2708
+ **/
2709
+ function intro()
2710
+ {
2711
+ if ( 'incomplete' == $this->step_status[$this->step] && isset( $this->strings[$this->step]['intro'] ) ) {
2712
+ $messages = $this->strings[$this->step]['intro'];
2713
+ $count = count( $messages );
2714
+ $i = 0;
2715
+ $r = '';
2716
+ foreach ( $messages as $paragraph ) {
2717
+ $i++;
2718
+ $class = ( $i === $count ) ? 'intro last' : 'intro';
2719
+ $r .= '<p class="' . $class . '">' . $paragraph . '</p>' . "\n";
2720
+ }
2721
+ echo $r;
2722
+ }
2723
+ }
2724
+
2725
+ /**
2726
+ * Prints the standard header for each step.
2727
+ *
2728
+ * @param integer $step The number of the step whose header should be printed.
2729
+ * @return void
2730
+ **/
2731
+ function step_header( $step )
2732
+ {
2733
+ $class = ( $step == $this->step ) ? 'open' : 'closed';
2734
+
2735
+ $r = '<div id="' . esc_attr( 'step' . $step ) . '" class="' . $class . '">' . "\n";
2736
+ $r .= '<h2 class="' . $class . '">' . $this->strings[$step]['h2'] . '</h2>' . "\n";
2737
+ $r .= '<div>' . "\n";
2738
+
2739
+ if ( $step < $this->step && $this->strings[$step]['status'] ) {
2740
+ $r .= '<p class="status">' . $this->strings[$step]['status'] . '</p>' . "\n";
2741
+ }
2742
+
2743
+ echo $r;
2744
+
2745
+ if ( $step == $this->step ) {
2746
+ $this->intro();
2747
+ }
2748
+
2749
+ $this->tabindex = 0;
2750
+ }
2751
+
2752
+ /**
2753
+ * Prints the standard step footer.
2754
+ *
2755
+ * @return void
2756
+ **/
2757
+ function step_footer()
2758
+ {
2759
+ $r = '</div></div>' . "\n";
2760
+
2761
+ echo $r;
2762
+ }
2763
+ } // END class BB_Install
bp-forums/bbpress/bb-admin/includes/defaults.bb-htaccess.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $_rules = <<<EOF
4
+ # BEGIN bbPress
5
+
6
+ Options -MultiViews
7
+
8
+ <IfModule mod_rewrite.c>
9
+ RewriteEngine On
10
+ RewriteBase %PATH%
11
+
12
+ RewriteRule ^page/([0-9]+)/?$ %PATH%index.php?page=$1 [L,QSA]
13
+ RewriteRule ^forum/([^/]+)/page/([0-9]+)/?$ %PATH%forum.php?id=$1&page=$2 [L,QSA]
14
+ RewriteRule ^forum/([^/]+)/?$ %PATH%forum.php?id=$1 [L,QSA]
15
+ RewriteRule ^forum/?$ %PATH% [R=302,L,QSA]
16
+ RewriteRule ^topic/([^/]+)/page/([0-9]+)/?$ %PATH%topic.php?id=$1&page=$2 [L,QSA]
17
+ RewriteRule ^topic/([^/]+)/?$ %PATH%topic.php?id=$1 [L,QSA]
18
+ RewriteRule ^topic/?$ %PATH% [R=302,L,QSA]
19
+ RewriteRule ^tags/([^/]+)/page/([0-9]+)/?$ %PATH%tags.php?tag=$1&page=$2 [L,QSA]
20
+ RewriteRule ^tags/([^/]+)/?$ %PATH%tags.php?tag=$1 [L,QSA]
21
+ RewriteRule ^tags/?$ %PATH%tags.php [L,QSA]
22
+ RewriteRule ^profile/([^/]+)/page/([0-9]+)/?$ %PATH%profile.php?id=$1&page=$2 [L,QSA]
23
+ RewriteRule ^profile/([^/]+)/([^/]+)/?$ %PATH%profile.php?id=$1&tab=$2 [L,QSA]
24
+ RewriteRule ^profile/([^/]+)/([^/]+)/page/([0-9]+)/?$ %PATH%profile.php?id=$1&tab=$2&page=$3 [L,QSA]
25
+ RewriteRule ^profile/([^/]+)/?$ %PATH%profile.php?id=$1 [L,QSA]
26
+ RewriteRule ^profile/?$ %PATH%profile.php [L,QSA]
27
+ RewriteRule ^view/([^/]+)/page/([0-9]+)/?$ %PATH%view.php?view=$1&page=$2 [L,QSA]
28
+ RewriteRule ^view/([^/]+)/?$ %PATH%view.php?view=$1 [L,QSA]
29
+ RewriteRule ^rss/?$ %PATH%rss.php [L,QSA]
30
+ RewriteRule ^rss/topics/?$ %PATH%rss.php?topics=1 [L,QSA]
31
+ RewriteRule ^rss/forum/([^/]+)/?$ %PATH%rss.php?forum=$1 [L,QSA]
32
+ RewriteRule ^rss/forum/([^/]+)/topics/?$ %PATH%rss.php?forum=$1&topics=1 [L,QSA]
33
+ RewriteRule ^rss/topic/([^/]+)/?$ %PATH%rss.php?topic=$1 [L,QSA]
34
+ RewriteRule ^rss/tags/([^/]+)/?$ %PATH%rss.php?tag=$1 [L,QSA]
35
+ RewriteRule ^rss/tags/([^/]+)/topics/?$ %PATH%rss.php?tag=$1&topics=1 [L,QSA]
36
+ RewriteRule ^rss/profile/([^/]+)/?$ %PATH%rss.php?profile=$1 [L,QSA]
37
+ RewriteRule ^rss/view/([^/]+)/?$ %PATH%rss.php?view=$1 [L,QSA]
38
+ RewriteCond %{REQUEST_FILENAME} !-f
39
+ RewriteCond %{REQUEST_FILENAME} !-d
40
+ RewriteRule ^.*$ %PATH%index.php [L]
41
+ </IfModule>
42
+
43
+ # END bbPress
44
+ EOF;
45
+
46
+ $_rules = str_replace( '%PATH%', bb_get_option( 'path' ), $_rules );
bp-forums/bbpress/bb-admin/includes/defaults.bb-schema.php ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Globalise as this file is included within the functions bb_install() and bb_upgrade_all()
4
+ global $bb_queries, $bbdb, $bb_schema_ignore;
5
+
6
+ // Die if no database class is loaded
7
+ if ( !isset($bbdb) || ( !is_a( $bbdb, 'BPDB' ) && !is_a( $bbdb, 'db' ) ) )
8
+ die( __('Database class not loaded.') );
9
+
10
+ // Initialise the query array
11
+ $bb_queries = array();
12
+
13
+ // forums
14
+ $bb_queries['forums'] = "CREATE TABLE IF NOT EXISTS `$bbdb->forums` (
15
+ `forum_id` int(10) NOT NULL auto_increment,
16
+ `forum_name` varchar(150) NOT NULL default '',
17
+ `forum_slug` varchar(255) NOT NULL default '',
18
+ `forum_desc` text NOT NULL,
19
+ `forum_parent` int(10) NOT NULL default 0,
20
+ `forum_order` int(10) NOT NULL default 0,
21
+ `topics` bigint(20) NOT NULL default 0,
22
+ `posts` bigint(20) NOT NULL default 0,
23
+ PRIMARY KEY (`forum_id`),
24
+ KEY `forum_slug` (`forum_slug`)
25
+ );";
26
+
27
+ // meta
28
+ $bb_queries['meta'] = "CREATE TABLE IF NOT EXISTS `$bbdb->meta` (
29
+ `meta_id` bigint(20) NOT NULL auto_increment,
30
+ `object_type` varchar(16) NOT NULL default 'bb_option',
31
+ `object_id` bigint(20) NOT NULL default 0,
32
+ `meta_key` varchar(255) default NULL,
33
+ `meta_value` longtext default NULL,
34
+ PRIMARY KEY (`meta_id`),
35
+ KEY `object_type__meta_key` (`object_type`, `meta_key`),
36
+ KEY `object_type__object_id__meta_key` (`object_type`, `object_id`, `meta_key`)
37
+ );";
38
+
39
+ // posts
40
+ $bb_queries['posts'] = "CREATE TABLE IF NOT EXISTS `$bbdb->posts` (
41
+ `post_id` bigint(20) NOT NULL auto_increment,
42
+ `forum_id` int(10) NOT NULL default 1,
43
+ `topic_id` bigint(20) NOT NULL default 1,
44
+ `poster_id` int(10) NOT NULL default 0,
45
+ `post_text` text NOT NULL,
46
+ `post_time` datetime NOT NULL default '0000-00-00 00:00:00',
47
+ `poster_ip` varchar(15) NOT NULL default '',
48
+ `post_status` tinyint(1) NOT NULL default 0,
49
+ `post_position` bigint(20) NOT NULL default 0,
50
+ PRIMARY KEY (`post_id`),
51
+ KEY `topic_time` (`topic_id`, `post_time`),
52
+ KEY `poster_time` (`poster_id`, `post_time`),
53
+ KEY `post_time` (`post_time`),
54
+ FULLTEXT KEY `post_text` (`post_text`)
55
+ ) TYPE = MYISAM;";
56
+
57
+ // terms
58
+ $bb_queries['terms'] = "CREATE TABLE IF NOT EXISTS `$bbdb->terms` (
59
+ `term_id` bigint(20) NOT NULL auto_increment,
60
+ `name` varchar(55) NOT NULL default '',
61
+ `slug` varchar(200) NOT NULL default '',
62
+ `term_group` bigint(10) NOT NULL default 0,
63
+ PRIMARY KEY (`term_id`),
64
+ UNIQUE KEY `slug` (`slug`),
65
+ KEY name (name)
66
+ );";
67
+
68
+ // term_relationships
69
+ $bb_queries['term_relationships'] = "CREATE TABLE IF NOT EXISTS `$bbdb->term_relationships` (
70
+ `object_id` bigint(20) NOT NULL default 0,
71
+ `term_taxonomy_id` bigint(20) NOT NULL default 0,
72
+ `user_id` bigint(20) NOT NULL default 0,
73
+ `term_order` int(11) NOT NULL default 0,
74
+ PRIMARY KEY (`object_id`, `term_taxonomy_id`),
75
+ KEY `term_taxonomy_id` (`term_taxonomy_id`)
76
+ );";
77
+
78
+ // term_taxonomy
79
+ $bb_queries['term_taxonomy'] = "CREATE TABLE IF NOT EXISTS `$bbdb->term_taxonomy` (
80
+ `term_taxonomy_id` bigint(20) NOT NULL auto_increment,
81
+ `term_id` bigint(20) NOT NULL default 0,
82
+ `taxonomy` varchar(32) NOT NULL default '',
83
+ `description` longtext NOT NULL,
84
+ `parent` bigint(20) NOT NULL default 0,
85
+ `count` bigint(20) NOT NULL default 0,
86
+ PRIMARY KEY (`term_taxonomy_id`),
87
+ UNIQUE KEY `term_id_taxonomy` (`term_id`, `taxonomy`),
88
+ KEY `taxonomy` (`taxonomy`)
89
+ );";
90
+
91
+ // topics
92
+ $bb_queries['topics'] = "CREATE TABLE IF NOT EXISTS `$bbdb->topics` (
93
+ `topic_id` bigint(20) NOT NULL auto_increment,
94
+ `topic_title` varchar(100) NOT NULL default '',
95
+ `topic_slug` varchar(255) NOT NULL default '',
96
+ `topic_poster` bigint(20) NOT NULL default 0,
97
+ `topic_poster_name` varchar(40) NOT NULL default 'Anonymous',
98
+ `topic_last_poster` bigint(20) NOT NULL default 0,
99
+ `topic_last_poster_name` varchar(40) NOT NULL default '',
100
+ `topic_start_time` datetime NOT NULL default '0000-00-00 00:00:00',
101
+ `topic_time` datetime NOT NULL default '0000-00-00 00:00:00',
102
+ `forum_id` int(10) NOT NULL default 1,
103
+ `topic_status` tinyint(1) NOT NULL default 0,
104
+ `topic_open` tinyint(1) NOT NULL default 1,
105
+ `topic_last_post_id` bigint(20) NOT NULL default 1,
106
+ `topic_sticky` tinyint(1) NOT NULL default 0,
107
+ `topic_posts` bigint(20) NOT NULL default 0,
108
+ `tag_count` bigint(20) NOT NULL default 0,
109
+ PRIMARY KEY (`topic_id`),
110
+ KEY `topic_slug` (`topic_slug`),
111
+ KEY `forum_time` (`forum_id`, `topic_time`),
112
+ KEY `user_start_time` (`topic_poster`, `topic_start_time`),
113
+ KEY `stickies` (`topic_status`, `topic_sticky`, `topic_time`)
114
+ );";
115
+
116
+ // users - 'user_login', 'user_nicename' and 'user_registered' indices are inconsistent with WordPress
117
+ $bb_queries['users'] = "CREATE TABLE IF NOT EXISTS `$bbdb->users` (
118
+ `ID` bigint(20) unsigned NOT NULL auto_increment,
119
+ `user_login` varchar(60) NOT NULL default '',
120
+ `user_pass` varchar(64) NOT NULL default '',
121
+ `user_nicename` varchar(50) NOT NULL default '',
122
+ `user_email` varchar(100) NOT NULL default '',
123
+ `user_url` varchar(100) NOT NULL default '',
124
+ `user_registered` datetime NOT NULL default '0000-00-00 00:00:00',
125
+ `user_status` int(11) NOT NULL default 0,
126
+ `display_name` varchar(250) NOT NULL default '',
127
+ PRIMARY KEY (`ID`),
128
+ UNIQUE KEY `user_login` (`user_login`),
129
+ UNIQUE KEY `user_nicename` (`user_nicename`),
130
+ KEY `user_registered` (`user_registered`)
131
+ );";
132
+
133
+ // usermeta
134
+ $bb_queries['usermeta'] = "CREATE TABLE IF NOT EXISTS `$bbdb->usermeta` (
135
+ `umeta_id` bigint(20) NOT NULL auto_increment,
136
+ `user_id` bigint(20) NOT NULL default 0,
137
+ `meta_key` varchar(255),
138
+ `meta_value` longtext,
139
+ PRIMARY KEY (`umeta_id`),
140
+ KEY `user_id` (`user_id`),
141
+ KEY `meta_key` (`meta_key`)
142
+ );";
143
+
144
+ $bb_queries = apply_filters( 'bb_schema_pre_charset', $bb_queries );
145
+
146
+ // Set the charset and collation on each table
147
+ foreach ($bb_queries as $_table_name => $_sql) {
148
+ // Skip SQL that isn't creating a table
149
+ if (!preg_match('@^\s*CREATE\s+TABLE\s+@im', $_sql)) {
150
+ continue;
151
+ }
152
+
153
+ // Skip if the table's database doesn't support collation
154
+ if (!$bbdb->has_cap('collation', $bbdb->$_table_name)) {
155
+ continue;
156
+ }
157
+
158
+ // Find out if the table has a custom database set
159
+ if (
160
+ isset($bbdb->db_tables) &&
161
+ is_array($bbdb->db_tables) &&
162
+ isset($bbdb->db_tables[$bbdb->$_table_name])
163
+ ) {
164
+ // Set the database for this table
165
+ $_database = $bbdb->db_tables[$bbdb->$_table_name];
166
+ } else {
167
+ // Set the default global database
168
+ $_database = 'dbh_global';
169
+ }
170
+
171
+ // Make sure the database exists
172
+ if (
173
+ isset($bbdb->db_servers) &&
174
+ is_array($bbdb->db_servers) &&
175
+ isset($bbdb->db_servers[$_database]) &&
176
+ is_array($bbdb->db_servers[$_database])
177
+ ) {
178
+ $_charset_collate = '';
179
+ if (isset($bbdb->db_servers[$_database]['charset']) && !empty($bbdb->db_servers[$_database]['charset'])) {
180
+ // Add a charset if set
181
+ $_charset_collate .= ' DEFAULT CHARACTER SET \'' . $bbdb->db_servers[$_database]['charset'] . '\'';
182
+ }
183
+ if (isset($bbdb->db_servers[$_database]['collate']) && !empty($bbdb->db_servers[$_database]['collate'])) {
184
+ // Add a collation if set
185
+ $_charset_collate .= ' COLLATE \'' . $bbdb->db_servers[$_database]['collate'] . '\'';
186
+ }
187
+ if ($_charset_collate) {
188
+ // Modify the SQL
189
+ $bb_queries[$_table_name] = str_replace(';', $_charset_collate . ';', $_sql);
190
+ }
191
+ }
192
+ unset($_database, $_charset_collate);
193
+ }
194
+ unset($_table_name, $_sql);
195
+
196
+ $bb_queries = apply_filters( 'bb_schema', $bb_queries );
197
+
198
+ // These elements in the schema may need to be ignored when doing comparisons due to inconsistencies with WordPress
199
+ if ( bb_get_option('wp_table_prefix') || ( defined( 'BB_SCHEMA_IGNORE_WP_USERS_KEYS' ) && BB_SCHEMA_IGNORE_WP_USERS_KEYS ) ) {
200
+ $bb_schema_ignore = array(
201
+ 'tables' => array(),
202
+ 'columns' => array(),
203
+ 'indices' => array(
204
+ $bbdb->users => array(
205
+ 'user_login',
206
+ 'user_nicename',
207
+ 'user_registered'
208
+ )
209
+ )
210
+ );
211
+ } else {
212
+ $bb_schema_ignore = false;
213
+ }
214
+
215
+ $bb_schema_ignore = apply_filters( 'bb_schema_ignore', $bb_schema_ignore );
216
+
217
+ do_action( 'bb_schema_defined' );
218
+
219
+ ?>
bp-forums/bbpress/bb-admin/includes/functions.bb-admin.php ADDED
@@ -0,0 +1,1432 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function bb_get_admin_header()
4
+ {
5
+ do_action( 'bb_admin-header.php' );
6
+ include( 'admin-header.php' );
7
+ do_action( 'bb_get_admin_header' );
8
+ }
9
+
10
+ function bb_get_admin_footer()
11
+ {
12
+ do_action( 'bb_admin-footer.php' );
13
+ include( 'admin-footer.php' );
14
+ }
15
+
16
+ function bb_admin_notice( $message, $class = false )
17
+ {
18
+ if ( is_string( $message ) ) {
19
+ $message = '<p>' . $message . '</p>';
20
+ $class = $class ? $class : 'updated';
21
+ } elseif ( is_wp_error( $message ) ) {
22
+ $errors = $message->get_error_messages();
23
+ switch ( count( $errors ) ) {
24
+ case 0:
25
+ return false;
26
+ break;
27
+ case 1:
28
+ $message = '<p>' . $errors[0] . '</p>';
29
+ break;
30
+ default:
31
+ $message = '<ul>' . "\n\t" . '<li>' . join( '</li>' . "\n\t" . '<li>', $errors ) . '</li>' . "\n" . '</ul>';
32
+ break;
33
+ }
34
+ $class = $class ? $class : 'error';
35
+ } else {
36
+ return false;
37
+ }
38
+
39
+ $message = '<div id="message" class="' . esc_attr( $class ) . '">' . $message . '</div>';
40
+ $message = str_replace( "'", "\'", $message );
41
+ $lambda = create_function( '', "echo '$message';" );
42
+ add_action( 'bb_admin_notices', $lambda );
43
+ return $lambda;
44
+ }
45
+
46
+ /* Menu */
47
+
48
+ function bb_admin_menu_generator()
49
+ {
50
+ global $bb_menu, $bb_submenu;
51
+ $bb_menu = array();
52
+ $bb_submenu = array();
53
+
54
+ // Dashboard menu items < 50
55
+ $bb_menu[0] = array( __( 'Dashboard' ), 'moderate', 'index.php', '', 'bb-menu-dashboard' );
56
+ $bb_submenu['index.php'][5] = array( __( 'Dashboard' ), 'moderate', 'index.php' );
57
+
58
+ // 50 < Plugin added menu items < 100
59
+
60
+ $bb_menu[100] = array( '', 'read', 'separator' );
61
+
62
+ // 100 < Plugin added menu items < 150
63
+
64
+ // 150 < First menu items < 200
65
+ $bb_menu[150] = array( __( 'Forums' ), 'manage_forums', 'forums.php', '', 'bb-menu-forums' );
66
+ $bb_submenu['forums.php'][5] = array( __( 'Forums' ), 'manage_forums', 'forums.php' );
67
+ $bb_menu[155] = array( __( 'Topics' ), 'moderate', 'topics.php', '', 'bb-menu-topics' );
68
+ $bb_submenu['topics.php'][5] = array( __( 'Topics' ), 'moderate', 'topics.php' );
69
+ $bb_menu[160] = array( __( 'Posts' ), 'moderate', 'posts.php', '', 'bb-menu-posts' );
70
+ $bb_submenu['posts.php'][5] = array( __( 'Posts' ), 'moderate', 'posts.php' );
71
+
72
+ // 200 < Plugin added menu items < 250
73
+
74
+ $bb_menu[250] = array( '', 'read', 'separator' );
75
+
76
+ // 250 < Plugin added menu items < 300
77
+
78
+ // 300 < Second menu items < 350
79
+ $bb_menu[300] = array( __( 'Appearance' ), 'manage_themes', 'themes.php', '', 'bb-menu-appearance' );
80
+ $bb_submenu['themes.php'][5] = array(__('Themes'), 'manage_themes', 'themes.php');
81
+ $bb_menu[305] = array( __( 'Plugins' ), 'use_keys', 'plugins.php', '', 'bb-menu-plugins' );
82
+ $bb_submenu['plugins.php'][5] = array( __( 'Installed' ), 'manage_plugins', 'plugins.php' );
83
+ $bb_menu[310] = array( __( 'Users' ), 'moderate', 'users.php', '', 'bb-menu-users' );
84
+ $bb_submenu['users.php'][5] = array( __( 'Users' ), 'moderate', 'users.php' );
85
+ $bb_menu[315] = array( __( 'Tools' ), 'recount', 'tools-recount.php', '', 'bb-menu-tools' );
86
+ $bb_submenu['tools-recount.php'][5] = array( __( 'Re-count' ), 'recount', 'tools-recount.php' );
87
+ $bb_menu[320] = array( __( 'Settings' ), 'manage_options', 'options-general.php', '', 'bb-menu-settings' );
88
+ $bb_submenu['options-general.php'][5] = array( __( 'General' ), 'manage_options', 'options-general.php' );
89
+ //$bb_submenu['options-general.php'][10] = array( __( 'Date and Time' ), 'manage_options', 'options-time.php' );
90
+ $bb_submenu['options-general.php'][15] = array( __( 'Writing' ), 'manage_options', 'options-writing.php' );
91
+ $bb_submenu['options-general.php'][20] = array( __( 'Reading' ), 'manage_options', 'options-reading.php' );
92
+ $bb_submenu['options-general.php'][25] = array( __( 'Discussion' ), 'manage_options', 'options-discussion.php' );
93
+ $bb_submenu['options-general.php'][30] = array( __( 'Permalinks' ), 'manage_options', 'options-permalinks.php' );
94
+ $bb_submenu['options-general.php'][35] = array( __( 'WordPress Integration' ), 'manage_options', 'options-wordpress.php' );
95
+
96
+ // 350 < Plugin added menu items
97
+
98
+ do_action( 'bb_admin_menu_generator' );
99
+ ksort( $bb_menu );
100
+
101
+ $last_key = false;
102
+ foreach ( $bb_menu as $key => $m ) {
103
+ if ( $last_key === false || $bb_menu[$last_key][2] === 'separator' ) {
104
+ $bb_menu[$key][3] .= ' bb-menu-first';
105
+ }
106
+ if ( $bb_menu[$key][2] === 'separator' ) {
107
+ $bb_menu[$last_key][3] .= ' bb-menu-last';
108
+ }
109
+ $last_key = $key;
110
+ if ( isset( $bb_submenu[$m[2]] ) ) {
111
+ ksort( $bb_submenu[$m[2]] );
112
+ }
113
+ }
114
+ $bb_menu[$last_key][3] .= ' bb-menu-last';
115
+ }
116
+
117
+ function bb_admin_add_menu( $display_name, $capability, $file_name, $menu_position = false, $class = '', $id = '' )
118
+ {
119
+ global $bb_menu;
120
+
121
+ if ( $display_name && $capability && $file_name ) {
122
+ // Get an array of the keys
123
+ $menu_keys = array_keys( $bb_menu );
124
+
125
+ if ( $menu_position ) {
126
+ if ( is_numeric( $menu_position ) ) {
127
+ if ( !isset( $bb_menu[$menu_position] ) ) {
128
+ $plugin_menu_next = $menu_position;
129
+ } else {
130
+ return bb_admin_add_menu( $display_name, $capability, $file_name, ( $menu_position + 1 ), $class, $id );
131
+ }
132
+ } else {
133
+ // Set the bounds for different menu groups (main or side)
134
+ switch ( $menu_position ) {
135
+ case 'dash':
136
+ $lower = 50;
137
+ $upper = 100;
138
+ break;
139
+ case 'main':
140
+ $lower = 200;
141
+ $upper = 250;
142
+ break;
143
+ default:
144
+ $lower = 350;
145
+ $upper = 500;
146
+ break;
147
+ }
148
+
149
+ // Get an array of all plugin added keys
150
+ $plugin_menu_keys = array_filter( $menu_keys, create_function( '$v', 'if ($v >= ' . $lower . ' && $v < ' . $upper . ') { return $v; }' ) );
151
+
152
+ // If there is an array of keys
153
+ if ( is_array( $plugin_menu_keys ) && count( $plugin_menu_keys ) ) {
154
+ // Get the highest key value and add one
155
+ $plugin_menu_next = max( $plugin_menu_keys ) + 1;
156
+ } else {
157
+ // It's the first one
158
+ $plugin_menu_next = $lower;
159
+ }
160
+ }
161
+ } else {
162
+ $plugin_menu_next = max( array_keys( $bb_menu ) ) + 1;
163
+ $bb_menu[$plugin_menu_next] = array( '', 'read', 'separator' );
164
+ $plugin_menu_next++;
165
+ }
166
+
167
+ // Add the menu item at the given key
168
+ $bb_menu[$plugin_menu_next] = array( $display_name, $capability, $file_name, $class, $id );
169
+
170
+ ksort( $bb_menu );
171
+
172
+ return $plugin_menu_next;
173
+ }
174
+
175
+ return false;
176
+ }
177
+
178
+ function bb_admin_add_submenu( $display_name, $capability, $file_name, $parent = 'plugins.php' )
179
+ {
180
+ global $bb_submenu;
181
+ if ( $display_name && $capability && $file_name ) {
182
+ $bb_submenu[$parent][] = array( $display_name, $capability, $file_name );
183
+ ksort( $bb_submenu );
184
+ }
185
+ }
186
+
187
+ function bb_get_current_admin_menu()
188
+ {
189
+ global $bb_menu, $bb_submenu, $bb_admin_page, $bb_current_menu, $bb_current_submenu;
190
+ foreach ( $bb_submenu as $m => $b ) {
191
+ foreach ( $b as $s ) {
192
+ if ( $s[2] == $bb_admin_page ) {
193
+ $bb_current_submenu = $s;
194
+ $bb_current_menu = $m;
195
+ break;
196
+ }
197
+ }
198
+ }
199
+ if ( !isset($bb_current_menu) ) {
200
+ $bb_current_menu = $bb_menu[0];
201
+ $bb_current_submenu = $bb_submenu['index.php'][5];
202
+ } else {
203
+ foreach ( $bb_menu as $m ) {
204
+ if ( $m[2] == $bb_current_menu ) {
205
+ $bb_current_menu = $m;
206
+ break;
207
+ }
208
+ }
209
+ }
210
+ if ( $bb_current_submenu && !bb_current_user_can( $bb_current_submenu[1] ) || !bb_current_user_can( $bb_current_menu[1] ) ) {
211
+ wp_redirect( bb_get_uri(null, null, BB_URI_CONTEXT_HEADER) );
212
+ exit;
213
+ }
214
+ }
215
+
216
+ function bb_admin_title()
217
+ {
218
+ global $bb_current_menu, $bb_current_submenu;
219
+
220
+ $title = $bb_current_menu[0] . ' &lsaquo; ' . bb_get_option( 'name' ) . ' &#8212; ' . __( 'bbPress' );
221
+
222
+ if ( $bb_current_submenu && $bb_current_submenu[0] !== $bb_current_menu[0] ) {
223
+ $title = $bb_current_submenu[0] . ' &lsaquo; ' . $title;
224
+ }
225
+
226
+ echo esc_html( $title );
227
+ }
228
+
229
+ function bb_admin_menu()
230
+ {
231
+ global $bb_menu, $bb_submenu, $bb_current_menu, $bb_current_submenu;
232
+
233
+ if ( !is_array( $bb_menu ) || !count( $bb_menu ) ) {
234
+ return '';
235
+ }
236
+
237
+ $r = "\t\t\t" . '<ul id="bbAdminMenu">' . "\n";
238
+
239
+ foreach ( $bb_menu as $key => $m ) {
240
+ if ( !bb_current_user_can( $m[1] ) ) {
241
+ continue;
242
+ }
243
+ $class = 'bb-menu';
244
+ if ( isset( $m[3] ) ) {
245
+ $class .= ' ' . $m[3];
246
+ }
247
+ $id = '';
248
+ if ( isset( $m[4] ) ) {
249
+ $id .= ' id="' . $m[4] . '"';
250
+ }
251
+ $m[0] = esc_html( $m[0] );
252
+ if ( $m[2] === 'separator' ) {
253
+ if ( 'f' == bb_get_user_setting( 'fm' ) ) {
254
+ $href = '?foldmenu=0';
255
+ } else {
256
+ $href = '?foldmenu=1';
257
+ }
258
+ $m[0] = '<br />';
259
+ $class .= ' bb-menu-separator';
260
+ } elseif ( strpos( $m[2], 'http://' ) === 0 || strpos( $m[2], 'https://' ) === 0 ) {
261
+ $href = esc_url( $m[2] );
262
+ $class .= ' bb-menu-external';
263
+ } else {
264
+ $href = esc_url( bb_get_option( 'path' ) . 'bb-admin/' . bb_get_admin_tab_link( $m[2] ) );
265
+ }
266
+ if ( $m[2] == $bb_current_menu[2] ) {
267
+ $class .= ' bb-menu-current';
268
+ }
269
+
270
+ $sr = '';
271
+ if ( $m[2] !== 'separator' && isset( $bb_submenu[$m[2]] ) && is_array( $bb_submenu[$m[2]] ) && count( $bb_submenu[$m[2]] ) ) {
272
+ $sr .= "\t\t\t\t\t" . '<div class="bb-menu-sub-wrap"><span>' . $m[0] . '</span>' . "\n";
273
+ $sr .= "\t\t\t\t\t\t" . '<ul>' . "\n";
274
+ $sc = 0;
275
+ foreach ( $bb_submenu[$m[2]] as $skey => $sm ) {
276
+ if ( $sc === 0 && $sm[2] === $m[2] ) {
277
+ $no_submenu = true;
278
+ }
279
+ if ( $sc > 0 ) {
280
+ $no_submenu = false;
281
+ }
282
+ $sc++;
283
+ $sclass = 'bb-menu-sub';
284
+ if ( isset( $sm[3] ) ) {
285
+ $sclass .= ' ' . $sm[3];
286
+ }
287
+ if ( strpos( $sm[2], 'http://' ) === 0 || strpos( $sm[2], 'https://' ) === 0 ) {
288
+ $shref = $sm[2];
289
+ $sclass .= ' bb-menu-external';
290
+ } else {
291
+ $shref = bb_get_option( 'path' ) . 'bb-admin/' . bb_get_admin_tab_link( $sm[2] );
292
+ }
293
+ if ( $sm[2] == $bb_current_submenu[2] ) {
294
+ $sclass .= ' bb-menu-sub-current';
295
+ }
296
+ $sr .= "\t\t\t\t\t\t\t" . '<li class="' . esc_attr( trim( $sclass ) ) . '"><a href="' . esc_url( $shref ) . '">' . esc_html( $sm[0] ) . '</a></li>' . "\n";
297
+ }
298
+ $sr .= "\t\t\t\t\t\t" . '</ul>' . "\n";
299
+ $sr .= "\t\t\t\t\t" . '</div>' . "\n";
300
+ }
301
+
302
+ if ( $sr && !$no_submenu ) {
303
+ $class .= ' bb-menu-has-submenu';
304
+ if ( $m[2] == $bb_current_menu[2] ) {
305
+ $class .= ' bb-menu-open';
306
+ }
307
+ }
308
+
309
+ $r .= "\t\t\t\t" . '<li' . $id . ' class="' . esc_attr( trim( $class ) ) . '"><a href="' . $href . '">';
310
+
311
+ if ( $m[2] !== 'separator' ) {
312
+ $r .= '<div class="bb-menu-icon"></div>';
313
+ }
314
+
315
+ $r .= '<span>' . $m[0] . '</span></a>' . "\n";
316
+
317
+ if ( $sr && !$no_submenu ) {
318
+ $r .= '<div class="bb-menu-toggle"></div>';
319
+ $r .= $sr;
320
+ }
321
+
322
+ $r .= "\t\t\t\t" . '</li>' . "\n";
323
+ }
324
+
325
+ $r .= "\t\t\t" . '</ul>' . "\n";
326
+
327
+ echo $r;
328
+ }
329
+
330
+ function bb_get_admin_tab_link( $tab )
331
+ {
332
+ if ( is_array( $tab ) ) {
333
+ $tab = $tab[2];
334
+ }
335
+ if ( strpos( $tab, '.php' ) !== false ) {
336
+ return $tab;
337
+ } else {
338
+ return 'admin-base.php?plugin=' . $tab;
339
+ }
340
+ }
341
+
342
+ /* Stats */
343
+
344
+ function bb_get_recently_moderated_objects( $num = 5 ) {
345
+ $post_query = new BB_Query( 'post', array( 'per_page' => $num, 'post_status' => '-normal', 'topic_status' => 0 ) ); // post_time != moderation_time;
346
+ $topic_query = new BB_Query( 'topic', array( 'per_page' => $num, 'topic_status' => '-normal' ) ); // topic_time == topic_start_time != moderation_time;
347
+
348
+ $objects = array();
349
+ if ( $post_query->results )
350
+ foreach ( array_keys($post_query->results) as $key )
351
+ $objects[bb_gmtstrtotime($post_query->results[$key]->post_time)] = array('type' => 'post', 'data' => $post_query->results[$key]);
352
+ if ( $topic_query->results )
353
+ foreach ( array_keys($topic_query->results) as $key )
354
+ $objects[bb_gmtstrtotime($topic_query->results[$key]->topic_time)] = array('type' => 'topic', 'data' => $topic_query->results[$key]);
355
+ krsort($objects);
356
+ return array_slice($objects, 0, $num);
357
+ }
358
+
359
+ /* Users */
360
+
361
+ // Not bbdb::prepared
362
+ function bb_get_ids_by_role( $role = 'moderator', $sort = 0, $page = 1, $limit = 50 ) {
363
+ global $bbdb, $bb_last_countable_query;
364
+ $sort = $sort ? 'DESC' : 'ASC';
365
+ $key = $bbdb->escape( $bbdb->prefix . 'capabilities' );
366
+
367
+ if ( !$page = abs( (int) $page ) )
368
+ $page = 1;
369
+ $limit = abs( (int) $limit );
370
+
371
+ $limit = ($limit * ($page - 1)) . ", $limit";
372
+
373
+ $role = $bbdb->escape_deep($role);
374
+
375
+ if ( is_array($role) )
376
+ $and_where = "( meta_value LIKE '%" . join("%' OR meta_value LIKE '%", $role) . "%' )";
377
+ else
378
+ $and_where = "meta_value LIKE '%$role%'";
379
+ $bb_last_countable_query = "SELECT user_id FROM $bbdb->usermeta WHERE meta_key = '$key' AND $and_where ORDER BY user_id $sort LIMIT $limit";
380
+
381
+ $ids = false;
382
+
383
+ $_tuple = compact( 'ids', 'role', 'sort', 'page', 'key', 'limit', 'bb_last_countable_query' );
384
+ $_tuple = apply_filters( 'bb_get_ids_by_role', $_tuple );
385
+ extract( $_tuple, EXTR_OVERWRITE );
386
+
387
+ if ( !$ids ) {
388
+ $ids = (array) $bbdb->get_col( $bb_last_countable_query );
389
+ }
390
+
391
+ if ( $ids ) {
392
+ bb_cache_users( $ids );
393
+ }
394
+
395
+ return $ids;
396
+ }
397
+
398
+ function bb_user_row( $user, $role = '', $email = false ) {
399
+ $actions = "<a href='" . esc_attr( get_user_profile_link( $user->ID ) ) . "'>" . __('View') . "</a>";
400
+ if ( bb_current_user_can( 'edit_user', $user_id ) )
401
+ $actions .= " | <a href='" . esc_attr( get_profile_tab_link( $user->ID, 'edit' ) ) . "'>" . __('Edit') . "</a>";
402
+ $r = "\t<tr id='user-$user->ID'" . get_alt_class("user-$role") . ">\n";
403
+ $r .= "\t\t<td class=\"user\">" . bb_get_avatar( $user->ID, 32 ) . "<span class=\"row-title\"><a href='" . get_user_profile_link( $user->ID ) . "'>" . get_user_name( $user->ID ) . "</a></span><div><span class=\"row-actions\">$actions</span>&nbsp;</div></td>\n";
404
+ $r .= "\t\t<td><a href='" . get_user_profile_link( $user->ID ) . "'>" . get_user_display_name( $user->ID ) . "</a></td>\n";
405
+ if ( $email ) {
406
+ $email = bb_get_user_email( $user->ID );
407
+ $r .= "\t\t<td><a href='mailto:$email'>$email</a></td>\n";
408
+ }
409
+
410
+ $registered_time = bb_gmtstrtotime( $user->user_registered );
411
+ if ( $registered_time < ( time() - 86400 ) ) {
412
+ $time = date( 'Y/m/d\<\b\r \/\>H:i:s', bb_offset_time( $registered_time ) );
413
+ } else {
414
+ $time = sprintf( __( '%s ago' ), bb_since( $registered_time ) );
415
+ }
416
+
417
+ $r .= "\t\t<td>" . $time . "</td>\n";
418
+
419
+ if (
420
+ !isset($user->capabilities) ||
421
+ !is_array($user->capabilities) ||
422
+ empty($user->capabilities)
423
+ ) {
424
+ $role = array( __('Inactive (no role)') );
425
+ } else {
426
+ global $wp_roles;
427
+ $_roles = $wp_roles->get_names();
428
+ $role = array();
429
+ foreach ( $user->capabilities as $cap => $cap_set ) {
430
+ if (!$cap_set) {
431
+ continue;
432
+ }
433
+ $role[] = $_roles[$cap];
434
+ }
435
+ if ( !count( $role ) ) {
436
+ $role[] = __('None');
437
+ }
438
+ }
439
+
440
+ $r .= "\t\t<td>" . join(', ', $role) . "</td>\n\t</tr>";
441
+ return $r;
442
+ }
443
+
444
+ // BB_User_Search class
445
+ // by Mark Jaquith
446
+
447
+ class BB_User_Search {
448
+ var $results;
449
+ var $search_term;
450
+ var $page;
451
+ var $raw_page;
452
+ var $users_per_page = 50;
453
+ var $first_user;
454
+ var $last_user;
455
+ var $query_limit;
456
+ var $total_users_for_query = 0;
457
+ var $search_errors;
458
+ var $paging_text;
459
+ var $paging_text_bottom;
460
+
461
+ function BB_User_Search ($search_term = false, $page = 1, $roles = false ) { // constructor
462
+ $this->search_term = $search_term ? stripslashes($search_term) : false;
463
+ $this->raw_page = ( '' == $page ) ? false : (int) $page;
464
+ $page = (int) $page;
465
+ $this->page = $page < 2 ? 1 : $page;
466
+ $roles = (array) $roles;
467
+ $_roles = array();
468
+ foreach ( $roles as $role ) {
469
+ if ( false !== $role ) {
470
+ $_roles[] = stripslashes( $role );
471
+ }
472
+ }
473
+ $this->roles = empty( $_roles ) ? false : $_roles;
474
+
475
+ $this->prepare_query();
476
+ $this->query();
477
+ $this->prepare_vars_for_template_usage();
478
+ $this->do_paging();
479
+ }
480
+
481
+ function prepare_query() {
482
+ $this->first_user = ($this->page - 1) * $this->users_per_page;
483
+ }
484
+
485
+ function query() {
486
+ $users = bb_user_search( array(
487
+ 'query' => $this->search_term,
488
+ 'user_email' => true,
489
+ 'users_per_page' => $this->users_per_page,
490
+ 'page' => $this->page,
491
+ 'roles' => $this->roles
492
+ ) );
493
+
494
+ if ( is_wp_error($users) )
495
+ $this->search_errors = $users;
496
+ else if ( $users )
497
+ $this->results = $users;
498
+ // foreach ( (array) $users as $user )
499
+ // $this->results[] = $user->ID;
500
+
501
+ if ( $this->results )
502
+ $this->total_users_for_query = bb_count_last_query();
503
+ elseif ( !is_wp_error($this->search_errors) )
504
+ $this->search_errors = new WP_Error( 'no_matching_users_found', __( '<strong>No matching users were found!</strong>' ) );
505
+
506
+ if ( is_wp_error( $this->search_errors ) )
507
+ bb_admin_notice( $this->search_errors );
508
+ }
509
+
510
+ function prepare_vars_for_template_usage() {
511
+ $this->search_term = stripslashes($this->search_term); // done with DB, from now on we want slashes gone
512
+ }
513
+
514
+ function do_paging() {
515
+ global $bb_current_submenu;
516
+ $displaying_num = sprintf(
517
+ __( '%1$s to %2$s of %3$s' ),
518
+ bb_number_format_i18n( ( $this->page - 1 ) * $this->users_per_page + 1 ),
519
+ $this->page * $this->users_per_page < $this->total_users_for_query ? bb_number_format_i18n( $this->page * $this->users_per_page ) : '<span class="total-type-count">' . bb_number_format_i18n( $this->total_users_for_query ) . '</span>',
520
+ '<span class="total-type-count">' . bb_number_format_i18n( $this->total_users_for_query ) . '</span>'
521
+ );
522
+ $page_number_links = $this->total_users_for_query > $this->users_per_page ? get_page_number_links( $this->page, $this->total_users_for_query, $this->users_per_page, false ) : '';
523
+ $this->paging_text = "<div class='tablenav-pages'><span class='displaying-num'>$displaying_num</span><span class=\"displaying-pages\">$page_number_links</span><div class=\"clear\"></div></div>\n";
524
+ $this->paging_text_bottom = "<div class='tablenav-pages'><span class=\"displaying-pages\">$page_number_links</span><div class=\"clear\"></div></div>\n";
525
+ }
526
+
527
+ function get_results() {
528
+ return (array) $this->results;
529
+ }
530
+
531
+ function page_links() {
532
+ echo $this->paging_text;
533
+ }
534
+
535
+ function results_are_paged() {
536
+ if ( isset($this->paging_text) && $this->paging_text )
537
+ return true;
538
+ return false;
539
+ }
540
+
541
+ function is_search() {
542
+ if ( $this->search_term )
543
+ return true;
544
+ return false;
545
+ }
546
+
547
+ function display( $show_search = true, $show_email = false ) {
548
+ global $wp_roles;
549
+
550
+ $r = '';
551
+
552
+ if ( isset($this->title) )
553
+ $title = $this->title;
554
+ elseif ( $this->is_search() )
555
+ $title = sprintf(__('Users Matching "%s" by Role'), esc_html( $this->search_term ));
556
+
557
+ $h2_search = $this->search_term;
558
+ $h2_role = $this->roles[0];
559
+
560
+ $roles = $wp_roles->get_names();
561
+ if ( in_array( $h2_role, array_keys( $roles ) ) ) {
562
+ $h2_role = $roles[$h2_role];
563
+ }
564
+
565
+ $h2_search = $h2_search ? ' ' . sprintf( __('containing &#8220;%s&#8221;'), esc_html( $h2_search ) ) : '';
566
+ $h2_role = $h2_role ? ' ' . sprintf( __('with role &#8220;%s&#8221;'), esc_html( $h2_role ) ) : '';
567
+
568
+ $h2_span = '<span class="subtitle">';
569
+ $h2_span .= apply_filters( 'bb_user_search_description', sprintf( __( '%1$s%2$s' ), $h2_search, $h2_role ), $h2_search, $h2_role, $this );
570
+ $h2_span .= '</span>';
571
+
572
+ echo "<h2 class=\"first\">" . apply_filters( 'bb_user_search_title', __('Users') ) . $h2_span . "</h2>\n";
573
+ do_action( 'bb_admin_notices' );
574
+
575
+ if ( $show_search ) {
576
+ $roles = apply_filters( 'bb_user_search_form_roles', $wp_roles->get_names() );
577
+
578
+ $r .= "<form action='' method='get' id='search' class='search-form'>\n";
579
+ $r .= "<fieldset>\n";
580
+ $r .= "<div>\n";
581
+ $r .= "\t\t<label for='usersearch'>" . __('Search term') . "</label>";
582
+ $r .= "\t\t<div><input type='text' name='usersearch' id='usersearch' class='text-input' value='" . esc_html( $this->search_term, 1) . "' /></div>\n";
583
+ $r .= "</div>\n";
584
+ $r .= "<div>\n";
585
+ $r .= "\t\t<label for='userrole'>" . __('Role') . "</label>";
586
+ $r .= "\t\t<div><select name='userrole[]' id='userrole'>\n";
587
+ $r .= "\t\t\t<option value=''>All</option>\n";
588
+
589
+ foreach ( $roles as $role => $display ) {
590
+ $selected = '';
591
+ if ( is_array( $this->roles ) && in_array( $role, $this->roles ) ) {
592
+ $selected = ' selected="selected"';
593
+ }
594
+ $value = esc_attr($role);
595
+ $display = esc_html(translate($display));
596
+ $r .= "\t\t\t<option value='$value'$selected>$display</option>\n";
597
+ }
598
+
599
+ $r .= "\t\t</select></div>\n";
600
+ $r .= "</div>\n";
601
+
602
+ $r = apply_filters( 'bb_user_search_form_inputs', $r, $this );
603
+
604
+ $r .= "<div class=\"submit\">\n";
605
+ $r .= "\t\t<label class='hidden' for='submit'>" . __('Search') . "</label>";
606
+ $r .= "\t\t<div><input type='submit' id='submit' class='button submit-input' value='" . __('Filter') . "' /></div>\n";
607
+ $r .= "</div>\n";
608
+ $r .= "</fieldset>\n";
609
+ $r .= "</form>\n\n";
610
+ }
611
+
612
+ if ( $this->get_results() ) {
613
+ if ( $this->results_are_paged() )
614
+ $r .= "<div class='tablenav'>\n" . $this->paging_text . "</div><div class=\"clear\"></div>\n\n";
615
+
616
+ //foreach($roleclasses as $role => $roleclass) {
617
+ //ksort($roleclass);
618
+ //if ( !empty($role) )
619
+ // $r .= "\t\t<h3>{$wp_roles->role_names[$role]}</h3>\n";
620
+ //else
621
+ // $r .= "\t\t<h3><em>" . __('Users with no role in these forums') . "</h3>\n";
622
+ $r .= "<table class='widefat'>\n";
623
+ $r .= "<thead>\n";
624
+ $r .= "\t<tr>\n";
625
+ if ( $show_email ) {
626
+ $r .= "\t\t<th style='width:30%;'>" . __('Username') . "</th>\n";
627
+ $r .= "\t\t<th style='width:20%;'>" . __('Name') . "</th>\n";
628
+ $r .= "\t\t<th style='width:20%;'>" . __('E-mail') . "</th>\n";
629
+ } else {
630
+ $r .= "\t\t<th style='width:40%;'>" . __('Username') . "</th>\n";
631
+ $r .= "\t\t<th style='width:30%;'>" . __('Name') . "</th>\n";
632
+ }
633
+ $r .= "\t\t<th style='width:15%;'>" . __('Registered') . "</th>\n";
634
+ $r .= "\t\t<th style='width:15%;'>" . __('Role') . "</th>\n";
635
+ $r .= "\t</tr>\n";
636
+ $r .= "</thead>\n\n";
637
+ $r .= "<tfoot>\n";
638
+ $r .= "\t<tr>\n";
639
+ if ( $show_email ) {
640
+ $r .= "\t\t<th style='width:30%;'>" . __('Username') . "</th>\n";
641
+ $r .= "\t\t<th style='width:20%;'>" . __('Name') . "</th>\n";
642
+ $r .= "\t\t<th style='width:20%;'>" . __('E-mail') . "</th>\n";
643
+ } else {
644
+ $r .= "\t\t<th style='width:40%;'>" . __('Username') . "</th>\n";
645
+ $r .= "\t\t<th style='width:30%;'>" . __('Name') . "</th>\n";
646
+ }
647
+ $r .= "\t\t<th style='width:15%;'>" . __('Registered') . "</th>\n";
648
+ $r .= "\t\t<th style='width:15%;'>" . __('Role') . "</th>\n";
649
+ $r .= "\t</tr>\n";
650
+ $r .= "</tfoot>\n\n";
651
+
652
+ $r .= "<tbody id='role-$role'>\n";
653
+ foreach ( (array) $this->get_results() as $user_object )
654
+ $r .= bb_user_row($user_object, $role, $show_email);
655
+ $r .= "</tbody>\n";
656
+ $r .= "</table>\n\n";
657
+ //}
658
+
659
+ if ( $this->results_are_paged() )
660
+ $r .= "<div class='tablenav bottom'>\n" . $this->paging_text_bottom . "</div><div class=\"clear\"></div>\n\n";
661
+ }
662
+ echo $r;
663
+ }
664
+
665
+ }
666
+
667
+ class BB_Users_By_Role extends BB_User_Search {
668
+ var $role = '';
669
+ var $title = '';
670
+
671
+ function BB_Users_By_Role($role = '', $page = '') { // constructor
672
+ $this->role = $role ? $role : 'member';
673
+ $this->raw_page = ( '' == $page ) ? false : (int) $page;
674
+ $this->page = (int) ( '' == $page ) ? 1 : $page;
675
+
676
+ $this->prepare_query();
677
+ $this->query();
678
+ $this->do_paging();
679
+ }
680
+
681
+ function query() {
682
+ if ( $_results = bb_get_ids_by_role( $this->role, 0, $this->page, $this->users_per_page ) ) {
683
+ $this->results = bb_get_user($_results);
684
+ $this->total_users_for_query = bb_count_last_query();
685
+ } else
686
+ $this->search_errors = new WP_Error( 'no_matching_users_found', __( '<strong>No matching users were found!</strong>' ) );
687
+
688
+ if ( is_wp_error( $this->search_errors ) )
689
+ bb_admin_notice( $this->search_errors );
690
+ }
691
+
692
+ }
693
+
694
+ /* Forums */
695
+
696
+ // Expects forum_name, forum_desc to be pre-escaped
697
+ function bb_new_forum( $args ) {
698
+ global $bbdb;
699
+ if ( !bb_current_user_can( 'manage_forums' ) )
700
+ return false;
701
+
702
+ $defaults = array( 'forum_name' => '', 'forum_desc' => '', 'forum_parent' => 0, 'forum_order' => false, 'forum_is_category' => 0 );
703
+ $args = wp_parse_args( $args, $defaults );
704
+ if ( 1 < func_num_args() ) : // For back compat
705
+ $args['forum_name'] = func_get_arg(0);
706
+ $args['forum_desc'] = func_get_arg(1);
707
+ $args['forum_order'] = 2 < func_num_args() ? func_get_arg(2) : 0;
708
+ endif;
709
+
710
+ extract($args, EXTR_SKIP);
711
+
712
+ if ( !is_numeric($forum_order) )
713
+ $forum_order = (int) $bbdb->get_var("SELECT MAX(forum_order) FROM $bbdb->forums") + 1;
714
+
715
+ $forum_order = (int) $forum_order;
716
+ $forum_parent = (int) $forum_parent;
717
+ $forum_is_category = (int) $forum_is_category;
718
+
719
+ $forum_name = apply_filters( 'bb_pre_forum_name', stripslashes( wp_specialchars_decode( $forum_name, ENT_QUOTES ) ) );
720
+ $forum_desc = apply_filters( 'bb_pre_forum_desc', stripslashes($forum_desc) );
721
+
722
+ if ( strlen($forum_name) < 1 )
723
+ return false;
724
+
725
+ $forum_sql = "SELECT forum_slug FROM $bbdb->forums WHERE forum_slug = %s";
726
+
727
+ $forum_slug = $_forum_slug = bb_slug_sanitize($forum_name);
728
+ if ( strlen($_forum_slug) < 1 )
729
+ return false;
730
+
731
+ while ( is_numeric($forum_slug) || $existing_slug = $bbdb->get_var( $bbdb->prepare( $forum_sql, $forum_slug ) ) )
732
+ $forum_slug = bb_slug_increment($_forum_slug, $existing_slug);
733
+
734
+ $bbdb->insert( $bbdb->forums, compact( 'forum_name', 'forum_slug', 'forum_desc', 'forum_parent', 'forum_order' ) );
735
+ $forum_id = $bbdb->insert_id;
736
+ if ($forum_id && $forum_is_category)
737
+ bb_update_forummeta($forum_id, 'forum_is_category', $forum_is_category);
738
+ wp_cache_flush( 'bb_forums' );
739
+
740
+ return $forum_id;
741
+ }
742
+
743
+ // Expects forum_name, forum_desc to be pre-escaped
744
+ function bb_update_forum( $args ) {
745
+ global $bbdb;
746
+ if ( !bb_current_user_can( 'manage_forums' ) )
747
+ return false;
748
+
749
+ $defaults = array( 'forum_id' => 0, 'forum_name' => '', 'forum_slug' => '', 'forum_desc' => '', 'forum_parent' => 0, 'forum_order' => 0, 'forum_is_category' => 0 );
750
+ $fields = array( 'forum_name', 'forum_desc', 'forum_parent', 'forum_order' );
751
+ $args = wp_parse_args( $args, $defaults );
752
+ if ( 1 < func_num_args() ) : // For back compat
753
+ $args['forum_id'] = func_get_arg(0);
754
+ $args['forum_name'] = func_get_arg(1);
755
+ $args['forum_desc'] = 2 < func_num_args() ? func_get_arg(2) : '';
756
+ $args['forum_order'] = 3 < func_num_args() && is_numeric(func_get_arg(3)) ? func_get_arg(3) : 0;
757
+ endif;
758
+
759
+ extract($args, EXTR_SKIP);
760
+
761
+ if ( !$forum_id = (int) $forum_id )
762
+ return false;
763
+ if ( !$forum = bb_get_forum( $forum_id ) )
764
+ return false;
765
+ $forum_order = (int) $forum_order;
766
+ $forum_parent = (int) $forum_parent;
767
+ $forum_is_category = (int) $forum_is_category;
768
+
769
+ $forum_name = apply_filters( 'bb_pre_forum_name', stripslashes( wp_specialchars_decode( $forum_name, ENT_QUOTES ) ), $forum_id );
770
+ $forum_desc = apply_filters( 'bb_pre_forum_desc', stripslashes($forum_desc), $forum_id );
771
+
772
+ if ( strlen($forum_name) < 1 )
773
+ return false;
774
+
775
+ // Slug is not changing, don't update it
776
+ if ( !$forum_slug || $forum_slug == $forum->forum_slug ) {
777
+ // [sic]
778
+ } else {
779
+ $forum_slug = $_forum_slug = bb_slug_sanitize($forum_slug);
780
+ if ( strlen($_forum_slug) < 1 )
781
+ return false;
782
+
783
+ $forum_sql = "SELECT forum_slug FROM $bbdb->forums WHERE forum_slug = %s";
784
+
785
+ while ( is_numeric($forum_slug) || $existing_slug = $bbdb->get_var( $bbdb->prepare( $forum_sql, $forum_slug ) ) )
786
+ $forum_slug = bb_slug_increment($_forum_slug, $existing_slug);
787
+
788
+ $fields[] = 'forum_slug';
789
+ }
790
+
791
+ wp_cache_delete( $forum_id, 'bb_forum' );
792
+ wp_cache_flush( 'bb_forums' );
793
+
794
+ $update_result = $bbdb->update( $bbdb->forums, compact( $fields ), compact( 'forum_id' ) );
795
+
796
+ if ($forum_is_category)
797
+ bb_update_forummeta($forum_id, 'forum_is_category', $forum_is_category);
798
+ else
799
+ bb_delete_forummeta($forum_id, 'forum_is_category');
800
+
801
+ return $update_result;
802
+ }
803
+
804
+ // When you delete a forum, you delete *everything*
805
+ // NOT bbdb::prepared
806
+ function bb_delete_forum( $forum_id ) {
807
+ global $bbdb;
808
+ if ( !bb_current_user_can( 'delete_forum', $forum_id ) )
809
+ return false;
810
+ if ( !$forum_id = (int) $forum_id )
811
+ return false;
812
+
813
+ if ( !$forum = bb_get_forum( $forum_id ) )
814
+ return false;
815
+
816
+ if ( $topic_ids = $bbdb->get_col( $bbdb->prepare( "SELECT topic_id FROM $bbdb->topics WHERE forum_id = %d", $forum_id ) ) ) {
817
+ foreach ($topic_ids as $topic_id) {
818
+ bb_remove_topic_tags( $topic_id );
819
+ }
820
+ $_topic_ids = join(',', array_map('intval', $topic_ids));
821
+ $bbdb->query("DELETE FROM $bbdb->posts WHERE topic_id IN ($_topic_ids) AND topic_id != 0");
822
+ $bbdb->query("DELETE FROM $bbdb->meta WHERE object_type = 'bb_topic' AND object_id IN ($_topic_ids)");
823
+ $bbdb->query( $bbdb->prepare( "DELETE FROM $bbdb->topics WHERE forum_id = %d", $forum_id ) );
824
+ }
825
+
826
+ $bbdb->update( $bbdb->forums, array( 'forum_parent' => $forum->forum_parent ), array( 'forum_parent' => $forum_id ) );
827
+
828
+ $return = $bbdb->query( $bbdb->prepare( "DELETE FROM $bbdb->forums WHERE forum_id = %d", $forum_id ) );
829
+
830
+ wp_cache_flush( 'bb_post' );
831
+
832
+ if ( $topic_ids )
833
+ foreach ( $topic_ids as $topic_id ) {
834
+ // should maybe just flush these groups instead
835
+ wp_cache_delete( $topic_id, 'bb_topic' );
836
+ wp_cache_delete( $topic_id, 'bb_thread' );
837
+ }
838
+
839
+ wp_cache_delete( $forum_id, 'bb_forum' );
840
+ wp_cache_flush( 'bb_forums' );
841
+
842
+ return $return;
843
+ }
844
+
845
+ function bb_forum_row( $forum_id = 0, $echo = true, $close = false ) {
846
+ global $forum, $forums_count;
847
+ if ( $forum_id )
848
+ $_forum = bb_get_forum( $forum_id );
849
+ else
850
+ $_forum =& $forum;
851
+
852
+ if ( !$_forum )
853
+ return;
854
+
855
+ $description = get_forum_description( $_forum->forum_id );
856
+
857
+ $r = '';
858
+ if ( $close )
859
+ $r .= "\t<li id='forum-$_forum->forum_id'" . get_alt_class( 'forum', 'forum clear list-block' ) . ">\n";
860
+ $r .= "\t\t<div class='list-block posrel'>\n";
861
+ $r .= "\t\t\t<div class=\"row-title\">" . get_forum_name( $_forum->forum_id ) . "</div>\n";
862
+ if ( $description )
863
+ $r .= "\t\t\t<p class=\"row-description\">" . get_forum_description( $_forum->forum_id ) . "</p>\n";
864
+ $r .= "\t\t\t<div class=\"row-actions\"><span>\n";
865
+ $r .= "\t\t\t\t<a class='edit' href='" . get_forum_link() . "'>" . __('View') . "</a>\n";
866
+ if ( bb_current_user_can( 'manage_forums' ) )
867
+ $r .= "\t\t\t\t| <a class='edit' href='" . esc_attr( bb_get_uri('bb-admin/forums.php', array('action' => 'edit', 'id' => $_forum->forum_id), BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN) ) . "'>" . __('Edit') . "</a>\n";
868
+ if ( bb_current_user_can( 'delete_forum', $_forum->forum_id ) && 1 < $forums_count )
869
+ $r .= "\t\t\t\t| <a class='delete' href='" . esc_attr( bb_get_uri('bb-admin/forums.php', array('action' => 'delete', 'id' => $_forum->forum_id), BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN) ) . "'>" . __('Delete') . "</a>\n";
870
+ $r .= "\t\t\t</span>&nbsp;</div>\n";
871
+ $r .= "\t\t</div>\n";
872
+ if ( $close )
873
+ $r .= "\t</li>\n";
874
+
875
+ if ( $echo )
876
+ echo $r;
877
+ return $r;
878
+ }
879
+
880
+ function bb_forum_form( $forum_id = 0 ) {
881
+ $forum_id = (int) $forum_id;
882
+ if ( $forum_id && !$forum = bb_get_forum( $forum_id ) ) {
883
+ return;
884
+ }
885
+
886
+ $forum_name = '';
887
+ $forum_slug = '';
888
+ $forum_description = '';
889
+ $forum_position = '';
890
+
891
+ if ( $forum_id ) {
892
+ $forum_name = get_forum_name( $forum_id );
893
+ $forum_slug = $forum->forum_slug;
894
+ $forum_description = get_forum_description( $forum_id );
895
+ $forum_position = get_forum_position( $forum_id );
896
+ $legend = __( 'Edit Forum' );
897
+ $submit = __( 'Save Changes' );
898
+ $action = 'update';
899
+ } else {
900
+ $legend = __( 'Add Forum' );
901
+ $submit = __( 'Add Forum' );
902
+ $action = 'add';
903
+ }
904
+
905
+ $forum_options = array(
906
+ 'forum_name' => array(
907
+ 'title' => __( 'Name' ),
908
+ 'value' => $forum_name
909
+ ),
910
+ 'forum_slug' => array(
911
+ 'title' => __( 'Slug' ),
912
+ 'value' => $forum_slug
913
+ ),
914
+ 'forum_desc' => array(
915
+ 'title' => __( 'Description' ),
916
+ 'value' => $forum_description,
917
+ 'class' => 'long'
918
+ ),
919
+ 'forum_parent' => array(
920
+ 'title' => __( 'Parent' ),
921
+ 'type' => 'select',
922
+ 'options' => bb_get_forum_dropdown( array(
923
+ 'cut_branch' => $forum_id,
924
+ 'id' => 'forum_parent',
925
+ 'none' => true,
926
+ 'selected' => $forum_id ? get_forum_parent( $forum_id ) : 0,
927
+ 'disable_categories' => 0,
928
+ 'options_only' => true
929
+ ) )
930
+ ),
931
+ 'forum_order' => array(
932
+ 'title' => __( 'Position' ),
933
+ 'value' => $forum_position,
934
+ 'class' => 'short'
935
+ ),
936
+ 'forum_is_category' => array(
937
+ 'title' => __( 'Category' ),
938
+ 'type' => 'checkbox',
939
+ 'options' => array(
940
+ 1 => array(
941
+ 'label' => __( 'Make this forum a category' ),
942
+ 'value' => bb_get_forum_is_category( $forum_id ),
943
+ )
944
+ ),
945
+ 'note' => __( 'Categories are forums where new topics cannot be created. Categories usually contain a group of sub-forums.' )
946
+ )
947
+ );
948
+
949
+ if ( !$forum_id ) {
950
+ unset( $forum_options['forum_slug'] );
951
+ unset( $forum_options['forum_order'] );
952
+ }
953
+
954
+ ?>
955
+ <form class="settings" method="post" id="<?php echo $action; ?>-forum" action="<?php bb_uri('bb-admin/bb-forum.php', null, BB_URI_CONTEXT_FORM_ACTION + BB_URI_CONTEXT_BB_ADMIN); ?>" class="add:forum-list: forum-form">
956
+ <fieldset>
957
+ <legend><?php echo $legend; ?></legend>
958
+ <?php
959
+ foreach ( $forum_options as $option => $args ) {
960
+ bb_option_form_element( $option, $args );
961
+ }
962
+ ?>
963
+ <fieldset class="submit">
964
+ <?php if ( $forum_id ) : ?>
965
+ <input type="hidden" name="forum_id" value="<?php echo $forum_id; ?>" />
966
+ <?php endif; ?>
967
+ <?php bb_nonce_field( 'order-forums', 'order-nonce' ); ?>
968
+ <?php bb_nonce_field( $action . '-forum' ); ?>
969
+ <input type="hidden" name="action" value="<?php echo $action; ?>" />
970
+ <input class="submit" type="submit" name="submit" value="<?php echo $submit; ?>" />
971
+ </fieldset>
972
+ </form>
973
+ <?php
974
+ }
975
+
976
+ class BB_Walker_ForumAdminlistitems extends BB_Walker {
977
+ var $tree_type = 'forum';
978
+ var $db_fields = array ('parent' => 'forum_parent', 'id' => 'forum_id'); //TODO: decouple this
979
+
980
+ function start_lvl($output, $depth) {
981
+ $indent = str_repeat("\t", $depth) . ' ';
982
+ $output .= $indent . "<ul id='forum-root-$this->forum_id' class='list-block holder'>\n";
983
+ return $output;
984
+ }
985
+
986
+ function end_lvl($output, $depth) {
987
+ $indent = str_repeat("\t", $depth) . ' ';
988
+ $output .= $indent . "</ul>\n";
989
+ return $output;
990
+ }
991
+
992
+ function start_el($output, $forum, $depth) {
993
+ $this->forum_id = $forum->forum_id;
994
+ $indent = str_repeat("\t", $depth + 1);
995
+ $output .= $indent . "<li id='forum-$this->forum_id'" . get_alt_class( 'forum', 'forum clear list-block' ) . ">\n";
996
+
997
+ return $output;
998
+ }
999
+
1000
+ function end_el($output, $forum, $depth) {
1001
+ $indent = str_repeat("\t", $depth + 1);
1002
+ $output .= $indent . "</li>\n";
1003
+ return $output;
1004
+ }
1005
+ }
1006
+
1007
+
1008
+
1009
+ /* Topics */
1010
+
1011
+ function bb_move_forum_topics( $from_forum_id, $to_forum_id ) {
1012
+ global $bbdb;
1013
+
1014
+ $from_forum_id = (int) $from_forum_id ;
1015
+ $to_forum_id = (int) $to_forum_id;
1016
+
1017
+ add_filter('get_forum_where', 'bb_no_where'); // Just in case
1018
+
1019
+ $from_forum = bb_get_forum( $from_forum_id );
1020
+ if ( !$to_forum = bb_get_forum( $to_forum_id ) )
1021
+ return false;
1022
+
1023
+ $posts = $to_forum->posts + ( $from_forum ? $from_forum->posts : 0 );
1024
+ $topics = $to_forum->topics + ( $from_forum ? $from_forum->topics : 0 );
1025
+
1026
+ $bbdb->update( $bbdb->forums, compact( 'topics', 'posts' ), array( 'forum_id' => $to_forum_id ) );
1027
+ $bbdb->update( $bbdb->forums, array( 'topics' => 0, 'posts' => 0 ), array( 'forum_id' => $from_forum_id ) );
1028
+ $bbdb->update( $bbdb->posts, array( 'forum_id' => $to_forum_id ), array( 'forum_id' => $from_forum_id ) );
1029
+ $topic_ids = $bbdb->get_col( $bbdb->prepare( "SELECT topic_id FROM $bbdb->topics WHERE forum_id = %d", $from_forum_id ) );
1030
+ $return = $bbdb->update( $bbdb->topics, array( 'forum_id' => $to_forum_id ), array( 'forum_id' => $from_forum_id ) );
1031
+
1032
+ wp_cache_flush( 'bb_post' );
1033
+
1034
+ if ( $topic_ids )
1035
+ foreach ( $topic_ids as $topic_id ) {
1036
+ // should maybe just flush these groups
1037
+ wp_cache_delete( $topic_id, 'bb_topic' );
1038
+ wp_cache_delete( $topic_id, 'bb_thread' );
1039
+ }
1040
+
1041
+ wp_cache_delete( $from_forum_id, 'bb_forum' );
1042
+ wp_cache_delete( $to_forum_id, 'bb_forum' );
1043
+ wp_cache_flush( 'bb_forums' );
1044
+
1045
+ return $return;
1046
+ }
1047
+
1048
+ /* Posts */
1049
+
1050
+ function bb_admin_list_posts() {
1051
+ global $bb_posts, $bb_post;
1052
+
1053
+ if ( !$bb_posts ) {
1054
+ ?>
1055
+ <p class="no-results"><?php _e('No posts found.'); ?></p>
1056
+ <?php
1057
+ } else {
1058
+ ?>
1059
+ <table id="posts-list" class="widefat" cellspacing="0" cellpadding="0">
1060
+ <thead>
1061
+ <tr>
1062
+ <th scope="col"><?php _e( 'Post' ); ?></th>
1063
+ <th scope="col"><?php _e( 'Author' ); ?></th>
1064
+ <th scope="col"><?php _e( 'Topic' ); ?></th>
1065
+ <th scope="col"><?php _e( 'Date' ); ?></th>
1066
+ </tr>
1067
+ </thead>
1068
+ <tfoot>
1069
+ <tr>
1070
+ <th scope="col"><?php _e( 'Post' ); ?></th>
1071
+ <th scope="col"><?php _e( 'Author' ); ?></th>
1072
+ <th scope="col"><?php _e( 'Topic' ); ?></th>
1073
+ <th scope="col"><?php _e( 'Date' ); ?></th>
1074
+ </tr>
1075
+ </tfoot>
1076
+ <tbody>
1077
+ <?php
1078
+ foreach ( $bb_posts as $bb_post ) {
1079
+ ?>
1080
+ <tr id="post-<?php post_id(); ?>"<?php alt_class('post', post_del_class()); ?>>
1081
+ <td class="post">
1082
+ <?php post_text(); ?>
1083
+ <div>
1084
+ <span class="row-actions">
1085
+ <a href="<?php echo esc_url( get_post_link() ); ?>"><?php _e( 'View' ); ?></a>
1086
+ <?php
1087
+ bb_post_admin( array(
1088
+ 'before_each' => ' | ',
1089
+ 'each' => array(
1090
+ 'undelete' => array(
1091
+ 'before' => ' '
1092
+ )
1093
+ ),
1094
+ 'last_each' => array(
1095
+ 'before' => ' | '
1096
+ )
1097
+ ) );
1098
+ ?>
1099
+ </span>&nbsp;
1100
+ </div>
1101
+ </td>
1102
+
1103
+ <td class="author">
1104
+ <a href="<?php user_profile_link( get_post_author_id() ); ?>">
1105
+ <?php post_author_avatar( '16' ); ?>
1106
+ <?php post_author(); ?>
1107
+ </a>
1108
+ </td>
1109
+
1110
+ <td class="topic">
1111
+ <a href="<?php topic_link( $bb_post->topic_id ); ?>"><?php topic_title( $bb_post->topic_id ); ?></a>
1112
+ </td>
1113
+
1114
+ <td class="date">
1115
+ <?php
1116
+ if ( bb_get_post_time( 'U' ) < ( time() - 86400 ) ) {
1117
+ bb_post_time( 'Y/m/d\<\b\r \/\>H:i:s' );
1118
+ } else {
1119
+ printf( __( '%s ago' ), bb_get_post_time( 'since' ) );
1120
+ }
1121
+ ?>
1122
+ </td>
1123
+ </tr>
1124
+ <?php
1125
+ }
1126
+ ?>
1127
+ </tbody>
1128
+ </table>
1129
+ <?php
1130
+ }
1131
+ }
1132
+
1133
+ /* Recounts */
1134
+
1135
+ function bb_recount_list()
1136
+ {
1137
+ global $recount_list;
1138
+ $recount_list = array(
1139
+ 5 => array( 'topic-posts', __( 'Count posts of every topic' ) ),
1140
+ 6 => array( 'topic-voices', __( 'Count voices of every topic' ) ),
1141
+ 10 => array( 'topic-deleted-posts', __( 'Count deleted posts on every topic' ) ),
1142
+ 15 => array( 'forums', __( 'Count topics and posts in every forum' ) ),
1143
+ 20 => array( 'topics-replied', __( 'Count topics to which each user has replied' ) ),
1144
+ 25 => array( 'topic-tag-count', __( 'Count tags for every topic' ) ),
1145
+ 30 => array( 'tags-tag-count', __( 'Count topics for every tag' ) ),
1146
+ 35 => array( 'tags-delete-empty', __( 'Delete tags with no topics' ) ),
1147
+ 40 => array( 'clean-favorites', __( 'Remove deleted topics from users\' favorites' ) )
1148
+ );
1149
+ do_action( 'bb_recount_list' );
1150
+ ksort( $recount_list );
1151
+ return $recount_list;
1152
+ }
1153
+
1154
+ /* Themes */
1155
+
1156
+ function bb_get_current_theme_data( $property = 'all' ) {
1157
+ if (!$property) {
1158
+ $property = 'all';
1159
+ }
1160
+ $directory = bb_get_active_theme_directory();
1161
+ $stylesheet = $directory . 'style.css';
1162
+ if (file_exists($stylesheet)) {
1163
+ $data = bb_get_theme_data($stylesheet);
1164
+ }
1165
+ if ($property == 'all') {
1166
+ return $data;
1167
+ } elseif (isset($data[$property])) {
1168
+ return $data[$property];
1169
+ } else {
1170
+ return false;
1171
+ }
1172
+ }
1173
+
1174
+ // Output sanitized for display
1175
+ function bb_get_theme_data( $theme_file )
1176
+ {
1177
+ if ( strpos($theme_file, '#') !== false ) {
1178
+ $theme_file = bb_get_theme_directory( $theme_file ) . 'style.css';
1179
+ }
1180
+ $theme_code = implode( '', file( $theme_file ) );
1181
+ $theme_code = str_replace ( '\r', '\n', $theme_code );
1182
+ // Grab just the first commented area from the file
1183
+ preg_match( '|/\*(.*)\*/|msU', $theme_code, $theme_block );
1184
+ $theme_data = trim( $theme_block[1] );
1185
+ preg_match( '|Theme Name:(.*)|i', $theme_data, $theme_name );
1186
+ preg_match( '|Theme URI:(.*)|i', $theme_data, $theme_uri );
1187
+ preg_match( '|Description:(.*)|i', $theme_data, $description );
1188
+ preg_match( '|Author:(.*)|i', $theme_data, $author_name );
1189
+ preg_match( '|Author URI:(.*)|i', $theme_data, $author_uri );
1190
+ preg_match( '|Ported By:(.*)|i', $theme_data, $porter_name );
1191
+ preg_match( '|Porter URI:(.*)|i', $theme_data, $porter_uri );
1192
+ // preg_match( '|Template:(.*)|i', $theme_data, $template );
1193
+ if ( preg_match( '|Version:(.*)|i', $theme_data, $version ) )
1194
+ $version = esc_html( trim( $version[1] ) );
1195
+ else
1196
+ $version ='';
1197
+ if ( preg_match('|Status:(.*)|i', $theme_data, $status) )
1198
+ $status = esc_html( trim($status[1]) );
1199
+ else
1200
+ $status = 'publish';
1201
+
1202
+ $description = trim($description[1]);
1203
+ $description = bb_encode_bad( $description );
1204
+ $description = bb_code_trick( $description );
1205
+ $description = force_balance_tags( $description );
1206
+ $description = bb_filter_kses( $description );
1207
+ $description = bb_autop( $description );
1208
+
1209
+ $name = $theme_name[1];
1210
+ $name = esc_html( trim($name) );
1211
+ $theme = $name;
1212
+
1213
+ if ( $author_name || $author_uri ) {
1214
+ if ( empty($author_uri[1]) ) {
1215
+ $author = bb_filter_kses( trim($author_name[1]) );
1216
+ } else {
1217
+ $author = '<a href="' . esc_url( trim($author_uri[1]) ) . '" title="' . esc_attr__( 'Visit author homepage' ) . '">' . bb_filter_kses( trim($author_name[1]) ) . '</a>';
1218
+ }
1219
+ } else {
1220
+ $author = '';
1221
+ }
1222
+
1223
+ if ( $porter_name || $porter_uri ) {
1224
+ if ( empty($porter_uri[1]) ) {
1225
+ $porter = bb_filter_kses( trim($porter_name[1]) );
1226
+ } else {
1227
+ $porter = '<a href="' . esc_url( trim($porter_uri[1]) ) . '" title="' . esc_attr__( 'Visit porter homepage' ) . '">' . bb_filter_kses( trim($porter_name[1]) ) . '</a>';
1228
+ }
1229
+ } else {
1230
+ $porter = '';
1231
+ }
1232
+
1233
+ global $bb;
1234
+
1235
+ // Normalise the path to the theme
1236
+ $theme_file = str_replace( '\\', '/', $theme_file );
1237
+
1238
+ foreach ( $bb->theme_locations as $_name => $_data ) {
1239
+ $_directory = str_replace( '\\', '/', $_data['dir'] );
1240
+ if ( 0 === strpos( $theme_file, $_directory ) ) {
1241
+ $location = $_name;
1242
+ break;
1243
+ }
1244
+ }
1245
+
1246
+ return array(
1247
+ 'Location' => $location,
1248
+ 'Name' => $name,
1249
+ 'Title' => $theme,
1250
+ 'Description' => $description,
1251
+ 'Author' => $author,
1252
+ 'Porter' => $porter,
1253
+ 'Version' => $version,
1254
+ // 'Template' => $template[1],
1255
+ 'Status' => $status,
1256
+ 'URI' => esc_url( $theme_uri[1] )
1257
+ );
1258
+ }
1259
+
1260
+ if ( !function_exists( 'checked' ) ) :
1261
+ function checked( $checked, $current) {
1262
+ if ( $checked == $current)
1263
+ echo ' checked="checked"';
1264
+ }
1265
+ endif;
1266
+
1267
+ if ( !function_exists( 'selected' ) ) :
1268
+ function selected( $selected, $current) {
1269
+ if ( $selected === $current)
1270
+ echo ' selected="selected"';
1271
+ }
1272
+ endif;
1273
+
1274
+ /* Options */
1275
+
1276
+ function bb_option_form_element( $name = 'name', $args = null ) {
1277
+ global $bb_hardcoded;
1278
+
1279
+ $defaults = array(
1280
+ 'title' => 'title',
1281
+ 'type' => 'text',
1282
+ 'value' => false,
1283
+ 'options' => false,
1284
+ 'message' => false,
1285
+ 'class' => false,
1286
+ 'default' => false,
1287
+ 'before' => '',
1288
+ 'after' => '',
1289
+ 'note' => false,
1290
+ 'attributes' => false,
1291
+ );
1292
+
1293
+ $args = wp_parse_args( $args, $defaults );
1294
+
1295
+ $id = str_replace( array( '_', '[', ']' ), array( '-', '-', '' ), $name );
1296
+ if ( false !== strpos( $name, '[' ) ) {
1297
+ list( $option_name, $option_key ) = preg_split( '/[\[\]]/', $name, -1, PREG_SPLIT_NO_EMPTY );
1298
+ $option = bb_get_option( $option_name );
1299
+ $value = false === $args['value'] ? esc_attr( $option[$option_key] ) : esc_attr( $args['value'] );
1300
+ $hardcoded = isset( $bb_hardcoded[$option_name][$option_key] );
1301
+ } else {
1302
+ $value = false === $args['value'] ? bb_get_form_option( $name ) : esc_attr( $args['value'] );
1303
+ $hardcoded = isset( $bb_hardcoded[$name] );
1304
+ }
1305
+
1306
+ $class = $args['class'] ? (array) $args['class'] : array();
1307
+ array_unshift( $class, $args['type'] );
1308
+ $disabled = $hardcoded ? ' disabled="disabled"' : '';
1309
+
1310
+ if ( $args['attributes'] ) {
1311
+ $attributes = array();
1312
+ foreach ( $args['attributes'] as $k => $v )
1313
+ $attributes[] = "$k='$v'";
1314
+ $attributes = ' ' . join( ' ', $attributes );
1315
+ } else {
1316
+ $attributes = '';
1317
+ }
1318
+
1319
+ ?>
1320
+
1321
+ <div id="option-<?php echo $id; ?>"<?php if ( $hardcoded ) echo ' class="disabled"'; ?>>
1322
+ <?php
1323
+ switch ( $args['type'] ) {
1324
+ case 'radio' :
1325
+ case 'checkbox' :
1326
+ case 'message' :
1327
+ ?>
1328
+ <div class="label">
1329
+ <?php echo $args['title']; ?>
1330
+ </div>
1331
+
1332
+ <?php
1333
+ break;
1334
+ case 'select' :
1335
+ default :
1336
+ ?>
1337
+ <label for="<?php echo $id; ?>">
1338
+ <?php echo $args['title']; ?>
1339
+ </label>
1340
+
1341
+ <?php
1342
+ break;
1343
+ }
1344
+ ?>
1345
+ <div class="inputs">
1346
+
1347
+ <?php
1348
+ if ( $args['before'] ) {
1349
+ echo '<span class="before">' . $args['before'] . '</span>';
1350
+ }
1351
+ switch ( $args['type'] ) {
1352
+ case 'select' :
1353
+ echo "<select$disabled class='" . join( ' ', $class ) . "' name='$name' id='$id'$attributes>\n";
1354
+ if ( is_array( $args['options'] ) ) {
1355
+ foreach ( $args['options'] as $option => $label )
1356
+ echo "\t<option value='$option'" . ( $value == $option ? " selected='selected'" : '' ) . ">$label</option>\n";
1357
+ } elseif ( is_string( $args['options'] ) ) {
1358
+ echo $args['options'] . "\n";
1359
+ }
1360
+ echo "</select>\n";
1361
+ break;
1362
+ case 'radio' :
1363
+ case 'checkbox' :
1364
+ if ( is_array( $args['options'] ) ) {
1365
+ $_id = 0;
1366
+ if ( 'radio' === $args['type'] && !in_array( $value, array_keys( $args['options'] ) ) && empty( $value ) ) {
1367
+ $use_first_value = true;
1368
+ }
1369
+ $type = $args['type'];
1370
+ foreach ( $args['options'] as $option => $label ) {
1371
+ if ( $use_first_value ) {
1372
+ $use_first_value = false;
1373
+ $value = $option;
1374
+ }
1375
+ if ( is_array( $label ) ) {
1376
+ if ( isset( $label['attributes'] ) ) {
1377
+ $attributes = array();
1378
+ foreach ( $label['attributes'] as $k => $v )
1379
+ $attributes[] = "$k='$v'";
1380
+ $attributes = ' ' . join( ' ', $attributes );
1381
+ } else {
1382
+ $attributes = '';
1383
+ }
1384
+ if ( isset( $label['name'] ) ) {
1385
+ $name = $label['name'];
1386
+ $id = str_replace( array( '_', '[', ']' ), array( '-', '-', '' ), $name );
1387
+ $hardcoded = isset( $bb_hardcoded[$name] );
1388
+ }
1389
+ if ( isset( $label['value'] ) ) {
1390
+ $_value = $label['value'];
1391
+ } else {
1392
+ $_value = $args['value'];
1393
+ }
1394
+ $value = false === $_value ? bb_get_form_option( $name ) : esc_attr( $_value );
1395
+ $label = $label['label'];
1396
+ }
1397
+ echo "<label class=\"{$type}s\"><input$disabled type='$type' class='" . join( ' ', $class ) . "' name='$name' id='$id-$_id' value='$option'" . ( $value == $option ? " checked='checked'" : '' ) . "{$attributes} /> $label</label>\n";
1398
+ $_id++;
1399
+ }
1400
+ } elseif ( is_string( $args['options'] ) ) {
1401
+ echo $args['options'] . "\n";
1402
+ }
1403
+ break;
1404
+ case 'message' :
1405
+ if ( $args['message'] ) {
1406
+ echo $args['message'];
1407
+ }
1408
+ break;
1409
+ default :
1410
+ echo "<input$disabled type='$args[type]' class='" . join( ' ', $class ) . "' name='$name' id='$id' value='$value'$attributes />\n";
1411
+ break;
1412
+ }
1413
+ if ( $args['after'] ) {
1414
+ echo '<span class="after">' . $args['after'] . '</span>';
1415
+ }
1416
+
1417
+ if ( $args['note'] ) {
1418
+ foreach ( (array) $args['note'] as $note ) {
1419
+ ?>
1420
+
1421
+ <p><?php echo $note; ?></p>
1422
+
1423
+ <?php
1424
+ }
1425
+ }
1426
+ ?>
1427
+
1428
+ </div>
1429
+ </div>
1430
+
1431
+ <?php
1432
+ }
bp-forums/bbpress/bb-admin/includes/functions.bb-plugin.php ADDED
@@ -0,0 +1,441 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function bb_get_plugins_callback( $type = 'normal', $path, $filename )
4
+ {
5
+ if ( '.php' != substr( $filename, -4 ) ) {
6
+ return false;
7
+ }
8
+
9
+ $data = array( 'autoload' => 0 );
10
+
11
+ if ( $has_underscore = '_' === substr( $filename, 0, 1 ) ) {
12
+ switch ( $type ) {
13
+ case 'all':
14
+ case 'autoload':
15
+ $data['autoload'] = 1;
16
+ break;
17
+ case 'normal':
18
+ default:
19
+ return false;
20
+ break;
21
+ }
22
+ } elseif ( 'autoload' === $type ) {
23
+ return false;
24
+ }
25
+
26
+ if ( $_data = bb_get_plugin_data( $path ) ) {
27
+ return array_merge( $_data , $data );
28
+ }
29
+
30
+ return false;
31
+ }
32
+
33
+ function bb_get_plugins( $location = 'all', $type = 'normal', $status = 'all' )
34
+ {
35
+ static $plugin_cache = array();
36
+
37
+ if ( !in_array( $type, array( 'all', 'autoload', 'normal' ) ) ) {
38
+ $type = 'normal';
39
+ }
40
+
41
+ if ( 'autoload' === $type || !in_array( $status, array( 'all', 'active', 'inactive' ) ) ) {
42
+ $status = 'all';
43
+ }
44
+
45
+ if ( isset( $plugin_cache[$location][$type][$status] ) ) {
46
+ return $plugin_cache[$location][$type][$status];
47
+ }
48
+
49
+ global $bb;
50
+ $directories = array();
51
+ if ( 'all' === $location ) {
52
+ foreach ( $bb->plugin_locations as $_data ) {
53
+ $directories[] = $_data['dir'];
54
+ }
55
+ } elseif ( isset( $bb->plugin_locations[$location]['dir'] ) ) {
56
+ $directories[] = $bb->plugin_locations[$location]['dir'];
57
+ }
58
+
59
+ require_once( BB_PATH . BB_INC . 'class.bb-dir-map.php' );
60
+
61
+ $plugin_arrays = array();
62
+ foreach ( $directories as $directory ) {
63
+ $dir_map = new BB_Dir_Map(
64
+ $directory,
65
+ array(
66
+ 'callback' => 'bb_get_plugins_callback',
67
+ 'callback_args' => array( $type ),
68
+ 'recurse' => 1
69
+ )
70
+ );
71
+ $dir_plugins = $dir_map->get_results();
72
+ $dir_plugins = is_wp_error( $dir_plugins ) ? array() : $dir_plugins;
73
+ $plugin_arrays[] = $dir_plugins;
74
+ unset($dir_map, $dir_plugins);
75
+ }
76
+
77
+ $plugins = array();
78
+ foreach ($plugin_arrays as $plugin_array) {
79
+ $plugins = array_merge($plugins, $plugin_array);
80
+ }
81
+
82
+ $active_plugins = (array) bb_get_option( 'active_plugins' );
83
+
84
+ $adjusted_plugins = array();
85
+ foreach ($plugins as $plugin => $plugin_data) {
86
+ $_id = $plugin_data['location'] . '#' . $plugin;
87
+ $plugin_data['active'] = 0;
88
+ if ( 'autoload' === $type || in_array( $_id, $active_plugins ) ) {
89
+ $plugin_data['active'] = 1;
90
+ }
91
+ if (
92
+ 'active' === $status && $plugin_data['active'] ||
93
+ 'inactive' === $status && !$plugin_data['active'] ||
94
+ 'all' === $status
95
+ ) {
96
+ $adjusted_plugins[$_id] = $plugin_data;
97
+ }
98
+ }
99
+
100
+ uasort( $adjusted_plugins, 'bb_plugins_sort' );
101
+
102
+ $plugin_cache[$location][$type][$status] = $adjusted_plugins;
103
+
104
+ return $adjusted_plugins;
105
+ }
106
+
107
+ function bb_plugins_sort( $a, $b )
108
+ {
109
+ return strnatcasecmp( $a['name'], $b['name'] );
110
+ }
111
+
112
+ function bb_get_plugin_counts()
113
+ {
114
+ $all_plugins = bb_get_plugins( 'all', 'all' );
115
+ $active_plugins = (array) bb_get_option( 'active_plugins' );
116
+ $counts = array(
117
+ 'plugin_count_all' => count( $all_plugins ),
118
+ 'plugin_count_active' => count( $active_plugins ),
119
+ 'plugin_count_inactive' => 0,
120
+ 'plugin_count_autoload' => 0
121
+ );
122
+ foreach ( $all_plugins as $id => $all_plugin ) {
123
+ if ( $all_plugin['autoload'] ) {
124
+ $counts['plugin_count_autoload']++;
125
+ } elseif ( !in_array( $id, $active_plugins ) ) {
126
+ $counts['plugin_count_inactive']++;
127
+ }
128
+ }
129
+ return $counts;
130
+ }
131
+
132
+ /**
133
+ * Parse the plugin contents to retrieve plugin's metadata.
134
+ *
135
+ * The metadata of the plugin's data searches for the following in the plugin's
136
+ * header. All plugin data must be on its own line. For plugin description, it
137
+ * must not have any newlines or only parts of the description will be displayed
138
+ * and the same goes for the plugin data. The below is formatted for printing.
139
+ *
140
+ * <code>
141
+ * /*
142
+ * Plugin Name: Name of Plugin
143
+ * Plugin URI: Link to plugin information
144
+ * Description: Plugin Description
145
+ * Author: Plugin author's name
146
+ * Author URI: Link to the author's web site
147
+ * Version: Must be set
148
+ * Requires at least: Optional. Minimum bbPress version this plugin requires
149
+ * Tested up to: Optional. Maximum bbPress version this plugin has been tested with
150
+ * Text Domain: Optional. Unique identifier, should be same as the one used in
151
+ * bb_load_plugin_textdomain()
152
+ * Domain Path: Optional. Only useful if the translations are located in a
153
+ * folder above the plugin's base path. For example, if .mo files are
154
+ * located in the locale folder then Domain Path will be "/locale/" and
155
+ * must have the first slash. Defaults to the base folder the plugin is
156
+ * located in.
157
+ * * / # You must remove the space to close comment (the space is here only for documentation purposes).
158
+ * </code>
159
+ *
160
+ * Plugin data returned array contains the following:
161
+ * 'location' - Location of plugin file
162
+ * 'name' - Name of the plugin, must be unique.
163
+ * 'uri' - Plugin's web site.
164
+ * 'plugin_link' - Title of plugin linked to plugin's web site.
165
+ * 'description' - Description of what the plugin does and/or notes
166
+ * from the author.
167
+ * 'author' - The author's name
168
+ * 'author_uri' - The author's web site address.
169
+ * 'author_link' - The author's name linked to the author's web site.
170
+ * 'version' - The plugin version number.
171
+ * 'requires' - Minimum bbPress version plugin requires
172
+ * 'tested' - Maximum bbPress version plugin has been tested with
173
+ * 'text_domain' - Plugin's text domain for localization.
174
+ * 'domain_path' - Plugin's relative directory path to .mo files.
175
+ *
176
+ * Some users have issues with opening large files and manipulating the contents
177
+ * for want is usually the first 1kiB or 2kiB. This function stops pulling in
178
+ * the plugin contents when it has all of the required plugin data.
179
+ *
180
+ * The first 8kiB of the file will be pulled in and if the plugin data is not
181
+ * within that first 8kiB, then the plugin author should correct their plugin
182
+ * and move the plugin data headers to the top.
183
+ *
184
+ * The plugin file is assumed to have permissions to allow for scripts to read
185
+ * the file. This is not checked however and the file is only opened for
186
+ * reading.
187
+ *
188
+ * @link http://trac.wordpress.org/ticket/5651 Previous Optimizations.
189
+ * @link http://trac.wordpress.org/ticket/7372 Further and better Optimizations.
190
+ * @since 1.5.0
191
+ *
192
+ * @param string $plugin_file Path to the plugin file
193
+ * @param bool $markup If the returned data should have HTML markup applied
194
+ * @param bool $translate If the returned data should be translated
195
+ * @return array See above for description.
196
+ */
197
+ function bb_get_plugin_data( $plugin_file, $markup = true, $translate = true ) {
198
+ global $bb;
199
+
200
+ if ( preg_match( '/^([a-z0-9_-]+)#((?:[a-z0-9\/\\_-]+.)+)(php)$/i', $plugin_file, $_matches ) ) {
201
+ $plugin_file = $bb->plugin_locations[$_matches[1]]['dir'] . $_matches[2] . $_matches[3];
202
+
203
+ $_directory = $bb->plugin_locations[$_matches[1]]['dir'];
204
+ $_plugin = $_matches[2] . $_matches[3];
205
+
206
+ if ( !$_plugin ) {
207
+ // Not likely
208
+ return false;
209
+ }
210
+
211
+ if ( validate_file( $_plugin ) ) {
212
+ // $plugin has .., :, etc.
213
+ return false;
214
+ }
215
+
216
+ $plugin_file = $_directory . $_plugin;
217
+ unset( $_matches, $_directory, $_plugin );
218
+ }
219
+
220
+ if ( !file_exists( $plugin_file ) ) {
221
+ // The plugin isn't there
222
+ return false;
223
+ }
224
+
225
+ // We don't need to write to the file, so just open for reading.
226
+ $fp = fopen($plugin_file, 'r');
227
+
228
+ // Pull only the first 8kiB of the file in.
229
+ $plugin_code = fread( $fp, 8192 );
230
+
231
+ // PHP will close file handle, but we are good citizens.
232
+ fclose($fp);
233
+
234
+ // Grab just the first commented area from the file
235
+ if ( !preg_match( '|/\*(.*?Plugin Name:.*?)\*/|ims', $plugin_code, $plugin_block ) )
236
+ return false;
237
+ $plugin_data = trim( $plugin_block[1] );
238
+
239
+ preg_match( '|Plugin Name:(.*)$|mi', $plugin_data, $name );
240
+ preg_match( '|Plugin URI:(.*)$|mi', $plugin_data, $uri );
241
+ preg_match( '|Version:(.*)|i', $plugin_data, $version );
242
+ preg_match( '|Description:(.*)$|mi', $plugin_data, $description );
243
+ preg_match( '|Author:(.*)$|mi', $plugin_data, $author );
244
+ preg_match( '|Author URI:(.*)$|mi', $plugin_data, $author_uri );
245
+ preg_match( '|Text Domain:(.*)$|mi', $plugin_data, $text_domain );
246
+ preg_match( '|Domain Path:(.*)$|mi', $plugin_data, $domain_path );
247
+ preg_match( '|Requires at least:(.*)$|mi', $plugin_data, $requires );
248
+ preg_match( '|Tested up to:(.*)$|mi', $plugin_data, $tested );
249
+
250
+ // Normalise the path to the plugin
251
+ $plugin_file = str_replace( '\\', '/', $plugin_file );
252
+
253
+ foreach ( $bb->plugin_locations as $_name => $_data ) {
254
+ $_directory = str_replace( '\\', '/', $_data['dir'] );
255
+ if ( 0 === strpos( $plugin_file, $_directory ) ) {
256
+ $location = array( 1 => $_name );
257
+ break;
258
+ }
259
+ }
260
+
261
+ $plugins_allowedtags = array('a' => array('href' => array(),'title' => array()),'abbr' => array('title' => array()),'acronym' => array('title' => array()),'code' => array(),'em' => array(),'strong' => array());
262
+
263
+ $fields = array(
264
+ 'location' => '',
265
+ 'name' => 'html',
266
+ 'uri' => 'url',
267
+ 'version' => 'text',
268
+ 'description' => 'html',
269
+ 'author' => 'html',
270
+ 'author_uri' => 'url',
271
+ 'text_domain' => '',
272
+ 'domain_path' => '',
273
+ 'requires' => 'text',
274
+ 'tested' => 'text',
275
+ );
276
+ foreach ( $fields as $field => $san ) {
277
+ if ( !empty( ${$field} ) ) {
278
+ ${$field} = trim(${$field}[1]);
279
+ switch ( $san ) {
280
+ case 'html' :
281
+ ${$field} = bb_filter_kses( ${$field} );
282
+ break;
283
+ case 'text' :
284
+ ${$field} = esc_html( ${$field} );
285
+ break;
286
+ case 'url' :
287
+ ${$field} = esc_url( ${$field} );
288
+ break;
289
+ }
290
+ } else {
291
+ ${$field} = '';
292
+ }
293
+ }
294
+
295
+ $plugin_data = compact( array_keys( $fields ) );
296
+
297
+ if ( $translate )
298
+ $plugin_data = _bb_get_plugin_data_translate( $plugin_data );
299
+
300
+ if ( $markup )
301
+ $plugin_data['description'] = bb_autop( preg_replace( '/[\r\n]+/', "\n", trim( $plugin_data['description'] ) ) );
302
+
303
+ $plugin_data['plugin_link'] = ( $plugin_data['uri'] ) ?
304
+ "<a href='{$plugin_data['uri']}' title='" . esc_attr__( 'Visit plugin site' ) . "'>{$plugin_data['name']}</a>" :
305
+ $plugin_data['name'];
306
+ $plugin_data['author_link'] = ( $plugin_data['author'] && $plugin_data['author_uri'] ) ?
307
+ "<a href='{$plugin_data['author_uri']}' title='" . esc_attr__( 'Visit author homepage' ) . "'>{$plugin_data['author']}</a>" :
308
+ $plugin_data['author'];
309
+
310
+ return $plugin_data;
311
+ }
312
+
313
+ function _bb_get_plugin_data_translate( $plugin_data ) {
314
+ //Translate fields
315
+ if( !empty($plugin_data['text_domain']) ) {
316
+ if( ! empty( $plugin_data['domain_path'] ) )
317
+ bb_load_plugin_textdomain($plugin_data['text_domain'], dirname($plugin_file). $plugin_data['domain_path']);
318
+ else
319
+ bb_load_plugin_textdomain($plugin_data['text_domain'], dirname($plugin_file));
320
+
321
+ foreach ( array('name', 'plugin_url', 'description', 'author', 'author_uri', 'version') as $field )
322
+ $plugin_data[$field] = translate($plugin_data[$field], $plugin_data['text_domain']);
323
+ }
324
+
325
+ return $plugin_data;
326
+ }
327
+
328
+ /**
329
+ * Attempts activation of plugin in a "sandbox" and redirects on success.
330
+ *
331
+ * A plugin that is already activated will not attempt to be activated again.
332
+ *
333
+ * The way it works is by setting the redirection to the error before trying to
334
+ * include the plugin file. If the plugin fails, then the redirection will not
335
+ * be overwritten with the success message. Also, the options will not be
336
+ * updated and the activation hook will not be called on plugin error.
337
+ *
338
+ * It should be noted that in no way the below code will actually prevent errors
339
+ * within the file. The code should not be used elsewhere to replicate the
340
+ * "sandbox", which uses redirection to work.
341
+ *
342
+ * If any errors are found or text is outputted, then it will be captured to
343
+ * ensure that the success redirection will update the error redirection.
344
+ *
345
+ * @since 1.0
346
+ *
347
+ * @param string $plugin Plugin path to main plugin file with plugin data.
348
+ * @param string $redirect Optional. URL to redirect to.
349
+ * @return WP_Error|null WP_Error on invalid file or null on success.
350
+ */
351
+ function bb_activate_plugin( $plugin, $redirect = '' ) {
352
+ $active_plugins = (array) bb_get_option( 'active_plugins' );
353
+ $plugin = bb_plugin_basename( trim( $plugin ) );
354
+
355
+ $valid_path = bb_validate_plugin( $plugin );
356
+ if ( is_wp_error( $valid_path ) )
357
+ return $valid_path;
358
+
359
+ if ( in_array( $plugin, $active_plugins ) ) {
360
+ return false;
361
+ }
362
+
363
+ if ( !empty( $redirect ) ) {
364
+ // We'll override this later if the plugin can be included without fatal error
365
+ wp_redirect( add_query_arg( '_scrape_nonce', bb_create_nonce( 'scrape-plugin_' . $plugin ), $redirect ) );
366
+ }
367
+
368
+ ob_start();
369
+ @include( $valid_path );
370
+ // Add to the active plugins array
371
+ $active_plugins[] = $plugin;
372
+ ksort( $active_plugins );
373
+ bb_update_option( 'active_plugins', $active_plugins );
374
+ do_action( 'bb_activate_plugin_' . $plugin );
375
+ ob_end_clean();
376
+
377
+ return $valid_path;
378
+ }
379
+
380
+ /**
381
+ * Deactivate a single plugin or multiple plugins.
382
+ *
383
+ * The deactivation hook is disabled by the plugin upgrader by using the $silent
384
+ * parameter.
385
+ *
386
+ * @since unknown
387
+ *
388
+ * @param string|array $plugins Single plugin or list of plugins to deactivate.
389
+ * @param bool $silent Optional, default is false. Prevent calling deactivate hook.
390
+ */
391
+ function bb_deactivate_plugins( $plugins, $silent = false ) {
392
+ $active_plugins = (array) bb_get_option( 'active_plugins' );
393
+
394
+ if ( !is_array( $plugins ) ) {
395
+ $plugins = array( $plugins );
396
+ }
397
+
398
+ foreach ( $plugins as $plugin ) {
399
+ $plugin = bb_plugin_basename( trim( $plugin ) );
400
+ if ( !in_array( $plugin, $active_plugins ) ) {
401
+ continue;
402
+ }
403
+ // Remove the deactivated plugin
404
+ array_splice( $active_plugins, array_search( $plugin, $active_plugins ), 1 );
405
+ if ( !$silent ) {
406
+ do_action( 'bb_deactivate_plugin_' . $plugin );
407
+ }
408
+ }
409
+
410
+ bb_update_option( 'active_plugins', $active_plugins );
411
+ }
412
+
413
+ /**
414
+ * Validate the plugin path.
415
+ *
416
+ * Checks that the file exists and is valid file.
417
+ *
418
+ * @since 1.0
419
+ * @uses validate_file() to check the passed plugin identifier isn't malformed
420
+ * @uses bb_get_plugin_path() to get the full path of the plugin
421
+ * @uses bb_get_plugins() to get the plugins that actually exist
422
+ *
423
+ * @param string $plugin Plugin Path
424
+ * @param string $location The location of plugin, one of 'user', 'core' or 'all'
425
+ * @param string $type The type of plugin, one of 'all', 'autoload' or 'normal'
426
+ * @return WP_Error|int 0 on success, WP_Error on failure.
427
+ */
428
+ function bb_validate_plugin( $plugin, $location = 'all', $type = 'all' ) {
429
+ if ( validate_file( trim( $plugin ) ) ) {
430
+ return new WP_Error( 'plugin_invalid', __( 'Invalid plugin path.' ) );
431
+ }
432
+ $path = bb_get_plugin_path( trim( $plugin ) );
433
+ if ( !file_exists( $path ) ) {
434
+ return new WP_Error( 'plugin_not_found', __( 'Plugin file does not exist.' ) );
435
+ }
436
+ if ( !in_array( trim( $plugin ), array_keys( bb_get_plugins( $location, $type ) ) ) ) {
437
+ return new WP_Error( 'plugin_not_available', __( 'That type of plugin is not available in the specified location.' ) );
438
+ }
439
+
440
+ return $path;
441
+ }
bp-forums/bbpress/bb-admin/includes/functions.bb-upgrade.php ADDED
@@ -0,0 +1,503 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ function bb_install() {
3
+ require_once( BACKPRESS_PATH . 'class.bp-sql-schema-parser.php' );
4
+ require_once( BB_PATH . 'bb-admin/includes/defaults.bb-schema.php' );
5
+ $alterations = BP_SQL_Schema_Parser::delta( $bbdb, $bb_queries, $bb_schema_ignore );
6
+
7
+ bb_update_db_version();
8
+
9
+ return array_filter($alterations);
10
+ }
11
+
12
+ function bb_upgrade_all() {
13
+ if ( !ini_get('safe_mode') )
14
+ set_time_limit(600);
15
+
16
+ $bb_upgrade = array();
17
+
18
+ // Pre DB Delta
19
+ $bb_upgrade['messages'][] = bb_upgrade_160(); // Break blocked users
20
+ $bb_upgrade['messages'][] = bb_upgrade_170(); // Escaping in usermeta
21
+ $bb_upgrade['messages'][] = bb_upgrade_180(); // Delete users for real
22
+ $bb_upgrade['messages'][] = bb_upgrade_190(); // Move topic_resolved to topicmeta
23
+ $bb_upgrade['messages'][] = bb_upgrade_200(); // Indices
24
+ $bb_upgrade['messages'][] = bb_upgrade_210(); // Convert text slugs to varchar slugs
25
+ $bb_upgrade['messages'][] = bb_upgrade_220(); // remove bb_tagged primary key, add new column and primary key
26
+
27
+ require_once( BACKPRESS_PATH . 'class.bp-sql-schema-parser.php' );
28
+ require_once( BB_PATH . 'bb-admin/includes/defaults.bb-schema.php' );
29
+ $delta = BP_SQL_Schema_Parser::delta( $bbdb, $bb_queries, $bb_schema_ignore );
30
+ if ( is_array( $delta ) ) {
31
+ $bb_upgrade['messages'] = array_merge($bb_upgrade['messages'], $delta['messages']);
32
+ $bb_upgrade['errors'] = $delta['errors'];
33
+ } else {
34
+ $bb_upgrade['errors'] = array();
35
+ }
36
+
37
+ // Post DB Delta
38
+ $bb_upgrade['messages'][] = bb_upgrade_1000(); // Make forum and topic slugs
39
+ $bb_upgrade['messages'][] = bb_upgrade_1010(); // Make sure all forums have a valid parent
40
+ $bb_upgrade['messages'][] = bb_upgrade_1020(); // Add a user_nicename to existing users
41
+ $bb_upgrade['messages'][] = bb_upgrade_1030(); // Move admin_email option to from_email
42
+ $bb_upgrade['messages'][] = bb_upgrade_1040(); // Activate Akismet and bozo plugins and convert active plugins to new convention on upgrade only
43
+ $bb_upgrade['messages'][] = bb_upgrade_1050(); // Update active theme if present
44
+ $bb_upgrade['messages'][] = bb_upgrade_1070(); // trim whitespace from raw_tag
45
+ $bb_upgrade['messages'][] = bb_upgrade_1080(); // Convert tags to taxonomy
46
+ $bb_upgrade['messages'][] = bb_upgrade_1090(); // Add display names
47
+ $bb_upgrade['messages'][] = bb_upgrade_1100(); // Replace forum_stickies index with stickies (#876)
48
+ $bb_upgrade['messages'][] = bb_upgrade_1110(); // Create plugin directory (#1083)
49
+ $bb_upgrade['messages'][] = bb_upgrade_1120(); // Create theme directory (#1083)
50
+
51
+ bb_update_db_version();
52
+ wp_cache_flush();
53
+
54
+ $bb_upgrade['messages'] = array_filter($bb_upgrade['messages']);
55
+ $bb_upgrade['errors'] = array_filter($bb_upgrade['errors']);
56
+
57
+ return $bb_upgrade;
58
+ }
59
+
60
+ function bb_upgrade_process_all_slugs() {
61
+ global $bbdb;
62
+ // Forums
63
+
64
+ $forums = (array) $bbdb->get_results("SELECT forum_id, forum_name FROM $bbdb->forums ORDER BY forum_order ASC" );
65
+
66
+ $slugs = array();
67
+ foreach ( $forums as $forum ) :
68
+ $slug = bb_slug_sanitize( wp_specialchars_decode( $forum->forum_name, ENT_QUOTES ) );
69
+ $slugs[$slug][] = $forum->forum_id;
70
+ endforeach;
71
+
72
+ foreach ( $slugs as $slug => $forum_ids ) :
73
+ foreach ( $forum_ids as $count => $forum_id ) :
74
+ $_slug = $slug;
75
+ $count = - $count; // madness
76
+ if ( is_numeric($slug) || $count )
77
+ $_slug = bb_slug_increment( $slug, $count );
78
+ $bbdb->query("UPDATE $bbdb->forums SET forum_slug = '$_slug' WHERE forum_id = '$forum_id';");
79
+ endforeach;
80
+ endforeach;
81
+ unset($forums, $forum, $slugs, $slug, $_slug, $forum_ids, $forum_id, $count);
82
+
83
+ // Topics
84
+
85
+ $topics = (array) $bbdb->get_results("SELECT topic_id, topic_title FROM $bbdb->topics ORDER BY topic_start_time ASC" );
86
+
87
+ $slugs = array();
88
+ foreach ( $topics as $topic) :
89
+ $slug = bb_slug_sanitize( wp_specialchars_decode( $topic->topic_title, ENT_QUOTES ) );
90
+ $slugs[$slug][] = $topic->topic_id;
91
+ endforeach;
92
+
93
+ foreach ( $slugs as $slug => $topic_ids ) :
94
+ foreach ( $topic_ids as $count => $topic_id ) :
95
+ $_slug = $slug;
96
+ $count = - $count;
97
+ if ( is_numeric($slug) || $count )
98
+ $_slug = bb_slug_increment( $slug, $count );
99
+ $bbdb->query("UPDATE $bbdb->topics SET topic_slug = '$_slug' WHERE topic_id = '$topic_id';");
100
+ endforeach;
101
+ endforeach;
102
+ unset($topics, $topic, $slugs, $slug, $_slug, $topic_ids, $topic_id, $count);
103
+ }
104
+
105
+ // Reversibly break passwords of blocked users.
106
+ function bb_upgrade_160() {
107
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 535 )
108
+ return;
109
+
110
+ require_once( BB_PATH . 'bb-admin/includes/functions.bb-admin.php' );
111
+ $blocked = bb_get_ids_by_role( 'blocked' );
112
+ foreach ( $blocked as $b )
113
+ bb_break_password( $b );
114
+ return 'Done reversibly breaking passwords: ' . __FUNCTION__;
115
+ }
116
+
117
+ function bb_upgrade_170() {
118
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 536 )
119
+ return;
120
+
121
+ global $bbdb;
122
+ foreach ( (array) $bbdb->get_results("SELECT * FROM $bbdb->usermeta WHERE meta_value LIKE '%&quot;%' OR meta_value LIKE '%&#039;%'") as $meta ) {
123
+ $value = str_replace(array('&quot;', '&#039;'), array('"', "'"), $meta->meta_value);
124
+ $value = stripslashes($value);
125
+ bb_update_usermeta( $meta->user_id, $meta->meta_key, $value);
126
+ }
127
+ bb_update_option( 'bb_db_version', 536 );
128
+ return 'Done updating usermeta: ' . __FUNCTION__;
129
+ }
130
+
131
+ function bb_upgrade_180() {
132
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 559 )
133
+ return;
134
+
135
+ global $bbdb;
136
+
137
+ foreach ( (array) $bbdb->get_col("SELECT ID FROM $bbdb->users WHERE user_status = 1") as $user_id )
138
+ bb_delete_user( $user_id );
139
+ bb_update_option( 'bb_db_version', 559 );
140
+ return 'Done clearing deleted users: ' . __FUNCTION__;
141
+ }
142
+
143
+ function bb_upgrade_190() {
144
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 630 )
145
+ return;
146
+
147
+ global $bbdb;
148
+
149
+ $exists = false;
150
+ foreach ( (array) $bbdb->get_col("DESC $bbdb->topics") as $col )
151
+ if ( 'topic_resolved' == $col )
152
+ $exists = true;
153
+ if ( !$exists )
154
+ return;
155
+
156
+ $topics = (array) $bbdb->get_results("SELECT topic_id, topic_resolved FROM $bbdb->topics" );
157
+ foreach ( $topics as $topic )
158
+ bb_update_topicmeta( $topic->topic_id, 'topic_resolved', $topic->topic_resolved );
159
+ unset($topics,$topic);
160
+
161
+ $bbdb->query("ALTER TABLE $bbdb->topics DROP topic_resolved");
162
+
163
+ bb_update_option( 'bb_db_version', 630 );
164
+
165
+ return 'Done converting topic_resolved: ' . __FUNCTION__;
166
+ }
167
+
168
+ function bb_upgrade_200() {
169
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 845 )
170
+ return;
171
+
172
+ global $bbdb;
173
+
174
+ $bbdb->hide_errors();
175
+ $bbdb->query( "DROP INDEX tag_id_index ON $bbdb->tagged" );
176
+ $bbdb->query( "DROP INDEX user_id ON $bbdb->topicmeta" );
177
+ $bbdb->query( "DROP INDEX forum_id ON $bbdb->topics" );
178
+ $bbdb->query( "DROP INDEX topic_time ON $bbdb->topics" );
179
+ $bbdb->query( "DROP INDEX topic_start_time ON $bbdb->topics" );
180
+ $bbdb->query( "DROP INDEX tag_id_index ON $bbdb->tagged" );
181
+ $bbdb->query( "DROP INDEX topic_id ON $bbdb->posts" );
182
+ $bbdb->query( "DROP INDEX poster_id ON $bbdb->posts" );
183
+ $bbdb->show_errors();
184
+
185
+ bb_update_option( 'bb_db_version', 845 );
186
+
187
+ return 'Done removing old indices: ' . __FUNCTION__;
188
+ }
189
+
190
+ // 210 converts text slugs to varchar(255) width slugs (upgrading from alpha version - fires before dbDelta)
191
+ // 1000 Gives new slugs (upgrading from previous release - fires after dbDelta)
192
+ function bb_upgrade_210() {
193
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 846 )
194
+ return;
195
+
196
+ global $bbdb;
197
+
198
+ $bbdb->hide_errors();
199
+ if ( !$bbdb->get_var("SELECT forum_slug FROM $bbdb->forums ORDER BY forum_order ASC LIMIT 1" ) )
200
+ return; // Wait till after dbDelta
201
+ $bbdb->show_errors();
202
+
203
+ bb_upgrade_process_all_slugs();
204
+
205
+ bb_update_option( 'bb_db_version', 846 );
206
+
207
+ return 'Done adding slugs: ' . __FUNCTION__;
208
+ }
209
+
210
+ function bb_upgrade_220() {
211
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1051 )
212
+ return;
213
+
214
+ global $bbdb;
215
+
216
+ $bbdb->query( "ALTER TABLE $bbdb->tagged DROP PRIMARY KEY" );
217
+ $bbdb->query( "ALTER TABLE $bbdb->tagged ADD tagged_id bigint(20) unsigned NOT NULL auto_increment PRIMARY KEY FIRST" );
218
+
219
+ return "Done removing key from $bbdb->tagged: " . __FUNCTION__;
220
+ }
221
+
222
+ function bb_upgrade_1000() { // Give all topics and forums slugs
223
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 846 )
224
+ return;
225
+
226
+ bb_upgrade_process_all_slugs();
227
+
228
+ bb_update_option( 'bb_db_version', 846 );
229
+
230
+ return 'Done adding slugs: ' . __FUNCTION__;;
231
+ }
232
+
233
+ // Make sure all forums have a valid parent
234
+ function bb_upgrade_1010() {
235
+ global $bbdb;
236
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 952 )
237
+ return;
238
+
239
+ $forums = (array) $bbdb->get_results( "SELECT forum_id, forum_parent FROM $bbdb->forums" );
240
+ $forum_ids = (array) $bbdb->get_col( '', 0 );
241
+
242
+ foreach ( $forums as $forum ) {
243
+ if ( $forum->forum_parent && !in_array( $forum->forum_parent, $forum_ids ) )
244
+ $bbdb->query( "UPDATE $bbdb->forums SET forum_parent = 0 WHERE forum_id = '$forum->forum_id'" );
245
+ }
246
+
247
+ bb_update_option( 'bb_db_version', 952 );
248
+
249
+ return 'Done re-parenting orphaned forums: ' . __FUNCTION__;
250
+ }
251
+
252
+ // Add a nicename for existing users if they don't have one already
253
+ function bb_upgrade_1020() {
254
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 977 )
255
+ return;
256
+
257
+ global $bbdb;
258
+
259
+ $users = $bbdb->get_results( "SELECT ID, user_login, user_nicename FROM $bbdb->users WHERE user_nicename IS NULL OR user_nicename = ''" );
260
+
261
+ if ( $users ) {
262
+ foreach ( $users as $user ) {
263
+ $user_nicename = $_user_nicename = bb_user_nicename_sanitize( $user->user_login );
264
+ while ( is_numeric($user_nicename) || $existing_user = bb_get_user_by_nicename( $user_nicename ) )
265
+ $user_nicename = bb_slug_increment($_user_nicename, $existing_user->user_nicename, 50);
266
+
267
+ $bbdb->query( "UPDATE $bbdb->users SET user_nicename = '$user_nicename' WHERE ID = $user->ID;" );
268
+ }
269
+ }
270
+
271
+ bb_update_option( 'bb_db_version', 977 );
272
+
273
+ return 'Done adding nice-names to existing users: ' . __FUNCTION__;
274
+ }
275
+
276
+ // Move admin_email option to from_email
277
+ function bb_upgrade_1030() {
278
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1058 )
279
+ return;
280
+
281
+ $admin_email = bb_get_option('admin_email');
282
+ if ($admin_email) {
283
+ bb_update_option('from_email', $admin_email);
284
+ }
285
+ bb_delete_option('admin_email');
286
+
287
+ bb_update_option( 'bb_db_version', 1058 );
288
+
289
+ return 'Done moving admin_email to from_email: ' . __FUNCTION__;
290
+ }
291
+
292
+ // Activate Akismet and bozo plugins and convert active plugins to new convention on upgrade only
293
+ function bb_upgrade_1040() {
294
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1230 )
295
+ return;
296
+
297
+ // Only do this when upgrading
298
+ if ( defined( 'BB_UPGRADING' ) && BB_UPGRADING ) {
299
+ $plugins = bb_get_option('active_plugins');
300
+ if ( bb_get_option('akismet_key') && !in_array('core#akismet.php', $plugins) ) {
301
+ $plugins[] = 'core#akismet.php';
302
+ }
303
+ if ( !in_array('core#bozo.php', $plugins) ) {
304
+ $plugins[] = 'core#bozo.php';
305
+ }
306
+
307
+ $new_plugins = array();
308
+ foreach ($plugins as $plugin) {
309
+ if (substr($plugin, 0, 5) != 'core#') {
310
+ if ($plugin != 'akismet.php' && $plugin != 'bozo.php') {
311
+ $new_plugins[] = 'user#' . $plugin;
312
+ }
313
+ } else {
314
+ $new_plugins[] = $plugin;
315
+ }
316
+ }
317
+
318
+ bb_update_option( 'active_plugins', $new_plugins );
319
+ }
320
+
321
+ bb_update_option( 'bb_db_version', 1230 );
322
+
323
+ return 'Done activating Akismet and Bozo plugins and converting active plugins to new convention on upgrade only: ' . __FUNCTION__;
324
+ }
325
+
326
+ // Update active theme if present
327
+ function bb_upgrade_1050() {
328
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1234 )
329
+ return;
330
+
331
+ // Only do this when upgrading
332
+ if ( defined( 'BB_UPGRADING' ) && BB_UPGRADING ) {
333
+ if ( $theme = bb_get_option( 'bb_active_theme' ) ) {
334
+ bb_update_option( 'bb_active_theme', bb_theme_basename( $theme ) );
335
+ }
336
+ }
337
+
338
+ bb_update_option( 'bb_db_version', 1234 );
339
+
340
+ return 'Done updating active theme if present: ' . __FUNCTION__;
341
+ }
342
+
343
+ function bb_upgrade_1070() {
344
+ global $bbdb;
345
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1467 )
346
+ return;
347
+
348
+ $bbdb->query( "UPDATE `$bbdb->tags` SET `raw_tag` = TRIM(`raw_tag`)" );
349
+
350
+ bb_update_option( 'bb_db_version', 1467 );
351
+
352
+ return 'Whitespace trimmed from raw_tag: ' . __FUNCTION__;
353
+ }
354
+
355
+ function bb_upgrade_1080() {
356
+ global $bbdb, $wp_taxonomy_object;
357
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1526 )
358
+ return;
359
+
360
+ $offset = 0;
361
+ while ( $tags = (array) $bbdb->get_results( "SELECT * FROM $bbdb->tags LIMIT $offset, 100" ) ) {
362
+ if ( !ini_get('safe_mode') ) set_time_limit(600);
363
+ $wp_taxonomy_object->defer_term_counting(true);
364
+ for ( $i = 0; isset($tags[$i]); $i++ ) {
365
+ $bbdb->insert( $bbdb->terms, array(
366
+ 'name' => $tags[$i]->raw_tag,
367
+ 'slug' => $tags[$i]->tag
368
+ ) );
369
+ $term_id = $bbdb->insert_id;
370
+ $bbdb->insert( $bbdb->term_taxonomy, array(
371
+ 'term_id' => $term_id,
372
+ 'taxonomy' => 'bb_topic_tag',
373
+ 'description' => ''
374
+ ) );
375
+ $term_taxonomy_id = $bbdb->insert_id;
376
+ $topics = (array) $bbdb->get_results( $bbdb->prepare( "SELECT user_id, topic_id FROM $bbdb->tagged WHERE tag_id = %d", $tags[$i]->tag_id ) );
377
+ for ( $j = 0; isset($topics[$j]); $j++ ) {
378
+ $bbdb->insert( $bbdb->term_relationships, array(
379
+ 'object_id' => $topics[$j]->topic_id,
380
+ 'term_taxonomy_id' => $term_taxonomy_id,
381
+ 'user_id' => $topics[$j]->user_id
382
+ ) );
383
+ }
384
+ $wp_taxonomy_object->update_term_count( array( $term_taxonomy_id ), 'bb_topic_tag' );
385
+ }
386
+ $wp_taxonomy_object->defer_term_counting(false);
387
+ $offset += 100;
388
+ }
389
+
390
+ bb_update_option( 'bb_db_version', 1526 );
391
+
392
+ return 'Tags copied to taxonomy tables: ' . __FUNCTION__;
393
+ }
394
+
395
+ function bb_upgrade_1090() {
396
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1589 )
397
+ return;
398
+
399
+ global $bbdb;
400
+
401
+ $users = (array) $bbdb->get_results( "SELECT `ID`, `user_login` FROM $bbdb->users WHERE `display_name` = '' OR `display_name` IS NULL;" );
402
+
403
+ if ($users) {
404
+ foreach ($users as $user) {
405
+ $bbdb->query( "UPDATE $bbdb->users SET `display_name` = '" . $user->user_login . "' WHERE ID = " . $user->ID . ";" );
406
+ }
407
+ unset($user, $users);
408
+ }
409
+
410
+ bb_update_option( 'bb_db_version', 1589 );
411
+
412
+ return 'Display names populated: ' . __FUNCTION__;
413
+ }
414
+
415
+ function bb_upgrade_1100() {
416
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1638 )
417
+ return;
418
+
419
+ global $bbdb;
420
+
421
+ $bbdb->query( "DROP INDEX forum_stickies ON $bbdb->topics" );
422
+
423
+ bb_update_option( 'bb_db_version', 1638 );
424
+
425
+ return 'Index forum_stickies dropped: ' . __FUNCTION__;
426
+ }
427
+
428
+ function bb_upgrade_1110() {
429
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 2077 )
430
+ return;
431
+
432
+ // No matter what happens, update the db version
433
+ bb_update_option( 'bb_db_version', 2077 );
434
+
435
+ if ( !defined( 'BB_PLUGIN_DIR' ) ) {
436
+ return;
437
+ }
438
+
439
+ if ( !BB_PLUGIN_DIR ) {
440
+ return;
441
+ }
442
+
443
+ if ( file_exists( BB_PLUGIN_DIR ) ) {
444
+ return;
445
+ }
446
+
447
+ // Just suppress errors as this is not critical
448
+ if ( @mkdir( BB_PLUGIN_DIR, 0755 ) ) {
449
+ return 'Making plugin directory at ' . BB_PLUGIN_DIR . ': ' . __FUNCTION__;
450
+ }
451
+
452
+ return;
453
+ }
454
+
455
+ function bb_upgrade_1120() {
456
+ if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 2078 ) {
457
+ return;
458
+ }
459
+
460
+ // No matter what happens, update the db version
461
+ bb_update_option( 'bb_db_version', 2078 );
462
+
463
+ if ( !defined( 'BB_THEME_DIR' ) ) {
464
+ return;
465
+ }
466
+
467
+ if ( !BB_THEME_DIR ) {
468
+ return;
469
+ }
470
+
471
+ if ( file_exists( BB_THEME_DIR ) ) {
472
+ return;
473
+ }
474
+
475
+ // Just suppress errors as this is not critical
476
+ if ( @mkdir( BB_THEME_DIR, 0755 ) ) {
477
+ return 'Making theme directory at ' . BB_THEME_DIR . ': ' . __FUNCTION__;
478
+ }
479
+
480
+ return;
481
+ }
482
+
483
+ function bb_deslash($content) {
484
+ // Note: \\\ inside a regex denotes a single backslash.
485
+
486
+ // Replace one or more backslashes followed by a single quote with
487
+ // a single quote.
488
+ $content = preg_replace("/\\\+'/", "'", $content);
489
+
490
+ // Replace one or more backslashes followed by a double quote with
491
+ // a double quote.
492
+ $content = preg_replace('/\\\+"/', '"', $content);
493
+
494
+ // Replace one or more backslashes with one backslash.
495
+ $content = preg_replace("/\\\+/", "\\", $content);
496
+
497
+ return $content;
498
+ }
499
+
500
+ function bb_update_db_version() {
501
+ bb_update_option( 'bb_db_version', bb_get_option( 'bb_db_version' ) );
502
+ }
503
+ ?>
bp-forums/bbpress/bb-admin/index.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once('admin.php');
3
+ require_once( BB_PATH . BB_INC . 'functions.bb-statistics.php' );
4
+
5
+ $rn_forums = get_total_forums();
6
+ $rn_forums = sprintf(__ngettext('<span>%d</span> forum', '<span>%d</span> forums', $rn_forums), $rn_forums);
7
+
8
+ $rn_topics = get_total_topics();
9
+ $rn_topics = sprintf(__ngettext('<span>%d</span> topic', '<span>%d</span> topics', $rn_topics), $rn_topics);
10
+
11
+ $rn_posts = get_total_posts();
12
+ $rn_posts = sprintf(__ngettext('<span>%d</span> post', '<span>%d</span> posts', $rn_posts), $rn_posts);
13
+
14
+ $rn_users = bb_get_total_users();
15
+ $rn_users = sprintf(__ngettext('<span>%d</span> user', '<span>%d</span> users', $rn_users), $rn_users);
16
+
17
+ $rn_topic_tags = bb_get_total_topic_tags();
18
+ $rn_topic_tags = sprintf(__ngettext('<span>%d</span> tag', '<span>%d</span> tags', $rn_topic_tags), $rn_topic_tags);
19
+
20
+ $rn_topics_average = get_topics_per_day();
21
+ $rn_topics_average = sprintf(__ngettext('<span>%d</span> topic', '<span>%d</span> topics', $rn_topics_average), $rn_topics_average);
22
+
23
+ $rn_posts_average = get_posts_per_day();
24
+ $rn_posts_average = sprintf(__ngettext('<span>%d</span> post', '<span>%d</span> posts', $rn_posts_average), $rn_posts_average);
25
+
26
+ $rn_users_average = get_registrations_per_day();
27
+ $rn_users_average = sprintf(__ngettext('<span>%d</span> user', '<span>%d</span> users', $rn_users_average), $rn_users_average);
28
+
29
+ $rn_topic_tags_average = bb_get_topic_tags_per_day();
30
+ $rn_topic_tags_average = sprintf(__ngettext('<span>%d</span> tag', '<span>%d</span> tags', $rn_topic_tags_average), $rn_topic_tags_average);
31
+
32
+ $bb_admin_body_class = ' bb-admin-dashboard';
33
+
34
+ bb_get_admin_header();
35
+ ?>
36
+
37
+ <div class="wrap">
38
+ <h2><?php _e('Dashboard'); ?></h2>
39
+ <?php do_action( 'bb_admin_notices' ); ?>
40
+
41
+ <div id="dashboard-right-now" class="dashboard">
42
+ <h3><?php _e('Right Now'); ?></h3>
43
+ <div class="table">
44
+ <table cellpadding="0" cellspacing="0">
45
+ <thead>
46
+ <tr>
47
+ <th><?php _e( 'Totals' ); ?></th>
48
+ <th><?php _e( 'Per Day' ); ?></th>
49
+ </tr>
50
+ </thead>
51
+ <tbody>
52
+ <tr>
53
+ <td><?php echo $rn_forums; ?></td>
54
+ <td>-</td>
55
+ </tr>
56
+ <tr>
57
+ <td><?php echo $rn_topics; ?></td>
58
+ <td><?php echo $rn_topics_average; ?></td>
59
+ </tr>
60
+ <tr>
61
+ <td><?php echo $rn_posts; ?></td>
62
+ <td><?php echo $rn_posts_average; ?></td>
63
+ </tr>
64
+ <tr>
65
+ <td><?php echo $rn_topic_tags; ?></td>
66
+ <td><?php echo $rn_topic_tags_average; ?></td>
67
+ </tr>
68
+ <tr>
69
+ <td><?php echo $rn_users; ?></td>
70
+ <td><?php echo $rn_users_average; ?></td>
71
+ </tr>
72
+ </tbody>
73
+ </table>
74
+ </div>
75
+
76
+ <div class="versions">
77
+ <p class="theme"><a class="button" href="<?php bb_uri( 'bb-admin/themes.php', null, BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN ); ?>"><?php _e( 'Change Theme' ); ?></a><?php printf ( __( 'Theme <a href="%1$s">%2$s</a>' ), bb_get_uri( 'bb-admin/themes.php', null, BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN ), bb_get_current_theme_data( 'Name' ) ); ?></p>
78
+ <p class="bbpress"><?php printf( __( 'You are using <span class="b">bbPress %s</span>' ), bb_get_option( 'version' ) ); ?></p>
79
+ </div>
80
+ </div>
81
+
82
+ <div id="dashboard-moderated" class="dashboard">
83
+ <h3><?php _e('Recently Moderated Items'); ?></h3>
84
+ <?php if ( $objects = bb_get_recently_moderated_objects() ) : ?>
85
+ <ul class="posts">
86
+ <?php add_filter( 'get_topic_where', 'bb_no_where' ); foreach ( $objects as $object ) : ?>
87
+ <?php if ( 'post' == $object['type'] ) : global $bb_post; $bb_post = $object['data']; ?>
88
+ <li>
89
+ <?php
90
+ printf(
91
+ __( '<a href="%1$s">Post</a> on <a href="%2$s">%3$s</a> by <a href="%4$s">%5$s</a>' ),
92
+ esc_attr( add_query_arg( 'view', 'all', get_post_link() ) ),
93
+ get_topic_link( $bb_post->topic_id ),
94
+ get_topic_title( $bb_post->topic_id ),
95
+ get_user_profile_link( $bb_post->poster_id ),
96
+ get_post_author()
97
+ );
98
+ ?>
99
+ </li>
100
+ <?php elseif ( 'topic' == $object['type'] ) : global $topic; $topic = $object['data']; ?>
101
+ <li>
102
+ <?php
103
+ printf(
104
+ __( 'Topic titled <a href="%1$s">%2$s</a> started by <a href="%3$s">%4$s</a>' ),
105
+ esc_attr( add_query_arg( 'view', 'all', get_topic_link() ) ),
106
+ get_topic_title(),
107
+ get_user_profile_link( $topic->topic_poster ),
108
+ get_topic_author()
109
+ );
110
+ ?>
111
+ </li>
112
+ <?php endif; endforeach; remove_filter( 'get_topic_where', 'bb_no_where' ); ?>
113
+ </ul>
114
+ <?php else : ?>
115
+ <p>
116
+ <?php _e('No moderated posts or topics&#8230; you must have very well behaved members.'); ?>
117
+ </p>
118
+ <?php endif; ?>
119
+ </div>
120
+ <div class="clear"></div>
121
+ </div>
122
+
123
+ <?php bb_get_admin_footer(); ?>
bp-forums/bbpress/bb-admin/install-rtl.css ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ font-family: Tahoma, "Times New Roman";
3
+ }
4
+
5
+ div#container {
6
+ text-align: right;
7
+ }
8
+
9
+ dl {
10
+ border-left-width: 0;
11
+ border-right: 1px solid rgb(125, 125, 125);
12
+ margin-right: 2.5em;
13
+ margin-left: 0;
14
+ }
15
+
16
+ dt {
17
+ padding-right: 0.6em;
18
+ padding-left: 0;
19
+ }
20
+
21
+ dd {
22
+ padding-right: 3.6em;
23
+ padding-left: 0;
24
+ }
25
+
26
+ p.status {
27
+ right: auto;
28
+ left: 0;
29
+ text-shadow: none;
30
+ }
31
+
32
+ h2 {
33
+ text-shadow: none;
34
+ }
35
+
36
+ label a.note-toggle {
37
+ float: right;
38
+ padding-left: 0;
39
+ width: 18px;
40
+ margin-left: 0;
41
+ margin-right: 6px;
42
+ }
43
+
44
+ label.has-note.for-textarea a.note-toggle {
45
+ margin-left: 0;
46
+ margin-right: 6px;
47
+ }
48
+
49
+ label.has-note.for-select a.note-toggle {
50
+ margin-left: 0;
51
+ margin-right: 4px;
52
+ }
53
+
54
+ label.has-note.for-toggle a.note-toggle {
55
+ margin-left: 0;
56
+ margin-right: 6px;
57
+ }
58
+
59
+ label.for-textarea span,
60
+ label.for-toggle span {
61
+ float: right;
62
+ }
63
+
64
+ label span.error {
65
+ margin-right: 3em;
66
+ margin-left: 0.4em;
67
+ }
68
+
69
+ fieldset.buttons label.forward {
70
+ float: left;
71
+ }
72
+
73
+ fieldset.buttons label.back {
74
+ float: right;
75
+ }
76
+
77
+ p.note {
78
+ margin-right: 2.5em;
79
+ margin-left: 0;
80
+ border-left-width: 0;
81
+ border-right: 1px solid rgb(50, 140, 0);
82
+ }
83
+
84
+ input.text {
85
+ font-family: Tahoma, "Times New Roman";
86
+ float: right;
87
+ }
88
+
89
+ select {
90
+ font-family: Tahoma, "Times New Roman";
91
+ float: right;
92
+ }
93
+
94
+ textarea {
95
+ font-family: Tahoma, "Times New Roman";
96
+ }
97
+
98
+ input.button {
99
+ font-family: Tahoma, "Times New Roman";
100
+ }
bp-forums/bbpress/bb-admin/install.css ADDED
@@ -0,0 +1,433 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Start with some basic resets
3
+ */
4
+
5
+ /*
6
+ Copyright (c) 2009, Yahoo! Inc. All rights reserved.
7
+ Code licensed under the BSD License:
8
+ http://developer.yahoo.net/yui/license.txt
9
+ version: 2.7.0
10
+ */
11
+ html{color:#000;background:#FFF;}
12
+ body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}
13
+ table{border-collapse:collapse;border-spacing:0;}
14
+ fieldset,img{border:0;}
15
+ address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit;}
16
+ del,ins{text-decoration:none;}
17
+ li{list-style:none;}
18
+ caption,th{text-align:left;}
19
+ h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}
20
+ q:before,q:after{content:'';}
21
+ abbr,acronym{border:0;font-variant:normal;}
22
+ sup{vertical-align:baseline;}
23
+ sub{vertical-align:baseline;}
24
+ legend{color:#000;}
25
+ input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}
26
+ input,button,textarea,select{*font-size:100%;}
27
+ body{font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}
28
+ select,input,button,textarea,button{font:99% arial,helvetica,clean,sans-serif;}
29
+ table{font-size:inherit;font:100%;}
30
+ pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}
31
+
32
+ /*
33
+ Now for our own code
34
+ */
35
+
36
+ html {
37
+ background-color: rgb(247, 247, 247);
38
+ }
39
+
40
+ body {
41
+ text-align: center;
42
+ font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
43
+ font-size: 1em;
44
+ color: rgb(255, 255, 255);
45
+ }
46
+
47
+ div#container {
48
+ margin: 2em auto 1em auto;
49
+ padding: 1em 32px;
50
+ width: 700px;
51
+ background-color: rgb(255, 255, 255);
52
+ text-align: left;
53
+ -moz-border-radius: 11px;
54
+ -khtml-border-radius: 11px;
55
+ -webkit-border-radius: 11px;
56
+ border-radius: 11px;
57
+ border: 1px solid rgb(223, 223, 223);
58
+ color: rgb(51, 51, 51);
59
+ }
60
+
61
+ a {
62
+ color: rgb(50, 140, 0);
63
+ text-decoration: none;
64
+ }
65
+
66
+ a:hover {
67
+ text-decoration: underline;
68
+ }
69
+
70
+ strong {
71
+ font-weight: bold;
72
+ }
73
+
74
+ em {
75
+ font-style: italic;
76
+ }
77
+
78
+ div.logo img {
79
+ margin: 12px 0 27px 0;
80
+ width: 200px;
81
+ height: 57px;
82
+ display: block;
83
+ }
84
+
85
+ h1 {
86
+ margin: 0 0 2em 0;
87
+ font-size: 0.75em;
88
+ font-weight: bold;
89
+ }
90
+
91
+ p {
92
+ margin: 0 0 1em 0;
93
+ font-size: 0.75em;
94
+ line-height: 1.4em;
95
+ }
96
+
97
+ dl {
98
+ border-left: 1px solid rgb(125, 125, 125);
99
+ margin: 1.5em 0 1.5em 2.5em;
100
+ font-size: 0.75em;
101
+ }
102
+
103
+ dl code {
104
+ font-size: 1.4em;
105
+ }
106
+
107
+ dt {
108
+ font-size: 1em;
109
+ padding: 0.6em 0 0.2em 0.6em;
110
+ }
111
+
112
+ dd {
113
+ font-size: 1em;
114
+ padding: 0 0 0.6em 3.6em;
115
+ }
116
+
117
+ p.status {
118
+ position: absolute;
119
+ right: 0;
120
+ top: -2.4em;
121
+ margin: 0;
122
+ padding: 0.5em 1em;
123
+ line-height: 1.4em;
124
+ text-shadow: rgb(255, 255, 255) 0px 1px 0px;
125
+ color: rgb(70, 70, 70);
126
+ }
127
+
128
+ p code {
129
+ font-size: 1.25em;
130
+ }
131
+
132
+ div.open div p.error.last,
133
+ div.open div p.message.last {
134
+ margin-bottom: 1.4em;
135
+ }
136
+
137
+ h2 {
138
+ font-size: 0.75em;
139
+ background-color: rgb(236, 236, 236);
140
+ padding: 0.5em 1em;
141
+ text-shadow: rgb(255, 255, 255) 0px 1px 0px;
142
+ color: rgb(70, 70, 70);
143
+ font-weight: bold;
144
+ line-height: 1.4em;
145
+ }
146
+
147
+ div.open,
148
+ div.closed {
149
+ border: 1px solid rgb(223, 223, 223);
150
+ -moz-border-radius: 6px;
151
+ -khtml-border-radius: 6px;
152
+ -webkit-border-radius: 6px;
153
+ border-radius: 6px;
154
+ margin-bottom: 1em;
155
+ background-color: rgb(247, 247, 247);
156
+ }
157
+
158
+ div.open div {
159
+ padding: 1em;
160
+ margin: 1px 0;
161
+ }
162
+
163
+ div.closed div {
164
+ position: relative;
165
+ }
166
+
167
+ p.error {
168
+ border: 1px solid rgb(204, 0, 0);
169
+ background-color: rgb(255, 235, 232);
170
+ padding: 0.6em;
171
+ -moz-border-radius: 4px;
172
+ -khtml-border-radius: 4px;
173
+ -webkit-border-radius: 4px;
174
+ border-radius: 4px;
175
+ }
176
+
177
+ p.error a {
178
+ color: rgb(204, 0, 0);
179
+ }
180
+
181
+ dl.error {
182
+ margin-top: -1em;
183
+ }
184
+
185
+ p.message {
186
+ border: 1px solid rgb(230, 219, 85);
187
+ background-color: rgb(255, 251, 204);
188
+ padding: 0.6em;
189
+ -moz-border-radius: 4px;
190
+ -khtml-border-radius: 4px;
191
+ -webkit-border-radius: 4px;
192
+ border-radius: 4px;
193
+ }
194
+
195
+ div.open div.toggle {
196
+ margin: 0;
197
+ padding: 0;
198
+ }
199
+
200
+ div.open h2 {
201
+ color: rgb(0, 0, 0);
202
+ }
203
+
204
+ form {
205
+ clear: both;
206
+ border: 1px solid rgb(223, 223, 223);
207
+ background-color: rgb(255, 255, 255);
208
+ -moz-border-radius: 4px;
209
+ -khtml-border-radius: 4px;
210
+ -webkit-border-radius: 4px;
211
+ border-radius: 4px;
212
+ padding: 1em 1em 1em 1em;
213
+ }
214
+
215
+ legend {
216
+ font-size: 0.9em;
217
+ font-weight: bold;
218
+ padding-bottom: 0.5em;
219
+ }
220
+
221
+ label {
222
+ display: block;
223
+ margin: 0 0 1.8em 0;
224
+ font-size: 0.75em;
225
+ color: rgb(34, 34, 34);
226
+ cursor: pointer;
227
+ clear: both;
228
+ }
229
+
230
+ label span {
231
+ display: block;
232
+ margin-bottom: 5px;
233
+ }
234
+
235
+ label.error {
236
+ border: 1px solid rgb(204, 0, 0);
237
+ background-color: rgb(255, 235, 232);
238
+ padding: 0.6em;
239
+ -moz-border-radius: 4px;
240
+ -khtml-border-radius: 4px;
241
+ -webkit-border-radius: 4px;
242
+ border-radius: 4px;
243
+ }
244
+
245
+ label.forward {
246
+ clear: none;
247
+ }
248
+
249
+ label a.note-toggle {
250
+ background-color: rgb(223, 223, 223);
251
+ color: rgb(255, 255, 255);
252
+ display: block;
253
+ text-align: center;
254
+ float: left;
255
+ font-weight: bold;
256
+ font-size: 1.2em;
257
+ padding-top: 1px;
258
+ padding-left: 1px;
259
+ width: 18px;
260
+ height: 18px;
261
+ line-height: 18px;
262
+ margin-left: 6px;
263
+ margin-top: 4px;
264
+ -moz-border-radius: 9px;
265
+ -khtml-border-radius: 9px;
266
+ -webkit-border-radius: 9px;
267
+ border-radius: 9px;
268
+ }
269
+
270
+ label a.note-toggle:hover {
271
+ text-decoration: none;
272
+ background-color: rgb(50, 140, 0);
273
+ }
274
+
275
+ label.has-note.for-textarea a.note-toggle {
276
+ margin-top: -2px;
277
+ margin-left: 6px;
278
+ }
279
+
280
+ label.has-note.for-select a.note-toggle {
281
+ margin-top: 3px;
282
+ margin-left: 4px;
283
+ }
284
+
285
+ label.has-note.for-toggle a.note-toggle {
286
+ margin-top: -2px;
287
+ margin-left: 6px;
288
+ }
289
+
290
+ label.for-textarea span,
291
+ label.for-toggle span {
292
+ float: left;
293
+ }
294
+
295
+ label.for-toggle span {
296
+ margin-bottom: 0;
297
+ }
298
+
299
+ label span.error {
300
+ color: rgb(204, 0, 0);
301
+ display: block;
302
+ margin: 0.4em 0.4em 0.4em 3em;
303
+ }
304
+
305
+ label code {
306
+ font-size: 1.25em;
307
+ }
308
+
309
+ fieldset.buttons label.forward {
310
+ margin: 0;
311
+ float: right;
312
+ }
313
+
314
+ fieldset.buttons label.back {
315
+ margin: 0;
316
+ float: left;
317
+ }
318
+
319
+ p.note {
320
+ margin: 0 0 0 2.5em;
321
+ color: rgb(102, 102, 102);
322
+ border-left: 1px solid rgb(50, 140, 0);
323
+ padding: 0.6em;
324
+ font-size: 0.9em;
325
+ font-style: italic;
326
+ clear: both;
327
+ }
328
+
329
+ input.text {
330
+ font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
331
+ font-size: 1.2em;
332
+ padding: 4px;
333
+ border: 1px solid rgb(187, 187, 187);
334
+ width: 400px;
335
+ display: block;
336
+ float: left;
337
+ -moz-border-radius: 4px;
338
+ -khtml-border-radius: 4px;
339
+ -webkit-border-radius: 4px;
340
+ border-radius: 4px;
341
+ clear: both;
342
+ }
343
+
344
+ select {
345
+ font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
346
+ font-size: 1.2em;
347
+ padding: 0;
348
+ border: 1px solid rgb(187, 187, 187);
349
+ display: block;
350
+ float: left;
351
+ }
352
+
353
+ textarea {
354
+ font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
355
+ font-size: 0.9em;
356
+ padding: 0;
357
+ border: 1px solid rgb(187, 187, 187);
358
+ width: 630px;
359
+ max-width: 630px;
360
+ height: 38em;
361
+ display: block;
362
+ -moz-border-radius: 4px;
363
+ -khtml-border-radius: 4px;
364
+ -webkit-border-radius: 4px;
365
+ border-radius: 4px;
366
+ clear: both;
367
+ }
368
+
369
+ textarea#config {
370
+ text-align: left;
371
+ }
372
+
373
+ textarea.short,
374
+ textarea#error_log {
375
+ height: 15em;
376
+ }
377
+
378
+ textarea#error_log {
379
+ border-color: rgb(153, 0, 0);
380
+ color: rgb(153, 0, 0);
381
+ }
382
+
383
+ input.checkbox {
384
+ font-size: 1.25em;
385
+ }
386
+
387
+ input.button {
388
+ background: url('images/white-grad.png') repeat-x 0 0 rgb(242, 242, 242);
389
+ -moz-border-radius: 15px;
390
+ -khtml-border-radius: 15px;
391
+ -webkit-border-radius: 15px;
392
+ border-radius: 15px;
393
+ border: 1px solid rgb(187, 187, 187);
394
+ color: rgb(70, 70, 70);
395
+ cursor: pointer;
396
+ font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
397
+ font-size: 1.2em;
398
+ line-height: 1.2em;
399
+ padding: 0.45em 0.9em;
400
+ text-decoration: none;
401
+ }
402
+
403
+ input.button:hover {
404
+ border-color: rgb(102, 102, 102);
405
+ color: rgb(0, 0, 0);
406
+ }
407
+
408
+ input.button:active {
409
+ background-image: url('images/white-grad-active.png');
410
+ }
411
+
412
+ label#label-toggle_4 {
413
+ margin-bottom: 0;
414
+ }
415
+
416
+ label#label-toggle_4 span {
417
+ margin-bottom: 0.4em;
418
+ }
419
+
420
+ label#label-error_log,
421
+ label#label-installation_log {
422
+ margin-top: 1.8em;
423
+ margin-bottom: 0;
424
+ }
425
+
426
+ div.clear {
427
+ clear: both;
428
+ height: 0;
429
+ line-height: 0;
430
+ font-size: 0;
431
+ margin: 0 !important;
432
+ padding: 0 !important;
433
+ }
bp-forums/bbpress/bb-admin/install.php ADDED
@@ -0,0 +1,401 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Modify error reporting levels
3
+ error_reporting(E_ALL ^ E_NOTICE);
4
+
5
+ // Let everyone know we are installing
6
+ define('BB_INSTALLING', true);
7
+
8
+ // Load bbPress
9
+ require_once('../bb-load.php');
10
+
11
+ // Instantiate the install class
12
+ require_once( BB_PATH . 'bb-admin/includes/class.bb-install.php' );
13
+ $bb_install = new BB_Install(__FILE__);
14
+
15
+ $bb_install->header();
16
+ ?>
17
+ <script type="text/javascript" charset="utf-8">
18
+ function toggleNote(target) {
19
+ var targetObj = document.getElementById(target);
20
+ if (targetObj.style.display == 'none') {
21
+ targetObj.style.display = 'block';
22
+ } else {
23
+ targetObj.style.display = 'none';
24
+ }
25
+ }
26
+ function toggleBlock(toggleObj, target) {
27
+ var targetObj = document.getElementById(target);
28
+ if (toggleObj.checked) {
29
+ targetObj.style.display = 'block';
30
+ } else {
31
+ targetObj.style.display = 'none';
32
+ }
33
+ }
34
+ function toggleValue(toggleObj, target, offValue, onValue) {
35
+ var targetObj = document.getElementById(target);
36
+ if (toggleObj.checked) {
37
+ targetObj.value = onValue;
38
+ } else {
39
+ targetObj.value = offValue;
40
+ }
41
+ }
42
+ </script>
43
+ <?php
44
+ switch ($bb_install->step) {
45
+ case -1:
46
+ $bb_install->messages();
47
+ $bb_install->intro();
48
+ break;
49
+
50
+ default:
51
+ $bb_install->step_header(0);
52
+
53
+ if ($bb_install->step === 0) {
54
+ ?>
55
+ <form action="install.php" method="post">
56
+ <?php
57
+ $bb_install->messages();
58
+ $bb_install->get_language_selector();
59
+ $bb_install->input_buttons('forward_0_0', false, 1);
60
+ ?>
61
+ </form>
62
+ <?php
63
+ } else {
64
+ $bb_install->sanitize_form_data();
65
+ }
66
+
67
+ $bb_install->step_footer();
68
+
69
+ $bb_install->step_header(1);
70
+
71
+ if ($bb_install->step === 1) {
72
+
73
+ switch($bb_install->step_status[1]) {
74
+ case 'incomplete':
75
+ ?>
76
+ <form action="install.php" method="post">
77
+ <?php
78
+ $bb_install->messages();
79
+ ?>
80
+ <fieldset>
81
+ <?php
82
+ $bb_install->input_text('bbdb_name');
83
+ $bb_install->input_text('bbdb_user');
84
+ $bb_install->input_text('bbdb_password');
85
+ $bb_install->select_language();
86
+ $bb_install->input_toggle('toggle_1');
87
+ ?>
88
+ <div class="toggle" id="toggle_1_target" style="<?php echo esc_attr( 'display:' . $bb_install->data[$bb_install->step]['form']['toggle_1']['display'] ); ?>;">
89
+ <?php
90
+ $bb_install->input_text('bbdb_host');
91
+ $bb_install->input_text('bbdb_charset');
92
+ $bb_install->input_text('bbdb_collate');
93
+ //$bb_install->input_text('bb_auth_key');
94
+ //$bb_install->input_text('bb_secure_auth_key');
95
+ //$bb_install->input_text('bb_logged_in_key');
96
+ //$bb_install->input_text('bb_nonce_key');
97
+ $bb_install->input_text('bb_table_prefix', 'ltr');
98
+ ?>
99
+ </div>
100
+ </fieldset>
101
+ <?php
102
+ $bb_install->input_buttons('forward_1_0');
103
+ ?>
104
+ </form>
105
+ <?php
106
+ break;
107
+
108
+ case 'manual':
109
+ ?>
110
+ <form action="install.php" method="post">
111
+ <?php
112
+ $bb_install->messages();
113
+ $bb_install->hidden_step_inputs();
114
+ ?>
115
+ <fieldset>
116
+ <?php
117
+ $bb_install->textarea('config', 'ltr');
118
+ ?>
119
+ </fieldset>
120
+ <?php
121
+ $bb_install->input_buttons('forward_1_1', 'back_1_1');
122
+ ?>
123
+ </form>
124
+ <?php
125
+ break;
126
+
127
+ case 'complete':
128
+ ?>
129
+ <form action="install.php" method="post">
130
+ <?php
131
+ $bb_install->messages();
132
+ $bb_install->input_buttons('forward_1_2', false, 2);
133
+ ?>
134
+ </form>
135
+ <?php
136
+ break;
137
+ }
138
+ }
139
+
140
+ $bb_install->step_footer();
141
+
142
+ $bb_install->step_header(2);
143
+
144
+ if ($bb_install->step === 2) {
145
+
146
+ switch ($bb_install->step_status[2]) {
147
+ case 'incomplete':
148
+ ?>
149
+ <form action="install.php" method="post">
150
+ <?php
151
+ $bb_install->messages();
152
+ ?>
153
+ <fieldset>
154
+ <?php
155
+ bb_nonce_field('bbpress-installer');
156
+ $bb_install->input_toggle('toggle_2_0');
157
+ ?>
158
+ </fieldset>
159
+ <div class="toggle" id="toggle_2_0_target" style="<?php echo esc_attr( 'display:' . $bb_install->data[$bb_install->step]['form']['toggle_2_0']['display'] ); ?>;">
160
+ <fieldset>
161
+ <?php
162
+ $bb_install->input_toggle('toggle_2_1');
163
+ ?>
164
+ </fieldset>
165
+ <div class="toggle" id="toggle_2_1_target" style="<?php echo esc_attr( 'display:' . $bb_install->data[$bb_install->step]['form']['toggle_2_1']['display'] ); ?>;">
166
+ <fieldset>
167
+ <legend><?php _e('Cookies'); ?></legend>
168
+ <p><?php _e('Integrating cookies allows you and your users to login to either your bbPress or your WordPress site and be automatically logged into both.'); ?></p>
169
+ <p><?php _e('You may need to make changes to your WordPress configuration once installation is complete. See the "WordPress Integration" section of the bbPress administration area when you are done.'); ?></p>
170
+ <?php
171
+ $bb_install->input_text('wp_siteurl', 'ltr');
172
+ $bb_install->input_text('wp_home', 'ltr');
173
+ $bb_install->input_text('wp_auth_key');
174
+ $bb_install->input_text('wp_auth_salt');
175
+ $bb_install->input_text('wp_secure_auth_key');
176
+ $bb_install->input_text('wp_secure_auth_salt');
177
+ $bb_install->input_text('wp_logged_in_key');
178
+ $bb_install->input_text('wp_logged_in_salt');
179
+ ?>
180
+ </fieldset>
181
+ </div>
182
+ <fieldset>
183
+ <?php
184
+ $bb_install->input_toggle('toggle_2_2');
185
+ ?>
186
+ </fieldset>
187
+ <div class="toggle" id="toggle_2_2_target" style="<?php echo esc_attr( 'display:' . $bb_install->data[$bb_install->step]['form']['toggle_2_2']['display'] ); ?>;">
188
+ <fieldset>
189
+ <legend><?php _e('User database'); ?></legend>
190
+ <p><?php _e('Integrating your WordPress database user tables allows you to store user data in one location, instead of having separate user data for both bbPress and WordPress.'); ?></p>
191
+ <?php
192
+ $bb_install->input_text('wp_table_prefix', 'ltr');
193
+ $bb_install->input_text('wordpress_mu_primary_blog_id', 'ltr');
194
+ $bb_install->input_toggle('toggle_2_3');
195
+ ?>
196
+ </fieldset>
197
+ <div class="toggle" id="toggle_2_3_target" style="<?php echo esc_attr( 'display:' . $bb_install->data[$bb_install->step]['form']['toggle_2_3']['display'] ); ?>;">
198
+ <fieldset>
199
+ <legend><?php _e('Separate user database settings'); ?></legend>
200
+ <p><?php _e('Most of the time these settings are <em>not</em> required. Look before you leap!'); ?></p>
201
+ <p><?php _e('If required, then all settings except for the character set must be specified.'); ?></p>
202
+ <?php
203
+ $bb_install->input_text('user_bbdb_name');
204
+ $bb_install->input_text('user_bbdb_user');
205
+ $bb_install->input_text('user_bbdb_password');
206
+ $bb_install->input_text('user_bbdb_host');
207
+ $bb_install->input_text('user_bbdb_charset');
208
+ $bb_install->input_text('user_bbdb_collate');
209
+ ?>
210
+ </fieldset>
211
+ <fieldset>
212
+ <legend><?php _e('Custom user tables'); ?></legend>
213
+ <p><?php _e('Only set these options if your integrated user tables do not fit the usual mould of <em>wp_user</em> and <em>wp_usermeta</em>.'); ?></p>
214
+ <?php
215
+ $bb_install->input_text('custom_user_table');
216
+ $bb_install->input_text('custom_user_meta_table');
217
+ ?>
218
+ </fieldset>
219
+ </div>
220
+ </div>
221
+ </div>
222
+ <?php
223
+ $bb_install->input_buttons('forward_2_0');
224
+ ?>
225
+ </form>
226
+ <script type="text/javascript" charset="utf-8">
227
+ function updateWordPressOptionURL () {
228
+ var siteURLInputValue = document.getElementById('wp_siteurl').value;
229
+ if (siteURLInputValue && siteURLInputValue.substr(-1,1) != '/') {
230
+ siteURLInputValue += '/';
231
+ }
232
+ var authSaltAnchor = document.getElementById('getAuthSaltOption');
233
+ var secureAuthSaltAnchor = document.getElementById('getSecureAuthSaltOption');
234
+ var loggedInSaltAnchor = document.getElementById('getLoggedInSaltOption');
235
+ if (siteURLInputValue) {
236
+ authSaltAnchor.href = siteURLInputValue + 'wp-admin/options.php';
237
+ secureAuthSaltAnchor.href = siteURLInputValue + 'wp-admin/options.php';
238
+ loggedInSaltAnchor.href = siteURLInputValue + 'wp-admin/options.php';
239
+ } else {
240
+ authSaltAnchor.href = '';
241
+ secureAuthSaltAnchor.href = '';
242
+ loggedInSaltAnchor.href = '';
243
+ }
244
+ }
245
+ var siteURLInput = document.getElementById('wp_siteurl');
246
+ if (siteURLInput.value) {
247
+ updateWordPressOptionURL();
248
+ }
249
+ siteURLInput.onkeyup = updateWordPressOptionURL;
250
+ siteURLInput.onblur = updateWordPressOptionURL;
251
+ siteURLInput.onclick = updateWordPressOptionURL;
252
+ siteURLInput.onchange = updateWordPressOptionURL;
253
+ </script>
254
+ <?php
255
+ break;
256
+
257
+ case 'complete':
258
+ ?>
259
+ <form action="install.php" method="post">
260
+ <?php
261
+ $bb_install->messages();
262
+ ?>
263
+ <fieldset>
264
+ <?php
265
+ bb_nonce_field('bbpress-installer');
266
+ ?>
267
+ </fieldset>
268
+ <?php
269
+ $bb_install->hidden_step_inputs();
270
+ $bb_install->input_buttons('forward_2_1', 'back_2_1', 3);
271
+ ?>
272
+ </form>
273
+ <?php
274
+ break;
275
+ }
276
+ }
277
+
278
+ $bb_install->step_footer();
279
+
280
+ $bb_install->step_header(3);
281
+
282
+ if ($bb_install->step === 3) {
283
+
284
+ switch($bb_install->step_status[3]) {
285
+ case 'incomplete':
286
+ ?>
287
+ <form action="install.php" method="post">
288
+ <?php
289
+ $bb_install->messages();
290
+ ?>
291
+ <fieldset>
292
+ <?php
293
+ bb_nonce_field('bbpress-installer');
294
+ ?>
295
+ </fieldset>
296
+ <?php
297
+ $bb_install->hidden_step_inputs(2);
298
+ ?>
299
+ <fieldset>
300
+ <?php
301
+ $bb_install->input_text('name');
302
+ $bb_install->input_text('uri', 'ltr');
303
+
304
+ if ($bb_install->populate_keymaster_user_login_from_user_tables()) {
305
+ echo $bb_install->strings[3]['scripts']['changeKeymasterEmail'];
306
+ $bb_install->select('keymaster_user_login');
307
+ $bb_install->input_hidden('keymaster_user_email');
308
+ } else {
309
+ $bb_install->input_text('keymaster_user_login');
310
+ $bb_install->input_text('keymaster_user_email', 'ltr');
311
+ }
312
+ $bb_install->input_hidden('keymaster_user_type');
313
+
314
+ if (!$bb_install->database_tables_are_installed()) {
315
+ $bb_install->input_text('forum_name');
316
+ }
317
+ ?>
318
+ </fieldset>
319
+ <?php
320
+ $bb_install->input_buttons('forward_3_0');
321
+ ?>
322
+ </form>
323
+ <?php
324
+ break;
325
+
326
+ case 'complete':
327
+ ?>
328
+ <form action="install.php" method="post">
329
+ <?php
330
+ $bb_install->messages();
331
+ ?>
332
+ <fieldset>
333
+ <?php
334
+ bb_nonce_field('bbpress-installer');
335
+ ?>
336
+ </fieldset>
337
+ <?php
338
+ $bb_install->hidden_step_inputs(2);
339
+ $bb_install->hidden_step_inputs(); // The current step (3) is assumed here
340
+ $bb_install->input_buttons('forward_3_1', 'back_3_1', 4);
341
+ ?>
342
+ </form>
343
+ <?php
344
+ break;
345
+ }
346
+ }
347
+
348
+ $bb_install->step_footer();
349
+
350
+ if ($bb_install->step === 4) {
351
+
352
+ $bb_install->step_header(4);
353
+ $bb_install->messages();
354
+
355
+ if ($bb_install->step_status[4] == 'complete') {
356
+ ?>
357
+ <p><?php _e('You can now log in with the following details:'); ?></p>
358
+ <dl>
359
+ <dt><?php _e('Username:'); ?></dt>
360
+ <dd><code><?php echo esc_html( $bb_install->data[3]['form']['keymaster_user_login']['value'] ); ?></code></dd>
361
+ <dt><?php _e('Password:'); ?></dt>
362
+ <dd><code><?php echo esc_html( $bb_install->data[4]['form']['keymaster_user_password']['value'] ); ?></code></dd>
363
+ <dt><?php _e('Site address:'); ?></dt>
364
+ <dd dir="ltr"><a href="<?php bb_uri(); ?>"><?php bb_uri(null, null, BB_URI_CONTEXT_TEXT); ?></a></dd>
365
+ </dl>
366
+ <?php
367
+ if ($bb_install->data[3]['form']['keymaster_user_type']['value'] == 'bbPress') {
368
+ ?>
369
+ <p><?php _e('<strong><em>Note that password</em></strong> carefully! It is a <em>random</em> password that was generated just for you. If you lose it, you will have to delete the tables from the database yourself, and re-install bbPress.'); ?></p>
370
+ <?php
371
+ }
372
+ }
373
+ ?>
374
+ <form action="<?php bb_uri(null, null, BB_URI_CONTEXT_FORM_ACTION); ?>">
375
+ <fieldset>
376
+ <?php
377
+ $bb_install->input_toggle('toggle_4');
378
+ ?>
379
+ <div class="toggle" id="toggle_4_target" style="display:none;">
380
+ <?php
381
+ if ($bb_install->data[4]['form']['error_log']['value']) {
382
+ $bb_install->textarea('error_log');
383
+ }
384
+ $bb_install->textarea('installation_log');
385
+ ?>
386
+ </div>
387
+ </fieldset>
388
+ </form>
389
+ <?php
390
+ $bb_install->step_footer();
391
+
392
+ } else {
393
+ //? >
394
+ // <div id="step4" class="closed"></div>
395
+ //<?php
396
+ }
397
+
398
+ break;
399
+ }
400
+ $bb_install->footer();
401
+ ?>
bp-forums/bbpress/bb-admin/js/admin-forums.js ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( function($) { // In here $ is jQuery
2
+
3
+ bbSortForums = {
4
+ handleText: 'drag',
5
+ handle: '',
6
+ sortCfg: {
7
+ accept: 'forum',
8
+ handle: 'img.sort-handle',
9
+ opacity: .3,
10
+ helperclass: 'helper',
11
+ onStop: function() {
12
+ bbSortForums.place = null;
13
+ bbSortForums.recolor();
14
+ }
15
+ },
16
+ editText: 'Edit Forum Order',
17
+ saveText: 'Save Forum Order',
18
+ place: null, // The id of the list item it's currently hovering before
19
+ placed: null, // The id of the list item it's been made a child of
20
+ rtl: 'rtl' == $('html').attr( 'dir' ),
21
+
22
+ recolor: function() {
23
+ $('#forum-list li:gt(0)').css( 'background-color', '' ).filter(':even').removeClass('alt').end().filter(':odd').addClass('alt');
24
+ },
25
+
26
+ checkHover: function(el, doit) {
27
+ if ( this.place == el.id && doit )
28
+ return;
29
+
30
+ if ( !doit ) {
31
+ this.place = null;
32
+ return;
33
+ }
34
+
35
+ this.place = el.id;
36
+ if ( $('#' + this.place).children('ul:has(li:visible)').size() ) // Don't shift over if there's already a UL with stuff in it
37
+ return;
38
+
39
+ var id = this.place.split('-')[1];
40
+ $('#' + this.place).not(':has(ul)').append("<ul id='forum-root-" + id + "' class='list-block holder'></ul>").end().children('ul').append(jQuery.iSort.helper.get(0)); // Place in shifted box
41
+ this.placed = 'forum-' + id;
42
+ },
43
+
44
+ serialize: function () {
45
+ h = '';
46
+ $('#forum-list, #forum-list ul').each( function() {
47
+ var i = this.id;
48
+ $('#' + i + '> .forum').each( function () {
49
+ if (h.length > 0)
50
+ h += '&';
51
+ var root = 'forum-list' == i ? 0 : i.split('-')[2];
52
+ h += 'root[' + root + '][]=' + this.id.split('-')[1];
53
+ } );
54
+ } );
55
+ return h;
56
+ },
57
+
58
+ init: function() {
59
+ this.handle = "<img class='sort-handle' src='images/drag.gif' alt='" + this.handleText + "' />";
60
+ var div = document.createElement('div');
61
+ div.innerHTML = this.saveText; // Save the raquo!
62
+ this.saveText = div.childNodes[0].nodeValue;
63
+ div.innerHTML = this.editText; // Save the raquo!
64
+ this.editText = div.childNodes[0].nodeValue;
65
+ div = null;
66
+ $('#forum-list').after("<form class='settings' action='' onsubmit='return false;'><fieldset class='submit'><input class='submit' type='submit' name='submit' id='forum-order-edit' value='" + this.editText + "' /></fieldset></form>");
67
+
68
+ $('#forum-order-edit').toggle( function() {
69
+ $(this).val(bbSortForums.saveText);
70
+ $('#forum-list li:gt(0) div.row-title').before(bbSortForums.handle);
71
+ $('#forum-list').Sortable( bbSortForums.sortCfg );
72
+ $('body').addClass('sorting');
73
+ }, function() {
74
+ $(this).val(bbSortForums.editText);
75
+ $('.sort-handle').remove();
76
+
77
+ var hash = bbSortForums.serialize();
78
+ hash += '&' + $.SortSerialize('forum-list').hash.replace(/forum-list/g, 'order').replace(/forum-/g, '')
79
+ $('#forum-list').SortableDestroy();
80
+ $('body').removeClass('sorting');
81
+
82
+ $.post(
83
+ 'admin-ajax.php',
84
+ 'action=order-forums&_ajax_nonce=' + $('#add-forum input[name=order-nonce]').val() + '&' + hash
85
+ );
86
+ } );
87
+ }
88
+ }
89
+
90
+ // overwrite with more advanced function
91
+ jQuery.iSort.checkhover = function(e,o) {
92
+ if (!jQuery.iDrag.dragged)
93
+ return;
94
+
95
+ if ( e.dropCfg.el.size() > 0 ) {
96
+ var bottom = jQuery.grep(e.dropCfg.el, function(i) { // All the list items whose bottom edges are inside the draggable
97
+ var x = bbSortForums.rtl ? i.pos.x + i.pos.wb > jQuery.iDrag.dragged.dragCfg.nx + jQuery.iDrag.dragged.dragCfg.oC.wb : i.pos.x < jQuery.iDrag.dragged.dragCfg.nx;
98
+ return i.pos.y + i.pos.hb > jQuery.iDrag.dragged.dragCfg.ny && i.pos.y + i.pos.hb < jQuery.iDrag.dragged.dragCfg.ny + 30 && x;
99
+ } );
100
+
101
+ if ( bottom.length > 0 ) { // Use the lowest one one the totem pole
102
+ var x = bbSortForums.rtl ? bottom[bottom.length-1].pos.x + bottom[bottom.length-1].pos.wb - 30 > jQuery.iDrag.dragged.dragCfg.nx + jQuery.iDrag.dragged.dragCfg.oC.wb : bottom[bottom.length-1].pos.x + 30 < jQuery.iDrag.dragged.dragCfg.nx;
103
+ if ( bbSortForums.placed != bottom[bottom.length-1].id || !x ) { // Testing to see if still placed in shifted box
104
+ bbSortForums.placed = null;
105
+ jQuery(bottom[bottom.length-1]).after(jQuery.iSort.helper.get(0));
106
+ }
107
+ bbSortForums.checkHover(bottom[bottom.length-1], x); // If far enough right, shift it over
108
+ return;
109
+ }
110
+
111
+ // Didn't find anything by checking bottems. Look at tops
112
+ var top = jQuery.grep(e.dropCfg.el, function(i) { // All the list items whose top edges are inside the draggable
113
+ var x = bbSortForums.rtl ? i.pos.x + i.pos.wb > jQuery.iDrag.dragged.dragCfg.nx : i.pos.x < jQuery.iDrag.dragged.dragCfg.nx;
114
+ return i.pos.y > jQuery.iDrag.dragged.dragCfg.ny && i.pos.y < jQuery.iDrag.dragged.dragCfg.ny + 30 && x;
115
+ } );
116
+
117
+ if ( top.length ) { // Use the highest one (should be only one)
118
+ jQuery(top[0]).before(jQuery.iSort.helper.get(0));
119
+ bbSortForums.checkHover(top[0], false);
120
+ return;
121
+ }
122
+ }
123
+ jQuery.iSort.helper.get(0).style.display = 'block';
124
+ }
125
+
126
+ if ( 'undefined' != typeof bbSortForumsL10n )
127
+ $.extend( bbSortForums, bbSortForumsL10n );
128
+
129
+ bbSortForums.init();
130
+
131
+ var options = $('#forum-parent').get(0).options;
132
+ var addAfter = function( r, settings ) {
133
+ var name = $("<span>" + $('name', r).text() + "</span>").html();
134
+ var id = $('forum', r).attr('id');
135
+ options[options.length] = new Option(name, id);
136
+ }
137
+
138
+ $('#forum-list').wpList( { addAfter: addAfter } );
139
+
140
+ } );
bp-forums/bbpress/bb-admin/js/common.js ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var showNotice, adminMenu, columns;
2
+ (function($){
3
+ // sidebar admin menu
4
+ adminMenu = {
5
+
6
+ init : function() {
7
+ $('ul#bbAdminMenu li.bb-menu div.bb-menu-toggle').each( function() {
8
+ if ( $(this).siblings('div.bb-menu-sub-wrap').length )
9
+ $(this).click(function(){ adminMenu.toggle( $(this).siblings('div.bb-menu-sub-wrap') ); });
10
+ else
11
+ $(this).hide();
12
+ });
13
+
14
+ $('#bbAdminMenu li.bb-menu.bb-menu-separator a').click(function(){
15
+ if ( $('body').hasClass('bb-menu-folded') ) {
16
+ adminMenu.fold(1);
17
+ deleteUserSetting( 'fm' );
18
+ } else {
19
+ adminMenu.fold();
20
+ setUserSetting( 'fm', 'f' );
21
+ }
22
+ return false;
23
+ });
24
+
25
+ if ( $('body').hasClass('bb-menu-folded') ) {
26
+ this.fold();
27
+ }
28
+ this.restoreMenuState();
29
+ },
30
+
31
+ restoreMenuState : function() {
32
+ $('ul#bbAdminMenu li.bb-menu.bb-menu-has-submenu').each(function(i, e) {
33
+ var v = getUserSetting( 'm'+i );
34
+ if ( $(e).hasClass('bb-menu-current') ) return true; // leave the current parent open
35
+
36
+ if ( 'o' == v ) $(e).addClass('bb-menu-open');
37
+ else if ( 'c' == v ) $(e).removeClass('bb-menu-open');
38
+ });
39
+ },
40
+
41
+ toggle : function(el) {
42
+ el['slideToggle'](150, function(){el.css('display','');}).parent().toggleClass( 'bb-menu-open' );
43
+
44
+ $('ul#bbAdminMenu li.bb-menu.bb-menu-has-submenu').each(function(i, e) {
45
+ var v = $(e).hasClass('bb-menu-open') ? 'o' : 'c';
46
+ setUserSetting( 'm'+i, v );
47
+ });
48
+
49
+ return false;
50
+ },
51
+
52
+ fold : function(off) {
53
+ if (off) {
54
+ $('body').removeClass('bb-menu-folded');
55
+ $('#bbAdminMenu li.bb-menu.bb-menu-has-submenu').unbind();
56
+ } else {
57
+ $('body').addClass('bb-menu-folded');
58
+ $('#bbAdminMenu li.bb-menu.bb-menu-has-submenu').hoverIntent({
59
+ over: function(e){
60
+ var m, b, h, o, f;
61
+ m = $(this).find('div.bb-menu-sub-wrap');
62
+ b = m.parent().offset().top + m.height() + 1; // Bottom offset of the menu
63
+ h = $('#bbWrap').height(); // Height of the entire page
64
+ o = 60 + b - h;
65
+ f = $(window).height() + $('body').scrollTop() - 15; // The fold
66
+ if (f < (b - o)) {
67
+ o = b - f;
68
+ }
69
+ if (o > 1) {
70
+ m.css({'marginTop':'-'+o+'px'});
71
+ } else if ( m.css('marginTop') ) {
72
+ m.css({'marginTop':''});
73
+ }
74
+ m.addClass('bb-menu-sub-open');
75
+ },
76
+ out: function(){ $(this).find('div.bb-menu-sub-wrap').removeClass('bb-menu-sub-open').css({'marginTop':''}); },
77
+ timeout: 220,
78
+ sensitivity: 8,
79
+ interval: 100
80
+ });
81
+ }
82
+ }
83
+ };
84
+
85
+ $(document).ready(function(){adminMenu.init();});
86
+
87
+ })(jQuery);
bp-forums/bbpress/bb-admin/js/utils.js ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // utility functions
2
+ function convertEntities(o) {
3
+ var c, v;
4
+ c = function(s) {
5
+ if (/&[^;]+;/.test(s)) {
6
+ var e = document.createElement("div");
7
+ e.innerHTML = s;
8
+ return !e.firstChild ? s : e.firstChild.nodeValue;
9
+ }
10
+ return s;
11
+ }
12
+
13
+ if ( typeof o === 'string' ) {
14
+ return c(o);
15
+ } else if ( typeof o === 'object' ) {
16
+ for (v in o) {
17
+ if ( typeof o[v] === 'string' ) {
18
+ o[v] = c(o[v]);
19
+ }
20
+ }
21
+ }
22
+ return o;
23
+ }
24
+
25
+ var wpCookies = {
26
+ // The following functions are from Cookie.js class in TinyMCE, Moxiecode, used under LGPL.
27
+
28
+ each : function(o, cb, s) {
29
+ var n, l;
30
+
31
+ if (!o)
32
+ return 0;
33
+
34
+ s = s || o;
35
+
36
+ if (typeof(o.length) != 'undefined') {
37
+ for (n=0, l = o.length; n<l; n++) {
38
+ if (cb.call(s, o[n], n, o) === false)
39
+ return 0;
40
+ }
41
+ } else {
42
+ for (n in o) {
43
+ if (o.hasOwnProperty(n)) {
44
+ if (cb.call(s, o[n], n, o) === false) {
45
+ return 0;
46
+ }
47
+ }
48
+ }
49
+ }
50
+ return 1;
51
+ },
52
+
53
+ getHash : function(n) {
54
+ var v = this.get(n), h;
55
+
56
+ if (v) {
57
+ this.each(v.split('&'), function(v) {
58
+ v = v.split('=');
59
+ h = h || {};
60
+ h[v[0]] = v[1];
61
+ });
62
+ }
63
+ return h;
64
+ },
65
+
66
+ setHash : function(n, v, e, p, d, s) {
67
+ var o = '';
68
+
69
+ this.each(v, function(v, k) {
70
+ o += (!o ? '' : '&') + k + '=' + v;
71
+ });
72
+
73
+ this.set(n, o, e, p, d, s);
74
+ },
75
+
76
+ get : function(n) {
77
+ var c = document.cookie, e, p = n + "=", b;
78
+
79
+ if (!c)
80
+ return;
81
+
82
+ b = c.indexOf("; " + p);
83
+
84
+ if (b == -1) {
85
+ b = c.indexOf(p);
86
+
87
+ if (b != 0)
88
+ return null;
89
+
90
+ } else {
91
+ b += 2;
92
+ }
93
+
94
+ e = c.indexOf(";", b);
95
+
96
+ if (e == -1)
97
+ e = c.length;
98
+
99
+ return decodeURIComponent(c.substring(b + p.length, e));
100
+ },
101
+
102
+ set : function(n, v, e, p, d, s) {
103
+ document.cookie = n + "=" + encodeURIComponent(v) +
104
+ ((e) ? "; expires=" + e.toGMTString() : "") +
105
+ ((p) ? "; path=" + p : "") +
106
+ ((d) ? "; domain=" + d : "") +
107
+ ((s) ? "; secure" : "");
108
+ },
109
+
110
+ remove : function(n, p) {
111
+ var d = new Date();
112
+
113
+ d.setTime(d.getTime() - 1000);
114
+
115
+ this.set(n, '', d, p, d);
116
+ }
117
+ };
118
+
119
+ // Returns the value as string. Second arg or empty string is returned when value is not set.
120
+ function getUserSetting( name, def ) {
121
+ var o = getAllUserSettings();
122
+
123
+ if ( o.hasOwnProperty(name) )
124
+ return o[name];
125
+
126
+ if ( typeof def != 'undefined' )
127
+ return def;
128
+
129
+ return '';
130
+ }
131
+
132
+ // Both name and value must be only ASCII letters, numbers or underscore
133
+ // and the shorter, the better (cookies can store maximum 4KB). Not suitable to store text.
134
+ function setUserSetting( name, value, del ) {
135
+ if ( 'object' !== typeof userSettings )
136
+ return false;
137
+
138
+ var c = 'bb-user-settings-' + userSettings.uid, o = wpCookies.getHash(c) || {}, d = new Date(), p,
139
+ n = name.toString().replace(/[^A-Za-z0-9_]/, ''), v = value.toString().replace(/[^A-Za-z0-9_]/, '');
140
+
141
+ if ( del ) {
142
+ delete o[n];
143
+ } else {
144
+ o[n] = v;
145
+ }
146
+
147
+ d.setTime( d.getTime() + 31536000000 );
148
+ p = userSettings.url;
149
+
150
+ wpCookies.setHash(c, o, d, p);
151
+ wpCookies.set('bb-user-settings-time-'+userSettings.uid, userSettings.time, d, p);
152
+
153
+ return name;
154
+ }
155
+
156
+ function deleteUserSetting( name ) {
157
+ return setUserSetting( name, '', 1 );
158
+ }
159
+
160
+ // Returns all settings as js object.
161
+ function getAllUserSettings() {
162
+ if ( 'object' !== typeof userSettings )
163
+ return {};
164
+
165
+ return wpCookies.getHash('bb-user-settings-' + userSettings.uid) || {};
166
+ }
bp-forums/bbpress/bb-admin/options-discussion.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once('admin.php');
4
+
5
+ if ( 'post' == strtolower( $_SERVER['REQUEST_METHOD'] ) && $_POST['action'] == 'update') {
6
+
7
+ bb_check_admin_referer( 'options-discussion-update' );
8
+
9
+ // Deal with pingbacks checkbox when it isn't checked
10
+ if (!isset($_POST['enable_pingback'])) {
11
+ $_POST['enable_pingback'] = false;
12
+ }
13
+
14
+ // Deal with avatars checkbox when it isn't checked
15
+ if (!isset($_POST['avatars_show'])) {
16
+ $_POST['avatars_show'] = false;
17
+ }
18
+
19
+ foreach ( (array) $_POST as $option => $value ) {
20
+ if ( !in_array( $option, array('_wpnonce', '_wp_http_referer', 'action', 'submit') ) ) {
21
+ $option = trim( $option );
22
+ $value = is_array( $value ) ? $value : trim( $value );
23
+ $value = stripslashes_deep( $value );
24
+ if ( $value ) {
25
+ bb_update_option( $option, $value );
26
+ } else {
27
+ bb_delete_option( $option );
28
+ }
29
+ }
30
+ }
31
+
32
+ $goback = add_query_arg('updated', 'true', wp_get_referer());
33
+ bb_safe_redirect($goback);
34
+ exit;
35
+ }
36
+
37
+ if ( !empty($_GET['updated']) ) {
38
+ bb_admin_notice( __( '<strong>Settings saved.</strong>' ) );
39
+ }
40
+
41
+ $remote_options = array(
42
+ 'enable_pingback' => array(
43
+ 'title' => __( 'Enable Pingbacks' ),
44
+ 'type' => 'checkbox',
45
+ 'options' => array(
46
+ 1 => __( 'Allow link notifications from other sites.' )
47
+ )
48
+ ),
49
+ );
50
+
51
+ $bb_get_option_avatars_show = create_function( '$a', 'return 1;' );
52
+ add_filter( 'bb_get_option_avatars_show', $bb_get_option_avatars_show );
53
+ $avatar_options = array(
54
+ 'avatars_show' => array(
55
+ 'title' => __( 'Avatar display' ),
56
+ 'type' => 'radio',
57
+ 'options' => array(
58
+ 0 => __( 'Don&#8217;t show avatars' ),
59
+ 1 => __( 'Show avatars' )
60
+ )
61
+ ),
62
+ 'avatars_rating' => array(
63
+ 'title' => __( 'Maximum rating' ),
64
+ 'type' => 'radio',
65
+ 'options' => array(
66
+ 'g' => __( 'G &#8212; Suitable for all audiences' ),
67
+ 'pg' => __( 'PG &#8212; Possibly offensive, usually for audiences 13 and above' ),
68
+ 'r' => __( 'R &#8212; Intended for adult audiences above 17' ),
69
+ 'x' => __( 'X &#8212; Even more mature than above' )
70
+ )
71
+ ),
72
+ 'avatars_default' => array(
73
+ 'title' => __( 'Default avatar' ),
74
+ 'type' => 'radio',
75
+ 'options' => array(
76
+ 'default' => bb_get_avatar( '', 32, 'default' ) . ' ' . __( 'Mystery Man' ),
77
+ 'blank' => bb_get_avatar( '', 32, 'blank' ) . ' ' . __( 'Blank' ),
78
+ 'logo' => bb_get_avatar( '', 32, 'logo' ) . ' ' . __( 'Gravatar Logo' ),
79
+ 'identicon' => bb_get_avatar( rand( 0, 999 ), 32, 'identicon' ) . ' ' . __( 'Identicon (Generated)' ),
80
+ 'wavatar' => bb_get_avatar( rand( 0, 999 ), 32, 'wavatar' ) . ' ' . __( 'Wavatar (Generated)' ),
81
+ 'monsterid' => bb_get_avatar( rand( 0, 999 ), 32, 'monsterid' ) . ' ' . __( 'MonsterID (Generated)' )
82
+ ),
83
+ 'note' => array(
84
+ __( 'For users without a custom avatar of their own, you can either display a generic logo or a generated one based on their e-mail address.' )
85
+ ),
86
+ )
87
+ );
88
+ remove_filter( 'bb_get_option_avatars_show', $bb_get_option_avatars_show );
89
+
90
+ $bb_admin_body_class = ' bb-admin-settings';
91
+
92
+ bb_get_admin_header();
93
+
94
+ ?>
95
+
96
+ <div class="wrap">
97
+
98
+ <h2><?php _e('Discussion Settings'); ?></h2>
99
+ <?php do_action( 'bb_admin_notices' ); ?>
100
+
101
+ <form class="settings" method="post" action="<?php bb_uri( 'bb-admin/options-discussion.php', null, BB_URI_CONTEXT_FORM_ACTION + BB_URI_CONTEXT_BB_ADMIN ); ?>">
102
+ <fieldset>
103
+ <?php
104
+ foreach ( $remote_options as $option => $args ) {
105
+ bb_option_form_element( $option, $args );
106
+ }
107
+ ?>
108
+ </fieldset>
109
+ <fieldset>
110
+ <legend><?php _e('Avatars'); ?></legend>
111
+ <p>
112
+ <?php _e('bbPress includes built-in support for <a href="http://gravatar.com/">Gravatars</a>. A Gravatar is an image that follows you from site to site, appearing beside your name when you comment on Gravatar enabled sites. Here you can enable the display of Gravatars on your site.'); ?>
113
+ </p>
114
+ <?php
115
+ foreach ( $avatar_options as $option => $args ) {
116
+ bb_option_form_element( $option, $args );
117
+ }
118
+ ?>
119
+ </fieldset>
120
+ <fieldset class="submit">
121
+ <?php bb_nonce_field( 'options-discussion-update' ); ?>
122
+ <input type="hidden" name="action" value="update" />
123
+ <input class="submit" type="submit" name="submit" value="<?php _e('Save Changes') ?>" />
124
+ </fieldset>
125
+ </form>
126
+
127
+ </div>
128
+
129
+ <?php
130
+
131
+ bb_get_admin_footer();
bp-forums/bbpress/bb-admin/options-general.php ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once('admin.php');
4
+
5
+ if ( 'post' == strtolower( $_SERVER['REQUEST_METHOD'] ) && $_POST['action'] == 'update' ) {
6
+
7
+ bb_check_admin_referer( 'options-general-update' );
8
+
9
+ foreach ( (array) $_POST as $option => $value ) {
10
+ if ( !in_array( $option, array( '_wpnonce', '_wp_http_referer', 'action', 'submit' ) ) ) {
11
+ $option = trim( $option );
12
+ $value = is_array( $value ) ? $value : trim( $value );
13
+ $value = stripslashes_deep( $value );
14
+ if ( $option == 'uri' && !empty( $value ) ) {
15
+ $value = rtrim( $value, " \t\n\r\0\x0B/" ) . '/';
16
+ }
17
+ if ( $value ) {
18
+ bb_update_option( $option, $value );
19
+ } else {
20
+ bb_delete_option( $option );
21
+ }
22
+ }
23
+ }
24
+
25
+ $goback = add_query_arg( 'updated', 'true', wp_get_referer() );
26
+ bb_safe_redirect( $goback );
27
+ exit;
28
+ }
29
+
30
+ if ( !empty( $_GET['updated'] ) ) {
31
+ bb_admin_notice( __( '<strong>Settings saved.</strong>' ) );
32
+ }
33
+
34
+ $general_options = array(
35
+ 'name' => array(
36
+ 'title' => __( 'Site title' ),
37
+ 'class' => 'long',
38
+ ),
39
+ 'description' => array(
40
+ 'title' => __( 'Tagline' ),
41
+ 'class' => 'long',
42
+ 'note' => __( 'In a few words, explain what this site is about.' )
43
+ ),
44
+ 'uri' => array(
45
+ 'title' => __( 'bbPress address (URL)' ),
46
+ 'class' => array('long', 'code'),
47
+ 'note' => __( 'The full URL of your bbPress install.' ),
48
+ ),
49
+ 'from_email' => array(
50
+ 'title' => __( 'E-mail address' ),
51
+ 'note' => __( 'This address is used for admin purposes, like new user notification.' ),
52
+ )
53
+ );
54
+
55
+ $time_options = array(
56
+ 'gmt_offset' => array(
57
+ 'title' => __( 'Time zone' ),
58
+ 'type' => 'select',
59
+ 'options' => array(
60
+ '-12' => '-12:00',
61
+ '-11.5' => '-11:30',
62
+ '-11' => '-11:00',
63
+ '-10.5' => '-10:30',
64
+ '-10' => '-10:00',
65
+ '-9.5' => '-9:30',
66
+ '-9' => '-9:00',
67
+ '-8.5' => '-8:30',
68
+ '-8' => '-8:00',
69
+ '-7.5' => '-7:30',
70
+ '-7' => '-7:00',
71
+ '-6.5' => '-6:30',
72
+ '-6' => '-6:00',
73
+ '-5.5' => '-5:30',
74
+ '-5' => '-5:00',
75
+ '-4.5' => '-4:30',
76
+ '-4' => '-4:00',
77
+ '-3.5' => '-3:30',
78
+ '-3' => '-3:00',
79
+ '-2.5' => '-2:30',
80
+ '-2' => '-2:00',
81
+ '-1.5' => '-1:30',
82
+ '-1' => '-1:00',
83
+ '-0.5' => '-0:30',
84
+ '0' => '',
85
+ '0.5' => '+0:30',
86
+ '1' => '+1:00',
87
+ '1.5' => '+1:30',
88
+ '2' => '+2:00',
89
+ '2.5' => '+2:30',
90
+ '3' => '+3:00',
91
+ '3.5' => '+3:30',
92
+ '4' => '+4:00',
93
+ '4.5' => '+4:30',
94
+ '5' => '+5:00',
95
+ '5.5' => '+5:30',
96
+ '5.75' => '+5:45',
97
+ '6' => '+6:00',
98
+ '6.5' => '+6:30',
99
+ '7' => '+7:00',
100
+ '7.5' => '+7:30',
101
+ '8' => '+8:00',
102
+ '8.5' => '+8:30',
103
+ '8.75' => '+8:45',
104
+ '9' => '+9:00',
105
+ '9.5' => '+9:30',
106
+ '10' => '+10:00',
107
+ '10.5' => '+10:30',
108
+ '11' => '+11:00',
109
+ '11.5' => '+11:30',
110
+ '12' => '+12:00',
111
+ '12.75' => '+12:45',
112
+ '13' => '+13:00',
113
+ '13.75' => '+13:45',
114
+ '14' => '+14:00'
115
+ ),
116
+ 'after' => __( 'hours' )
117
+ ),
118
+ 'datetime_format' => array(
119
+ 'title' => __( 'Date and time format' ),
120
+ 'class' => 'short',
121
+ 'value' => bb_get_datetime_formatstring_i18n(),
122
+ 'after' => bb_datetime_format_i18n( bb_current_time() ),
123
+ 'note' => array(
124
+ __( '<a href="http://codex.wordpress.org/Formatting_Date_and_Time">Documentation on date formatting</a>.' ),
125
+ __( 'Click "Save Changes" to update sample output.' )
126
+ )
127
+ ),
128
+ 'date_format' => array(
129
+ 'title' => __( 'Date format' ),
130
+ 'class' => 'short',
131
+ 'value' => bb_get_datetime_formatstring_i18n( 'date' ),
132
+ 'after' => bb_datetime_format_i18n( bb_current_time(), 'date' )
133
+ )
134
+ );
135
+
136
+ if ( !$gmt_offset = bb_get_option( 'gmt_offset' ) ) {
137
+ $gmt_offset = 0;
138
+ }
139
+
140
+ if ( wp_timezone_supported() ) {
141
+ unset( $time_options['gmt_offset'] );
142
+
143
+ if ( !$timezone_string = bb_get_option( 'timezone_string' ) ) {
144
+ // set the Etc zone if no timezone string exists
145
+ $_gmt_offset = (integer) round( $gmt_offset );
146
+ if ( $_gmt_offset === 0 ) {
147
+ $timezone_string = 'Etc/UTC';
148
+ } elseif ( $_gmt_offset > 0 ) {
149
+ // Zoneinfo has these signed backwards to common convention
150
+ $timezone_string = 'Etc/GMT-' . abs( $_gmt_offset );
151
+ } else {
152
+ // Zoneinfo has these signed backwards to common convention
153
+ $timezone_string = 'Etc/GMT+' . abs( $_gmt_offset );
154
+ }
155
+ unset( $_gmt_offset );
156
+ }
157
+
158
+ // Build the new selector
159
+ $_time_options = array(
160
+ 'timezone_string' => array(
161
+ 'title' => __( 'Time zone' ),
162
+ 'type' => 'select',
163
+ 'options' => wp_timezone_choice( $timezone_string ), // This passes a string of html, which gets used verbatim
164
+ 'note' => array(
165
+ __( 'Choose a city in the same time zone as you.' ),
166
+ sprintf( __( '<abbr title="Coordinated Universal Time">UTC</abbr> time is <code>%s</code>' ), bb_gmdate_i18n( bb_get_datetime_formatstring_i18n(), bb_current_time() ) ),
167
+ sprintf( __( 'Local time is <code>%s</code>' ), bb_datetime_format_i18n( bb_current_time() ) )
168
+ )
169
+ )
170
+ );
171
+
172
+ $_now = localtime( bb_current_time(), true );
173
+ if ( $now['tm_isdst'] ) {
174
+ $_time_options['timezone_string']['note'][] = __( 'This time zone is currently in daylight savings time.' );
175
+ } else {
176
+ $_time_options['timezone_string']['note'][] = __( 'This time zone is currently in standard time.' );
177
+ }
178
+
179
+ if ( function_exists( 'timezone_transitions_get' ) ) {
180
+ $timezone_object = new DateTimeZone( $timezone_string );
181
+ $found_transition = false;
182
+ foreach ( timezone_transitions_get( $timezone_object ) as $timezone_transition ) {
183
+ if ( $timezone_transition['ts'] > time() ) {
184
+ $note = $timezone_transition['isdst'] ? __('Daylight savings time begins on <code>%s</code>') : __('Standard time begins on <code>%s</code>');
185
+ $_time_options['timezone_string']['note'][] = sprintf( $note, bb_gmdate_i18n( bb_get_datetime_formatstring_i18n(), $timezone_transition['ts'], false ) );
186
+ break;
187
+ }
188
+ }
189
+ }
190
+
191
+ $time_options = array_merge( $_time_options, $time_options );
192
+
193
+ } else {
194
+ // Tidy up the old style dropdown
195
+ $time_options['gmt_offset']['note'] = array(
196
+ 1 => sprintf( __( '<abbr title="Coordinated Universal Time">UTC</abbr> %s is <code>%s</code>' ), $time_options['gmt_offset']['options'][$gmt_offset], bb_datetime_format_i18n( bb_current_time() ) ),
197
+ 2 => __( 'Unfortunately, you have to manually update this for Daylight Savings Time.' )
198
+ );
199
+
200
+ if ( $gmt_offset ) {
201
+ $time_options['gmt_offset']['note'][0] = sprintf( __( '<abbr title="Coordinated Universal Time">UTC</abbr> time is <code>%s</code>' ), bb_gmdate_i18n( bb_get_datetime_formatstring_i18n(), bb_current_time(), true ) );
202
+ ksort($time_options['gmt_offset']['note']);
203
+ }
204
+
205
+ foreach ( $time_options['gmt_offset']['options'] as $_key => $_value ) {
206
+ $time_options['gmt_offset']['options'][$_key] = sprintf( __( 'UTC %s' ), $_value );
207
+ }
208
+ }
209
+
210
+
211
+ $bb_admin_body_class = ' bb-admin-settings';
212
+
213
+ bb_get_admin_header();
214
+
215
+ ?>
216
+
217
+ <div class="wrap">
218
+
219
+ <h2><?php _e('General Settings'); ?></h2>
220
+ <?php do_action( 'bb_admin_notices' ); ?>
221
+
222
+ <form class="settings" method="post" action="<?php bb_uri( 'bb-admin/options-general.php', null, BB_URI_CONTEXT_FORM_ACTION + BB_URI_CONTEXT_BB_ADMIN ); ?>">
223
+ <fieldset>
224
+ <?php
225
+ foreach ( $general_options as $option => $args ) {
226
+ bb_option_form_element( $option, $args );
227
+ }
228
+ foreach ( $time_options as $option => $args ) {
229
+ bb_option_form_element( $option, $args );
230
+ }
231
+ ?>
232
+ </fieldset>
233
+ <fieldset class="submit">
234
+ <?php bb_nonce_field( 'options-general-update' ); ?>
235
+ <input type="hidden" name="action" value="update" />
236
+ <input class="submit" type="submit" name="submit" value="<?php _e('Save Changes') ?>" />
237
+ </fieldset>
238
+ </form>
239
+
240
+ </div>
241
+
242
+ <?php
243
+
244
+ bb_get_admin_footer();
bp-forums/bbpress/bb-admin/options-permalinks.php ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once('admin.php');
4
+
5
+ $file_source = BB_PATH . 'bb-admin/includes/defaults.bb-htaccess.php';
6
+ $file_target = BB_PATH . '.htaccess';
7
+ include( $file_source );
8
+ $file_source_rules = $_rules; // This is a string
9
+
10
+ if ( 'post' == strtolower( $_SERVER['REQUEST_METHOD'] ) && $_POST['action'] == 'update') {
11
+
12
+ bb_check_admin_referer( 'options-permalinks-update' );
13
+
14
+ foreach ( (array) $_POST as $option => $value ) {
15
+ if ( !in_array( $option, array('_wpnonce', '_wp_http_referer', 'action', 'submit') ) ) {
16
+ $option = trim( $option );
17
+ $value = is_array( $value ) ? $value : trim( $value );
18
+ $value = stripslashes_deep( $value );
19
+ if ( $value ) {
20
+ bb_update_option( $option, $value );
21
+ } else {
22
+ bb_delete_option( $option );
23
+ }
24
+ }
25
+ }
26
+
27
+ $mod_rewrite = (string) bb_get_option( 'mod_rewrite' );
28
+
29
+ $goback = remove_query_arg( array( 'updated', 'notapache', 'notmodrewrite' ), wp_get_referer() );
30
+
31
+ // Make sure mod_rewrite is possible on the server
32
+ if ( !$is_apache ) {
33
+ bb_delete_option( 'mod_rewrite_writable' );
34
+ $goback = add_query_arg( 'notapache', 'true', $goback );
35
+ bb_safe_redirect( $goback );
36
+ exit;
37
+ } elseif ( '0' !== $mod_rewrite && !apache_mod_loaded( 'mod_rewrite', true ) ) {
38
+ bb_delete_option( 'mod_rewrite_writable' );
39
+ bb_update_option( 'mod_rewrite', '0' );
40
+ $goback = add_query_arg( 'notmodrewrite', 'true', $goback );
41
+ bb_safe_redirect( $goback );
42
+ exit;
43
+ }
44
+
45
+ $file_target_rules = array();
46
+
47
+ $file_target_exists = false;
48
+ $file_target_writable = true;
49
+ if ( file_exists( $file_target ) ) {
50
+ if ( is_readable( $file_target ) ) {
51
+ $file_target_rules = explode( "\n", implode( '', file( $file_target ) ) );
52
+ }
53
+ $file_target_exists = true;
54
+ if ( !is_writable( $file_target ) ) {
55
+ $file_target_writable = false;
56
+ }
57
+ } else {
58
+ $file_target_dir = dirname( $file_target );
59
+ if ( file_exists( $file_target_dir ) ) {
60
+ if ( !is_writable( $file_target_dir ) || !is_dir( $file_target_dir ) ) {
61
+ $file_target_writable = false;
62
+ }
63
+ } else {
64
+ $file_target_writable = false;
65
+ }
66
+ }
67
+
68
+ // Strip out existing bbPress rules
69
+ $_keep_rule = true;
70
+ $_kept_rules = array();
71
+ foreach ( $file_target_rules as $_rule ) {
72
+ if ( false !== strpos( $_rule, '# BEGIN bbPress' ) ) {
73
+ $_keep_rule = false;
74
+ continue;
75
+ } elseif ( false !== strpos( $_rule, '# END bbPress' ) ) {
76
+ $_keep_rule = true;
77
+ continue;
78
+ }
79
+ if ( $_keep_rule ) {
80
+ $_kept_rules[] = $_rule;
81
+ }
82
+ }
83
+
84
+ $file_target_rules = join( "\n", $_kept_rules ) . "\n" . $file_source_rules;
85
+
86
+ $file_target_written = 0;
87
+ if ( $file_target_writable ) {
88
+ // Open the file for writing - rewrites the whole file
89
+ if ( $file_target_handle = fopen( $file_target, 'w' ) ) {
90
+ if ( fwrite( $file_target_handle, $file_target_rules ) ) {
91
+ $file_target_written = 1;
92
+ }
93
+ // Close the file
94
+ fclose( $file_target_handle );
95
+ @chmod( $file_target, 0666 );
96
+ }
97
+ }
98
+
99
+ bb_update_option( 'mod_rewrite_writable', $file_target_writable );
100
+ $goback = add_query_arg( 'updated', 'true', $goback );
101
+ bb_safe_redirect( $goback );
102
+ exit;
103
+ }
104
+
105
+ if ( $is_apache && bb_get_option( 'mod_rewrite' ) && !bb_get_option( 'mod_rewrite_writable' ) ) {
106
+ $manual_instructions = true;
107
+ }
108
+
109
+ if ( !empty( $_GET['notmodrewrite'] ) ) {
110
+ $manual_instructions = false;
111
+ bb_admin_notice( __( '<strong>It appears that your server does not support custom permalink structures.</strong>' ), 'error' );
112
+ }
113
+
114
+ if ( !empty( $_GET['notapache'] ) ) {
115
+ $manual_instructions = false;
116
+ bb_admin_notice( __( '<strong>Rewriting on webservers other than Apache using mod_rewrite is currently unsupported, but we won&#8217;t stop you from trying.</strong>' ), 'error' );
117
+ }
118
+
119
+ if ( !empty( $_GET['updated'] ) ) {
120
+ if ( $manual_instructions ) {
121
+ bb_admin_notice( __( '<strong>You should update your .htaccess now.</strong>' ) );
122
+ } else {
123
+ bb_admin_notice( __( '<strong>Permalink structure updated.</strong>' ) );
124
+ }
125
+ }
126
+
127
+ $permalink_options = array(
128
+ 'mod_rewrite' => array(
129
+ 'title' => __( 'Permalink type' ),
130
+ 'type' => 'radio',
131
+ 'options' => array(
132
+ '0' => sprintf( __( '<span>None</span> <code>%s</code>' ), bb_get_uri( 'forums.php', array( 'id' => 1 ), BB_URI_CONTEXT_TEXT ) ),
133
+ '1' => sprintf( __( '<span>Numeric</span> <code>%s</code>' ), bb_get_uri( 'forums/1', null, BB_URI_CONTEXT_TEXT ) ),
134
+ 'slugs' => sprintf( __( '<span>Name based</span> <code>%s</code>' ), bb_get_uri( '/forums/first-forum', null, BB_URI_CONTEXT_TEXT ) )
135
+ )
136
+ )
137
+ );
138
+
139
+ $bb_admin_body_class = ' bb-admin-settings';
140
+
141
+ bb_get_admin_header();
142
+
143
+ ?>
144
+
145
+ <div class="wrap">
146
+
147
+ <h2><?php _e( 'Permalink Settings' ); ?></h2>
148
+ <?php do_action( 'bb_admin_notices' ); ?>
149
+
150
+ <form class="settings" method="post" action="<?php bb_uri( 'bb-admin/options-permalinks.php', null, BB_URI_CONTEXT_FORM_ACTION + BB_URI_CONTEXT_BB_ADMIN ); ?>">
151
+ <fieldset>
152
+ <p>
153
+ <?php _e( 'By default bbPress uses web URLs which have question marks and lots of numbers in them, however bbPress offers you the ability to choose an alternative URL structure for your permalinks. This can improve the aesthetics, usability, and forward-compatibility of your links.' ); ?>
154
+ </p>
155
+ <?php
156
+ foreach ( $permalink_options as $option => $args ) {
157
+ bb_option_form_element( $option, $args );
158
+ }
159
+ ?>
160
+ </fieldset>
161
+ <fieldset class="submit">
162
+ <?php bb_nonce_field( 'options-permalinks-update' ); ?>
163
+ <input type="hidden" name="action" value="update" />
164
+ <input class="submit" type="submit" name="submit" value="<?php _e('Save Changes') ?>" />
165
+ </fieldset>
166
+ </form>
167
+
168
+ <?php
169
+ if ( $manual_instructions ) {
170
+ ?>
171
+ <form class="settings" method="post" action="<?php bb_uri( 'bb-admin/options-permalinks.php', null, BB_URI_CONTEXT_FORM_ACTION + BB_URI_CONTEXT_BB_ADMIN ); ?>">
172
+ <fieldset>
173
+ <p>
174
+ <?php _e( 'If your <code>.htaccess</code> file were <a href="http://codex.wordpress.org/Changing_File_Permissions">writable</a>, we could do this automatically, but it isn&#8217;t so these are the mod_rewrite rules you should have in your <code>.htaccess</code> file. Click in the field and press <kbd>CTRL + a</kbd> to select all.' ); ?>
175
+ </p>
176
+ <textarea dir="ltr" id="rewrite-rules" class="readonly" readonly="readonly" rows="6"><?php echo esc_html( trim( $file_source_rules ) ); ?></textarea>
177
+ </fieldset>
178
+ </form>
179
+
180
+ <?php
181
+ }
182
+ ?>
183
+
184
+ </div>
185
+
186
+ <?php
187
+
188
+ bb_get_admin_footer();
bp-forums/bbpress/bb-admin/options-reading.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once('admin.php');
4
+
5
+ if ( 'post' == strtolower( $_SERVER['REQUEST_METHOD'] ) && $_POST['action'] == 'update') {
6
+
7
+ bb_check_admin_referer( 'options-reading-update' );
8
+
9
+ foreach ( (array) $_POST as $option => $value ) {
10
+ if ( !in_array( $option, array('_wpnonce', '_wp_http_referer', 'action', 'submit') ) ) {
11
+ $option = trim( $option );
12
+ $value = is_array( $value ) ? $value : trim( $value );
13
+ $value = stripslashes_deep( $value );
14
+ if ( $value ) {
15
+ bb_update_option( $option, $value );
16
+ } else {
17
+ bb_delete_option( $option );
18
+ }
19
+ }
20
+ }
21
+
22
+ $goback = add_query_arg('updated', 'true', wp_get_referer());
23
+ bb_safe_redirect($goback);
24
+ exit;
25
+ }
26
+
27
+ if ( !empty($_GET['updated']) ) {
28
+ bb_admin_notice( __( '<strong>Settings saved.</strong>' ) );
29
+ }
30
+
31
+ $reading_options = array(
32
+ 'page_topics' => array(
33
+ 'title' => __( 'Items per page' ),
34
+ 'class' => 'short',
35
+ 'note' => __( 'Number of topics, posts or tags to show per page.' ),
36
+ )
37
+ );
38
+
39
+ $bb_admin_body_class = ' bb-admin-settings';
40
+
41
+ bb_get_admin_header();
42
+
43
+ ?>
44
+
45
+ <div class="wrap">
46
+
47
+ <h2><?php _e('Reading Settings'); ?></h2>
48
+ <?php do_action( 'bb_admin_notices' ); ?>
49
+
50
+ <form class="settings" method="post" action="<?php bb_uri('bb-admin/options-reading.php', null, BB_URI_CONTEXT_FORM_ACTION + BB_URI_CONTEXT_BB_ADMIN); ?>">
51
+ <fieldset>
52
+ <?php
53
+ foreach ( $reading_options as $option => $args ) {
54
+ bb_option_form_element( $option, $args );
55
+ }
56
+ ?>
57
+ </fieldset>
58
+ <fieldset class="submit">
59
+ <?php bb_nonce_field( 'options-reading-update' ); ?>
60
+ <input type="hidden" name="action" value="update" />
61
+ <input class="submit" type="submit" name="submit" value="<?php _e('Save Changes') ?>" />
62
+ </fieldset>
63
+ </form>
64
+
65
+ </div>
66
+
67
+ <?php
68
+
69
+ bb_get_admin_footer();
bp-forums/bbpress/bb-admin/options-wordpress.php ADDED
@@ -0,0 +1,311 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once('admin.php');
4
+
5
+ if ( 'post' == strtolower( $_SERVER['REQUEST_METHOD'] ) )
6
+ $action = @$_POST['action'];
7
+ else
8
+ $action = false;
9
+
10
+ if ( in_array( $action, array('update-users', 'update-options') ) ) {
11
+ bb_check_admin_referer( 'options-wordpress-' . $action );
12
+
13
+ // Deal with advanced user database checkbox when it isn't checked
14
+ if (!isset($_POST['user_bbdb_advanced'])) {
15
+ $_POST['user_bbdb_advanced'] = false;
16
+ }
17
+
18
+ foreach ( (array) $_POST as $option => $value ) {
19
+ if ( !in_array( $option, array('_wpnonce', '_wp_http_referer', 'action', 'submit') ) ) {
20
+ $option = trim( $option );
21
+ $value = is_array( $value ) ? $value : trim( $value );
22
+ $value = stripslashes_deep( $value );
23
+ if ( ( $option == 'wp_siteurl' || $option == 'wp_home' ) && !empty( $value ) ) {
24
+ $value = rtrim( $value, " \t\n\r\0\x0B/" ) . '/';
25
+ }
26
+ if ( $value ) {
27
+ bb_update_option( $option, $value );
28
+ } else {
29
+ bb_delete_option( $option );
30
+ }
31
+ }
32
+ }
33
+
34
+ if ($action == 'update-users') {
35
+ bb_apply_wp_role_map_to_orphans();
36
+ }
37
+
38
+ $goback = add_query_arg('updated', $action, wp_get_referer());
39
+ bb_safe_redirect($goback);
40
+ exit;
41
+ }
42
+
43
+ switch (@$_GET['updated']) {
44
+ case 'update-users':
45
+ bb_admin_notice( __( '<strong>User role mapping saved.</strong>' ) );
46
+ break;
47
+ case 'update-options':
48
+ bb_admin_notice( __( '<strong>User integration settings saved.</strong>' ) );
49
+ break;
50
+ }
51
+
52
+
53
+
54
+ $bb_role_names[''] = _c( 'none|no bbPress role' );
55
+ $bb_role_names = array_merge( $bb_role_names, array_map( create_function( '$a', 'return sprintf( _c( "bbPress %s|bbPress role" ), $a );' ), $wp_roles->get_names() ) );
56
+
57
+ $wpRoles = array(
58
+ 'administrator' => __('WordPress Administrator'),
59
+ 'editor' => __('WordPress Editor'),
60
+ 'author' => __('WordPress Author'),
61
+ 'contributor' => __('WordPress Contributor'),
62
+ 'subscriber' => __('WordPress Subscriber')
63
+ );
64
+
65
+ $cookie_options = array(
66
+ 'wp_siteurl' => array(
67
+ 'title' => __( 'WordPress address (URL)' ),
68
+ 'class' => 'long',
69
+ 'note' => __( 'This value should exactly match the <strong>WordPress address (URL)</strong> setting in your WordPress general settings.' )
70
+ ),
71
+ 'wp_home' => array(
72
+ 'title' => __( 'Blog address (URL)' ),
73
+ 'class' => 'long',
74
+ 'note' => __( 'This value should exactly match the <strong>Blog address (URL)</strong> setting in your WordPress general settings.' )
75
+ ),
76
+ 'bb_auth_salt' => array(
77
+ 'title' => __( 'WordPress "auth" cookie salt' ),
78
+ 'note' => __( 'This must match the value of the WordPress setting named "auth_salt" in your WordPress site. Look for the option labeled "auth_salt" in <a href="#" id="getAuthSaltOption" onclick="window.open(this.href); return false;">this WordPress admin page</a>.' )
79
+ ),
80
+ 'bb_secure_auth_salt' => array(
81
+ 'title' => __( 'WordPress "secure auth" cookie salt' ),
82
+ 'note' => __( 'This must match the value of the WordPress setting named "secure_auth_salt" in your WordPress site. Look for the option labeled "secure_auth_salt" in <a href="#" id="getSecureAuthSaltOption" onclick="window.open(this.href); return false;">this WordPress admin page</a>. Sometimes this value is not set in WordPress, in that case you can leave this setting blank as well.' )
83
+ ),
84
+ 'bb_logged_in_salt' => array(
85
+ 'title' => __( 'WordPress "logged in" cookie salt' ),
86
+ 'note' => __( 'This must match the value of the WordPress setting named "logged_in_salt" in your WordPress site. Look for the option labeled "logged_in_salt" in <a href="#" id="getLoggedInSaltOption" onclick="window.open(this.href); return false;">this WordPress admin page</a>.' )
87
+ )
88
+ );
89
+
90
+ foreach ( array( 'bb_auth_salt', 'bb_secure_auth_salt', 'bb_logged_in_salt' ) as $salt_constant ) {
91
+ if ( defined( strtoupper( $salt_constant ) ) ) {
92
+ $cookie_options[$salt_constant]['note'] = array(
93
+ sprintf( __( 'You have defined the "%s" constant which locks this setting.' ), strtoupper( $salt_constant ) ),
94
+ $cookie_options[$salt_constant]['note'],
95
+ );
96
+ $cookie_options[$salt_constant]['value'] = constant( strtoupper( $salt_constant ) );
97
+ $bb_hardcoded[$salt_constant] = true;
98
+ }
99
+ }
100
+
101
+ $user_db_options = array(
102
+ 'wp_table_prefix' => array(
103
+ 'title' => __( 'User database table prefix' ),
104
+ 'note' => __( 'If your bbPress and WordPress sites share the same database, then this is the same value as <code>$table_prefix</code> in your WordPress <code>wp-config.php</code> file. It is usually <strong>wp_</strong>.' )
105
+ ),
106
+ 'wordpress_mu_primary_blog_id' => array(
107
+ 'title' => __( 'WordPress MU primary blog ID' ),
108
+ 'note' => __( 'If you are integrating with a WordPress MU site you need to specify the primary blog ID for that site. It is usually <strong>1</strong>. You should probably leave this blank if you are integrating with a standard WordPress site' )
109
+ ),
110
+ 'user_bbdb_advanced' => array(
111
+ 'title' => __( 'Show advanced database settings' ),
112
+ 'type' => 'checkbox',
113
+ 'options' => array(
114
+ 1 => array(
115
+ 'label' => __( 'If your bbPress and WordPress site do not share the same database, then you will need to add advanced settings.' ),
116
+ 'attributes' => array( 'onclick' => 'toggleAdvanced(this);' )
117
+ )
118
+ )
119
+ )
120
+ );
121
+
122
+ $advanced_user_db_options = array(
123
+ 'user_bbdb_name' => array(
124
+ 'title' => __( 'User database name' ),
125
+ 'note' => __( 'The name of the database in which your user tables reside.' )
126
+ ),
127
+ 'user_bbdb_user' => array(
128
+ 'title' => __( 'User database user' ),
129
+ 'note' => __( 'The database user that has access to that database.' )
130
+ ),
131
+ 'user_bbdb_password' => array(
132
+ 'title' => __( 'User database password' ),
133
+ 'note' => __( 'That database user\'s password.' )
134
+ ),
135
+ 'user_bbdb_host' => array(
136
+ 'title' => __( 'User database host' ),
137
+ 'note' => __( 'The domain name or IP address of the server where the database is located. If the database is on the same server as the web site, then this probably should be <strong>localhost</strong>.' )
138
+ ),
139
+ 'user_bbdb_charset' => array(
140
+ 'title' => __( 'User database character set' ),
141
+ 'note' => __( 'The best choice is <strong>utf8</strong>, but you will need to match the character set which you created the database with.' )
142
+ ),
143
+ 'user_bbdb_collate' => array(
144
+ 'title' => __( 'User database character collation' ),
145
+ 'note' => __( 'The character collation value set when the user database was created.' )
146
+ )
147
+ );
148
+
149
+ $custom_table_options = array(
150
+ 'custom_user_table' => array(
151
+ 'title' => __( 'User database "user" table' ),
152
+ 'note' => __( 'The complete table name, including any prefix.' ),
153
+ ),
154
+ 'custom_user_meta_table' => array(
155
+ 'title' => __( 'User database "user meta" table' ),
156
+ 'note' => __( 'The complete table name, including any prefix.' ),
157
+ ),
158
+ );
159
+
160
+ $advanced_display = bb_get_option( 'user_bbdb_advanced' ) ? 'block' : 'none';
161
+
162
+ $bb_admin_body_class = ' bb-admin-settings';
163
+
164
+ bb_get_admin_header();
165
+
166
+ ?>
167
+
168
+ <div class="wrap">
169
+
170
+ <h2><?php _e( 'WordPress Integration Settings' ); ?></h2>
171
+ <?php do_action( 'bb_admin_notices' ); ?>
172
+
173
+ <form class="settings" method="post" action="<?php bb_uri('bb-admin/options-wordpress.php', null, BB_URI_CONTEXT_FORM_ACTION + BB_URI_CONTEXT_BB_ADMIN); ?>">
174
+ <fieldset>
175
+ <legend><?php _e('User Role Map'); ?></legend>
176
+ <p><?php _e('Here you can match WordPress roles to bbPress roles.'); ?></p>
177
+ <p><?php _e('This will have no effect until your user tables are integrated below. Only standard WordPress roles are supported. Changes do not affect users with existing roles in both WordPress and bbPress.'); ?></p>
178
+ <?php foreach ( $wpRoles as $wpRole => $wpRoleName ) bb_option_form_element( "wp_roles_map[$wpRole]", array( 'title' => $wpRoleName, 'type' => 'select', 'options' => $bb_role_names ) ); ?>
179
+ </fieldset>
180
+ <fieldset class="submit">
181
+ <?php bb_nonce_field( 'options-wordpress-update-users' ); ?>
182
+ <input type="hidden" name="action" value="update-users" />
183
+ <input class="submit" type="submit" name="submit" value="<?php _e('Save Changes') ?>" />
184
+ </fieldset>
185
+ </form>
186
+
187
+ <hr class="settings" />
188
+
189
+ <div class="settings">
190
+ <h3><?php _e('User Integration'); ?></h3>
191
+ <p><?php _e('Usually, you will have to specify both cookie integration and user database integration settings. Make sure you have a "User role map" setup above before trying to add user integration.'); ?></p>
192
+ <p><?php _e('<em><strong>Note:</strong> changing the settings below may cause you to be logged out!</em>'); ?></p>
193
+ </div>
194
+
195
+ <form class="settings" method="post" action="<?php bb_uri('bb-admin/options-wordpress.php', null, BB_URI_CONTEXT_FORM_ACTION + BB_URI_CONTEXT_BB_ADMIN); ?>">
196
+ <fieldset>
197
+ <legend><?php _e('Cookies'); ?></legend>
198
+ <p><?php _e('Cookie sharing allows users to log in to either your bbPress or your WordPress site, and have access to both.'); ?></p>
199
+ <?php foreach ( $cookie_options as $option => $args ) bb_option_form_element( $option, $args ); ?>
200
+ <script type="text/javascript" charset="utf-8">
201
+ /* <![CDATA[ */
202
+ function updateWordPressOptionURL () {
203
+ var siteURLInputValue = document.getElementById('wp-siteurl').value;
204
+ if (siteURLInputValue && siteURLInputValue.substr(-1,1) != '/') {
205
+ siteURLInputValue += '/';
206
+ }
207
+ var authSaltAnchor = document.getElementById('getAuthSaltOption');
208
+ var secureAuthSaltAnchor = document.getElementById('getSecureAuthSaltOption');
209
+ var loggedInSaltAnchor = document.getElementById('getLoggedInSaltOption');
210
+ if (siteURLInputValue) {
211
+ authSaltAnchor.href = siteURLInputValue + 'wp-admin/options.php';
212
+ secureAuthSaltAnchor.href = siteURLInputValue + 'wp-admin/options.php';
213
+ loggedInSaltAnchor.href = siteURLInputValue + 'wp-admin/options.php';
214
+ } else {
215
+ authSaltAnchor.href = '';
216
+ secureAuthSaltAnchor.href = '';
217
+ loggedInSaltAnchor.href = '';
218
+ }
219
+ }
220
+ var siteURLInput = document.getElementById('wp-siteurl');
221
+ if (siteURLInput.value) {
222
+ updateWordPressOptionURL();
223
+ }
224
+ siteURLInput.onkeyup = updateWordPressOptionURL;
225
+ siteURLInput.onblur = updateWordPressOptionURL;
226
+ siteURLInput.onclick = updateWordPressOptionURL;
227
+ siteURLInput.onchange = updateWordPressOptionURL;
228
+ /* ]]> */
229
+ </script>
230
+ <?php
231
+ $cookie_settings = array(
232
+ 'cookiedomain' => 'COOKIE_DOMAIN',
233
+ 'cookiepath' => 'COOKIEPATH'
234
+ );
235
+ $wp_settings = '';
236
+ foreach ($cookie_settings as $bb_setting => $wp_setting) {
237
+ if ( isset($bb->$bb_setting) ) {
238
+ $wp_settings .= 'define(\'' . $wp_setting . '\', \'' . $bb->$bb_setting . '\');' . "\n";
239
+ }
240
+ }
241
+ ?>
242
+ <p><?php printf(__('To complete cookie integration, you will need to add some settings to your <code>wp-config.php</code> file in the root directory of your WordPress installation. To get those settings, you will need to install and configure the <a href="%s">"bbPress Integration" plugin for WordPress</a>.'), 'http://wordpress.org/extend/plugins/bbpress-integration/'); ?></p>
243
+ <p><?php _e('You will also have to manually ensure that the following constants are equivalent in WordPress\' and bbPress\' respective config files.'); ?></p>
244
+ <div class="table">
245
+ <table>
246
+ <tr>
247
+ <th><?php _e('WordPress'); ?></th>
248
+ <td></td>
249
+ <th><?php _e('bbPress'); ?></th>
250
+ </tr>
251
+ <tr>
252
+ <td>AUTH_KEY</td>
253
+ <td>&lt;=&gt;</td>
254
+ <td>BB_AUTH_KEY</td>
255
+ </tr>
256
+ <tr>
257
+ <td>SECURE_AUTH_KEY</td>
258
+ <td>&lt;=&gt;</td>
259
+ <td>BB_SECURE_AUTH_KEY</td>
260
+ </tr>
261
+ <tr>
262
+ <td>LOGGED_IN_KEY</td>
263
+ <td>&lt;=&gt;</td>
264
+ <td>BB_LOGGED_IN_KEY</td>
265
+ </tr>
266
+ </table>
267
+ </div>
268
+ </fieldset>
269
+
270
+ <fieldset>
271
+ <legend><?php _e('User database'); ?></legend>
272
+ <p><?php _e('User database sharing allows you to store user data in your WordPress database.'); ?></p>
273
+ <p><?php _e('You should setup a "User role map" before'); ?></p>
274
+ <script type="text/javascript" charset="utf-8">
275
+ function toggleAdvanced(checkedObj) {
276
+ var advanced1 = document.getElementById('advanced1');
277
+ var advanced2 = document.getElementById('advanced2');
278
+ if (checkedObj.checked) {
279
+ advanced1.style.display = 'block';
280
+ advanced2.style.display = 'block';
281
+ } else {
282
+ advanced1.style.display = 'none';
283
+ advanced2.style.display = 'none';
284
+ }
285
+ }
286
+ </script>
287
+ <?php foreach ( $user_db_options as $option => $args ) bb_option_form_element( $option, $args ); ?>
288
+ </fieldset>
289
+ <fieldset id="advanced1" style="display:<?php echo $advanced_display; ?>">
290
+ <legend><?php _e('Separate user database settings'); ?></legend>
291
+ <p><?php _e('Most of the time these settings are <em>not</em> required. Look before you leap!'); ?></p>
292
+ <p><?php _e('All settings except for the character set must be specified.'); ?></p>
293
+ <?php foreach ( $advanced_user_db_options as $option => $args ) bb_option_form_element( $option, $args ); ?>
294
+ </fieldset>
295
+ <fieldset id="advanced2" style="display:<?php echo $advanced_display; ?>">
296
+ <legend><?php _e('Custom user tables'); ?></legend>
297
+ <p><?php _e('Only set these values if your user tables differ from the default WordPress naming convention.'); ?></p>
298
+ <?php foreach ( $custom_table_options as $option => $args ) bb_option_form_element( $option, $args ); ?>
299
+ </fieldset>
300
+ <fieldset class="submit">
301
+ <?php bb_nonce_field( 'options-wordpress-update-options' ); ?>
302
+ <input type="hidden" name="action" value="update-options" />
303
+ <input class="submit" type="submit" name="submit" value="<?php _e('Save Changes') ?>" />
304
+ </fieldset>
305
+ </form>
306
+
307
+ </div>
308
+
309
+ <?php
310
+ bb_get_admin_footer();
311
+ ?>
bp-forums/bbpress/bb-admin/options-writing.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once('admin.php');
4
+
5
+ if ( 'post' == strtolower( $_SERVER['REQUEST_METHOD'] ) && $_POST['action'] == 'update') {
6
+
7
+ bb_check_admin_referer( 'options-writing-update' );
8
+
9
+ // Deal with xmlrpc checkbox when it isn't checked
10
+ if (!isset($_POST['enable_xmlrpc'])) {
11
+ $_POST['enable_xmlrpc'] = false;
12
+ }
13
+
14
+ foreach ( (array) $_POST as $option => $value ) {
15
+ if ( !in_array( $option, array('_wpnonce', '_wp_http_referer', 'action', 'submit') ) ) {
16
+ $option = trim( $option );
17
+ $value = is_array( $value ) ? $value : trim( $value );
18
+ $value = stripslashes_deep( $value );
19
+ if ( $value ) {
20
+ bb_update_option( $option, $value );
21
+ } else {
22
+ bb_delete_option( $option );
23
+ }
24
+ }
25
+ }
26
+
27
+ $goback = add_query_arg('updated', 'true', wp_get_referer());
28
+ bb_safe_redirect($goback);
29
+ exit;
30
+ }
31
+
32
+ if ( !empty($_GET['updated']) ) {
33
+ bb_admin_notice( __( '<strong>Settings saved.</strong>' ) );
34
+ }
35
+
36
+ $general_options = array(
37
+ 'edit_lock' => array(
38
+ 'title' => __( 'Lock post editing after' ),
39
+ 'class' => 'short',
40
+ 'after' => __( 'minutes' ),
41
+ 'note' => __( 'A user can edit a post for this many minutes after submitting.' ),
42
+ )
43
+ );
44
+
45
+ $remote_options = array(
46
+ 'enable_xmlrpc' => array(
47
+ 'title' => __( 'XML-RPC' ),
48
+ 'type' => 'checkbox',
49
+ 'options' => array(
50
+ 1 => __( 'Enable the bbPress XML-RPC publishing protocol.' )
51
+ )
52
+ )
53
+ );
54
+
55
+ $bb_admin_body_class = ' bb-admin-settings';
56
+
57
+ bb_get_admin_header();
58
+
59
+ ?>
60
+
61
+ <div class="wrap">
62
+
63
+ <h2><?php _e('Writing Settings'); ?></h2>
64
+ <?php do_action( 'bb_admin_notices' ); ?>
65
+
66
+ <form class="settings" method="post" action="<?php bb_uri( 'bb-admin/options-writing.php', null, BB_URI_CONTEXT_FORM_ACTION + BB_URI_CONTEXT_BB_ADMIN ); ?>">
67
+ <fieldset><?php foreach ( $general_options as $option => $args ) bb_option_form_element( $option, $args ); ?></fieldset>
68
+ <fieldset>
69
+ <legend><?php _e('Remote Publishing'); ?></legend>
70
+ <p>
71
+ <?php _e( 'To interact with bbPress from a desktop client or remote website that uses the XML-RPC publishing interface you must enable it below.' ); ?>
72
+ </p>
73
+ <?php foreach ( $remote_options as $option => $args ) bb_option_form_element( $option, $args ); ?>
74
+ </fieldset>
75
+ <fieldset class="submit">
76
+ <?php bb_nonce_field( 'options-writing-update' ); ?>
77
+ <input type="hidden" name="action" value="update" />
78
+ <input class="submit" type="submit" name="submit" value="<?php _e('Save Changes') ?>" />
79
+ </fieldset>
80
+ </form>
81
+
82
+ </div>
83
+
84
+ <?php
85
+
86
+ bb_get_admin_footer();
bp-forums/bbpress/bb-admin/plugins.php ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once( 'admin.php' );
3
+
4
+ require_once( 'includes/functions.bb-plugin.php' );
5
+
6
+ $plugin_request = 'all';
7
+
8
+ if ( isset( $_GET['plugin_request'] ) ) {
9
+ $plugin_request = (string) $_GET['plugin_request'];
10
+ }
11
+
12
+ switch ( $plugin_request ) {
13
+ case 'active':
14
+ $_plugin_type = 'normal';
15
+ $_plugin_status = 'active';
16
+ break;
17
+ case 'inactive':
18
+ $_plugin_type = 'normal';
19
+ $_plugin_status = 'inactive';
20
+ break;
21
+ case 'autoload':
22
+ $_plugin_type = 'autoload';
23
+ $_plugin_status = 'all';
24
+ break;
25
+ default:
26
+ $plugin_request = 'all'; // For sanitisation
27
+ $_plugin_type = 'all';
28
+ $_plugin_status = 'all';
29
+ break;
30
+ }
31
+
32
+ $plugin_nav_class = array(
33
+ 'all' => '',
34
+ 'active' => '',
35
+ 'inactive' => '',
36
+ 'autoload' => ''
37
+ );
38
+ $plugin_nav_class[$plugin_request] = ' class="current"';
39
+
40
+ // Get plugin counts
41
+ extract( bb_get_plugin_counts() );
42
+
43
+ // Get requested plugins
44
+ $requested_plugins = bb_get_plugins( 'all', $_plugin_type, $_plugin_status );
45
+
46
+ // Get currently active
47
+ $active_plugins = (array) bb_get_option( 'active_plugins' );
48
+
49
+ // Check for missing plugin files and remove them from the active plugins array
50
+ $update = false;
51
+ foreach ( $active_plugins as $index => $plugin ) {
52
+ if ( !file_exists( bb_get_plugin_path( $plugin ) ) ) {
53
+ $update = true;
54
+ unset( $active_plugins[$index] );
55
+ }
56
+ }
57
+ if ( $update ) {
58
+ bb_update_option( 'active_plugins', $active_plugins );
59
+ }
60
+ unset( $update, $index, $plugin );
61
+
62
+ // Set the action
63
+ $action = '';
64
+ if( isset( $_GET['action'] ) && !empty( $_GET['action'] ) ) {
65
+ $action = trim( $_GET['action'] );
66
+ }
67
+
68
+ // Set the plugin
69
+ $plugin = isset( $_GET['plugin'] ) ? trim( stripslashes( $_GET['plugin'] ) ) : '';
70
+
71
+ // Deal with user actions
72
+ if ( !empty( $action ) ) {
73
+ switch ( $action ) {
74
+ case 'activate':
75
+ // Activation
76
+ bb_check_admin_referer( 'activate-plugin_' . $plugin );
77
+
78
+ $result = bb_activate_plugin( $plugin, 'plugins.php?message=error&plugin=' . urlencode( $plugin ) );
79
+ if ( is_wp_error( $result ) )
80
+ bb_die( $result );
81
+
82
+ // Overrides the ?message=error one above
83
+ wp_redirect( 'plugins.php?plugin_request=' . $plugin_request . '&message=activate&plugin=' . urlencode( $plugin ) );
84
+ break;
85
+
86
+ case 'deactivate':
87
+ // Deactivation
88
+ bb_check_admin_referer( 'deactivate-plugin_' . $plugin );
89
+
90
+ // Remove the deactivated plugin
91
+ bb_deactivate_plugins( $plugin );
92
+
93
+ // Redirect
94
+ wp_redirect( 'plugins.php?plugin_request=' . $plugin_request . '&message=deactivate&plugin=' . urlencode( $plugin ) );
95
+ break;
96
+
97
+ case 'scrape':
98
+ // Scrape php errors from the plugin
99
+ bb_check_admin_referer('scrape-plugin_' . $plugin);
100
+
101
+ $valid_path = bb_validate_plugin( $plugin );
102
+ if ( is_wp_error( $valid_path ) )
103
+ bb_die( $valid_path );
104
+
105
+ // Pump up the errors and output them to screen
106
+ error_reporting( E_ALL ^ E_NOTICE );
107
+ @ini_set( 'display_errors', true );
108
+
109
+ include( $valid_path );
110
+ break;
111
+ }
112
+
113
+ // Stop processing
114
+ exit;
115
+ }
116
+
117
+ // Display notices
118
+ if ( isset($_GET['message']) ) {
119
+ switch ( $_GET['message'] ) {
120
+ case 'error' :
121
+ bb_admin_notice( __( '<strong>Plugin could not be activated, it produced a Fatal Error</strong>. The error is shown below.' ), 'error' );
122
+ break;
123
+ case 'activate' :
124
+ $plugin_data = bb_get_plugin_data( $plugin );
125
+ bb_admin_notice( sprintf( __( '<strong>"%s" plugin activated</strong>' ), esc_attr( $plugin_data['name'] ) ) );
126
+ break;
127
+ case 'deactivate' :
128
+ $plugin_data = bb_get_plugin_data( $plugin );
129
+ bb_admin_notice( sprintf( __( '<strong>"%s" plugin deactivated</strong>' ), esc_attr( $plugin_data['name'] ) ) );
130
+ break;
131
+ }
132
+ }
133
+
134
+ if ( isset( $bb->safemode ) && $bb->safemode === true ) {
135
+ bb_admin_notice( __( '<strong>"Safe mode" is on, all plugins are disabled even if they are listed as active.</strong>' ), 'error' );
136
+ }
137
+
138
+ $bb_admin_body_class = ' bb-admin-plugins';
139
+
140
+ bb_get_admin_header();
141
+ ?>
142
+
143
+ <div class="wrap">
144
+
145
+ <h2><?php _e( 'Manage Plugins' ); ?></h2>
146
+ <?php do_action( 'bb_admin_notices' ); ?>
147
+
148
+ <?php
149
+ if ( bb_verify_nonce( $_GET['_scrape_nonce'], 'scrape-plugin_' . $plugin ) ) {
150
+ $scrape_src = esc_attr(
151
+ bb_nonce_url(
152
+ bb_get_uri(
153
+ 'bb-admin/plugins.php',
154
+ array(
155
+ 'action' => 'scrape',
156
+ 'plugin' => urlencode( $plugin )
157
+ ),
158
+ BB_URI_CONTEXT_IFRAME_SRC + BB_URI_CONTEXT_BB_ADMIN
159
+ ),
160
+ 'scrape-plugin_' . $plugin
161
+ )
162
+ );
163
+ ?>
164
+
165
+ <div class="plugin-error"><iframe src="<?php echo $scrape_src; ?>"></iframe></div>
166
+
167
+ <?php
168
+ }
169
+ ?>
170
+
171
+ <div class="table-filter">
172
+ <a<?php echo $plugin_nav_class['all']; ?> href="<?php bb_uri( 'bb-admin/plugins.php', null, BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN ); ?>"><?php printf( __( 'All <span class="count">(%d)</span>' ), $plugin_count_all ); ?></a> |
173
+ <a<?php echo $plugin_nav_class['active']; ?> href="<?php bb_uri( 'bb-admin/plugins.php', array( 'plugin_request' => 'active' ), BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN ); ?>"><?php printf( __( 'Active <span class="count">(%d)</span>' ), $plugin_count_active ); ?></a> |
174
+ <a<?php echo $plugin_nav_class['inactive']; ?> href="<?php bb_uri( 'bb-admin/plugins.php', array( 'plugin_request' => 'inactive' ), BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN ); ?>"><?php printf( __( 'Inactive <span class="count">(%d)</span>' ), $plugin_count_inactive ); ?></a> |
175
+ <a<?php echo $plugin_nav_class['autoload']; ?> href="<?php bb_uri( 'bb-admin/plugins.php', array( 'plugin_request' => 'autoload' ), BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN ); ?>"><?php printf( __( 'Autoloaded <span class="count">(%d)</span>' ), $plugin_count_autoload ); ?></a>
176
+ </div>
177
+
178
+ <?php
179
+ if ( $requested_plugins ) :
180
+ ?>
181
+
182
+ <table id="plugins-list" class="widefat">
183
+ <thead>
184
+ <tr>
185
+ <th><?php _e( 'Plugin' ); ?></th>
186
+ <th><?php _e( 'Description' ); ?></th>
187
+ </tr>
188
+ </thead>
189
+ <tfoot>
190
+ <tr>
191
+ <th><?php _e( 'Plugin' ); ?></th>
192
+ <th><?php _e( 'Description' ); ?></th>
193
+ </tr>
194
+ </tfoot>
195
+ <tbody>
196
+
197
+ <?php
198
+ foreach ( $requested_plugins as $plugin => $plugin_data ) :
199
+ $class = ' class="inactive"';
200
+ $action = 'activate';
201
+ $action_class = 'edit';
202
+ $action_text = __( 'Activate' );
203
+ if ( $plugin_data['autoload'] ) {
204
+ $class = ' class="autoload"';
205
+ } elseif ( in_array( $plugin, $active_plugins ) ) {
206
+ $class = ' class="active"';
207
+ $action = 'deactivate';
208
+ $action_class = 'delete';
209
+ $action_text = __( 'Deactivate' );
210
+ }
211
+ $href = esc_attr(
212
+ bb_nonce_url(
213
+ bb_get_uri(
214
+ 'bb-admin/plugins.php',
215
+ array(
216
+ 'plugin_request' => $plugin_request,
217
+ 'action' => $action,
218
+ 'plugin' => urlencode($plugin)
219
+ ),
220
+ BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN
221
+ ),
222
+ $action . '-plugin_' . $plugin
223
+ )
224
+ );
225
+ $meta = array();
226
+ if ( $plugin_data['version'] ) $meta[] = sprintf( __( 'Version %s' ), $plugin_data['version'] );
227
+ if ( $plugin_data['author_link'] ) $meta[] = sprintf( __( 'By %s' ), $plugin_data['author_link'] );
228
+ if ( $plugin_data['uri'] ) $meta[] = '<a href="' . $plugin_data['uri'] . '">' . esc_html__( 'Visit plugin site' ) . '</a>';
229
+ if ( count( $meta ) ) {
230
+ $meta = '<p class="meta">' . join( ' | ', $meta ) . '</p>';
231
+ } else {
232
+ $meta = '';
233
+ }
234
+ ?>
235
+
236
+ <tr<?php echo $class; ?>>
237
+ <td class="plugin-name">
238
+ <span class="row-title"><?php echo $plugin_data['name']; ?></span>
239
+ <div><span class="row-actions"><?php if ( !$plugin_data['autoload'] ) : ?><a class="<?php echo $action_class; ?>" href="<?php echo $href; ?>"><?php echo $action_text; ?></a><?php else : ?><span class="note"><?php _e( 'Autoloaded' ); ?></span><?php endif; ?></span>&nbsp;</div>
240
+ </td>
241
+ <td class="plugin-description">
242
+ <?php echo $plugin_data['description']; ?>
243
+ <?php echo $meta; ?>
244
+ </td>
245
+ </tr>
246
+
247
+ <?php
248
+ endforeach;
249
+ ?>
250
+
251
+ </tbody>
252
+ </table>
253
+
254
+ <?php
255
+ else :
256
+ ?>
257
+
258
+ <p class="no-results"><?php _e( 'No plugins found.' ); ?></p>
259
+
260
+ <?php
261
+ endif;
262
+ ?>
263
+
264
+ </div>
265
+
266
+ <?php
267
+ bb_get_admin_footer();
268
+ ?>
bp-forums/bbpress/bb-admin/posts.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once('admin.php');
3
+
4
+ if ( !empty( $_GET['message'] ) ) {
5
+ switch ( (string) $_GET['message'] ) {
6
+ case 'undeleted':
7
+ bb_admin_notice( __( '<strong>Post undeleted.</strong>' ) );
8
+ break;
9
+ case 'deleted':
10
+ bb_admin_notice( __( '<strong>Post deleted.</strong>' ) );
11
+ break;
12
+ case 'spammed':
13
+ bb_admin_notice( __( '<strong>Post spammed.</strong>' ) );
14
+ break;
15
+ case 'unspammed-normal':
16
+ bb_admin_notice( __( '<strong>Post removed from spam.</strong> It is now a normal post.' ) );
17
+ break;
18
+ case 'unspammed-deleted':
19
+ bb_admin_notice( __( '<strong>Post removed from spam.</strong> It is now a deleted post.' ) );
20
+ break;
21
+ }
22
+ }
23
+
24
+ $ip_available = false;
25
+ if ( bb_current_user_can( 'view_by_ip' ) ) {
26
+ $ip_available = true;
27
+ } elseif (isset($_GET['poster_ip'])) {
28
+ unset( $_GET['poster_ip'] );
29
+ }
30
+
31
+ $bb_admin_body_class = ' bb-admin-posts';
32
+
33
+ bb_get_admin_header();
34
+
35
+ if ( !bb_current_user_can('browse_deleted') )
36
+ die(__("Now how'd you get here? And what did you think you'd being doing?")); //This should never happen.
37
+ add_filter( 'get_topic_where', 'bb_no_where' );
38
+ add_filter( 'get_topic_link', 'bb_make_link_view_all' );
39
+ add_filter( 'post_edit_uri', 'bb_make_link_view_all' );
40
+ $post_query = new BB_Query_Form( 'post', array( 'post_status' => 'normal', 'count' => true, 'per_page' => 20 ) );
41
+ $bb_posts =& $post_query->results;
42
+ $total = $post_query->found_rows;
43
+ ?>
44
+
45
+ <div class="wrap">
46
+
47
+ <h2><?php _e( 'Posts' ); ?>
48
+ <?php
49
+ $h2_search = $post_query->get( 'post_text' );
50
+ $h2_forum = $post_query->get( 'forum_id' );
51
+ $h2_tag = $post_query->get( 'tag_id' );
52
+ $h2_author = $post_query->get( 'post_author_id' );
53
+
54
+ $h2_search = $h2_search ? ' ' . sprintf( __('containing &#8220;%s&#8221;'), esc_html( $h2_search ) ) : '';
55
+ $h2_forum = $h2_forum ? ' ' . sprintf( __('in &#8220;%s&#8221;') , get_forum_name( $h2_forum ) ) : '';
56
+ $h2_tag = $h2_tag ? ' ' . sprintf( __('with tag &#8220;%s&#8221;'), esc_html( bb_get_tag_name( $h2_tag ) ) ) : '';
57
+ $h2_author = $h2_author ? ' ' . sprintf( __('by %s') , esc_html( get_user_name( $h2_author ) ) ) : '';
58
+
59
+ if ($ip_available) {
60
+ $h2_ip = $post_query->get( 'poster_ip' );
61
+ $h2_ip = $h2_ip ? ' ' . sprintf( __('from IP address %s'), esc_html( $h2_ip ) ) : '';
62
+ } else {
63
+ $h2_ip = '';
64
+ }
65
+
66
+ if ( $h2_search || $h2_forum || $h2_tag || $h2_author || $h2_ip ) {
67
+ echo '<span class="subtitle">';
68
+
69
+ printf( __( '%1$s%2$s%3$s%4$s%5$s' ), $h2_search, $h2_forum, $h2_tag, $h2_author, $h2_ip );
70
+
71
+ echo '</span>';
72
+ }
73
+ ?>
74
+ </h2>
75
+ <?php do_action( 'bb_admin_notices' ); ?>
76
+
77
+ <?php $post_query->form( array( 'poster_ip' => $ip_available, 'tag' => true, 'post_author' => true, 'post_status' => true, 'submit' => __( 'Filter' ) ) ); ?>
78
+
79
+ <div class="tablenav">
80
+ <?php if ( $total ) : ?>
81
+ <div class="tablenav-pages">
82
+ <span class="displaying-num"><?php echo $displaying_num = sprintf(
83
+ __( '%1$s to %2$s of %3$s' ),
84
+ bb_number_format_i18n( ( $page - 1 ) * $post_query->get( 'per_page' ) + 1 ),
85
+ $page * $post_query->get( 'per_page' ) < $total ? bb_number_format_i18n( $page * $post_query->get( 'per_page' ) ) : '<span class="total-type-count">' . bb_number_format_i18n( $total ) . '</span>',
86
+ '<span class="total-type-count">' . bb_number_format_i18n( $total ) . '</span>'
87
+ ); ?></span><span class="displaying-pages">
88
+ <?php
89
+ $_page_link_args = array(
90
+ 'page' => $page,
91
+ 'total' => $total,
92
+ 'per_page' => $post_query->get( 'per_page' ),
93
+ 'mod_rewrite' => false,
94
+ 'prev_text' => __( '&laquo;' ),
95
+ 'next_text' => __( '&raquo;' )
96
+ );
97
+ echo $page_number_links = get_page_number_links( $_page_link_args );
98
+ ?></span>
99
+ <div class="clear"></div>
100
+ </div>
101
+ <?php endif; ?>
102
+ </div>
103
+ <div class="clear"></div>
104
+
105
+ <?php bb_admin_list_posts(); ?>
106
+
107
+ <div class="tablenav bottom">
108
+ <?php if ( $total ) : ?>
109
+ <div class="tablenav-pages">
110
+ <span class="displaying-pages"><?php echo $page_number_links; ?></span>
111
+ <div class="clear"></div>
112
+ </div>
113
+ <?php endif; ?>
114
+ </div>
115
+ <div class="clear"></div>
116
+
117
+ </div>
118
+
119
+ <?php bb_get_admin_footer(); ?>
bp-forums/bbpress/bb-admin/rewrite-rules.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ require('admin-action.php');
3
+
4
+ wp_redirect( bb_get_uri('bb-admin/options-permalinks.php', null, BB_URI_CONTEXT_BB_ADMIN + BB_URI_CONTEXT_HEADER) );
bp-forums/bbpress/bb-admin/sticky.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require('admin-action.php');
3
+
4
+ $topic_id = (int) $_GET['id'];
5
+ $topic = get_topic ( $topic_id );
6
+ $super = ( isset($_GET['super']) && 1 == (int) $_GET['super'] ) ? 1 : 0;
7
+
8
+ if ( !$topic )
9
+ bb_die(__('There is a problem with that topic, pardner.'));
10
+
11
+ if ( !bb_current_user_can( 'stick_topic', $topic_id ) ) {
12
+ wp_redirect( bb_get_uri(null, null, BB_URI_CONTEXT_HEADER) );
13
+ exit;
14
+ }
15
+
16
+ bb_check_admin_referer( 'stick-topic_' . $topic_id );
17
+
18
+ if ( topic_is_sticky( $topic_id ) )
19
+ bb_unstick_topic ( $topic_id );
20
+ else
21
+ bb_stick_topic ( $topic_id, $super );
22
+
23
+ if ( !$redirect = wp_get_referer() )
24
+ $redirect = get_topic_link( $topic_id );
25
+
26
+ bb_safe_redirect( $redirect );
27
+ exit;
28
+
29
+ ?>
bp-forums/bbpress/bb-admin/style-rtl.css ADDED
@@ -0,0 +1,456 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Start with some basic resets
3
+ */
4
+
5
+ caption,th{text-align:right;}
6
+
7
+
8
+ body {
9
+ font-family: Tahoma, "Times New Roman";
10
+ }
11
+
12
+
13
+
14
+ /* Header */
15
+
16
+ div#bbHead h1 {
17
+ padding-right: 39px;
18
+ padding-left: 0;
19
+ margin-right: 16px;
20
+ margin-left: 0;
21
+ background-position: 100% 7px;
22
+ font-family: "Times New Roman", Tahoma;
23
+ }
24
+
25
+ div#bbHead h1 a em {
26
+ margin-left: auto;
27
+ margin-right: 5px;
28
+ }
29
+
30
+ div#bbUserInfo {
31
+ right: auto;
32
+ left: 15px;
33
+ }
34
+
35
+
36
+
37
+ /* Body */
38
+
39
+ div#bbBody {
40
+ margin-left: 0;
41
+ margin-right: 175px;
42
+ padding-right: 0;
43
+ padding-left: 15px;
44
+ }
45
+
46
+ body.bb-menu-folded div#bbBody {
47
+ margin-left: auto;
48
+ margin-right: 59px;
49
+ }
50
+
51
+ h2 {
52
+ padding-right: 0;
53
+ padding-left: 15px;
54
+ font-family: "Times New Roman", Tahoma;
55
+ }
56
+
57
+ body.bb-admin-dashboard h2 {
58
+ padding-left: auto;
59
+ padding-right: 47px;
60
+ background-position: 100% -172px;
61
+ }
62
+
63
+ body.bb-admin-forums h2 {
64
+ padding-left: auto;
65
+ padding-right: 47px;
66
+ background-position: 100% -802px;
67
+ }
68
+
69
+ body.bb-admin-topics h2 {
70
+ padding-left: auto;
71
+ padding-right: 47px;
72
+ background-position: 100% -802px;
73
+ }
74
+
75
+ body.bb-admin-posts h2 {
76
+ padding-left: auto;
77
+ padding-right: 47px;
78
+ background-position: 100% -802px;
79
+ }
80
+
81
+ body.bb-admin-appearance h2 {
82
+ padding-left: auto;
83
+ padding-right: 47px;
84
+ background-position: 100% 8px;
85
+ }
86
+
87
+ body.bb-admin-plugins h2 {
88
+ padding-left: auto;
89
+ padding-right: 47px;
90
+ background-position: 100% -532px;
91
+ }
92
+
93
+ body.bb-admin-users h2 {
94
+ padding-left: auto;
95
+ padding-right: 47px;
96
+ background-position: 100% -891px;
97
+ }
98
+
99
+ body.bb-admin-tools h2 {
100
+ padding-left: auto;
101
+ padding-right: 47px;
102
+ background-position: 100% -621px;
103
+ }
104
+
105
+ body.bb-admin-settings h2 {
106
+ padding-left: auto;
107
+ padding-right: 47px;
108
+ background-position: 100% -712px;
109
+ }
110
+
111
+
112
+
113
+
114
+
115
+ /* Menu */
116
+ ul#bbAdminMenu {
117
+ float: right;
118
+ margin-right: -160px;
119
+ margin-left: 5px;
120
+ }
121
+
122
+ body.bb-menu-folded ul#bbAdminMenu {
123
+ margin-left: 5px;
124
+ margin-right: -44px;
125
+ }
126
+
127
+ ul#bbAdminMenu li.bb-menu a {
128
+ font-family: "Times New Roman", Tahoma;
129
+ }
130
+
131
+ ul#bbAdminMenu li.bb-menu div.bb-menu-toggle {
132
+ float: left;
133
+ background-image: url('images/menu-bits-rtl.gif');
134
+ background-position: 100% -110px;
135
+ }
136
+
137
+ ul#bbAdminMenu li.bb-menu.bb-menu-has-submenu.bb-menu-current div.bb-menu-toggle {
138
+ background-position: 100% -208px;
139
+ }
140
+
141
+ ul#bbAdminMenu li.bb-menu a div.bb-menu-icon {
142
+ float: right;
143
+ background-position: -331px -39px;
144
+ }
145
+
146
+ ul#bbAdminMenu li.bb-menu.bb-menu-current a div.bb-menu-icon,
147
+ ul#bbAdminMenu li.bb-menu a:hover div.bb-menu-icon {
148
+ background-position: -331px -7px;
149
+ }
150
+
151
+ ul#bbAdminMenu li#bb-menu-dashboard a div.bb-menu-icon {
152
+ background-position: -62px -39px;
153
+ }
154
+
155
+ ul#bbAdminMenu li#bb-menu-dashboard.bb-menu-current a div.bb-menu-icon,
156
+ ul#bbAdminMenu li#bb-menu-dashboard a:hover div.bb-menu-icon {
157
+ background-position: -62px -7px;
158
+ }
159
+
160
+ ul#bbAdminMenu li#bb-menu-forums a div.bb-menu-icon {
161
+ background-position: -272px -39px;
162
+ }
163
+
164
+ ul#bbAdminMenu li#bb-menu-forums.bb-menu-current a div.bb-menu-icon,
165
+ ul#bbAdminMenu li#bb-menu-forums a:hover div.bb-menu-icon {
166
+ background-position: -272px -7px;
167
+ }
168
+
169
+ ul#bbAdminMenu li#bb-menu-topics a div.bb-menu-icon {
170
+ background-position: -272px -39px;
171
+ }
172
+
173
+ ul#bbAdminMenu li#bb-menu-topics.bb-menu-current a div.bb-menu-icon,
174
+ ul#bbAdminMenu li#bb-menu-topics a:hover div.bb-menu-icon {
175
+ background-position: -272px -7px;
176
+ }
177
+
178
+ ul#bbAdminMenu li#bb-menu-posts a div.bb-menu-icon {
179
+ background-position: -272px -39px;
180
+ }
181
+
182
+ ul#bbAdminMenu li#bb-menu-posts.bb-menu-current a div.bb-menu-icon,
183
+ ul#bbAdminMenu li#bb-menu-posts a:hover div.bb-menu-icon {
184
+ background-position: -272px -7px;
185
+ }
186
+
187
+ ul#bbAdminMenu li#bb-menu-appearance a div.bb-menu-icon {
188
+ background-position: -1px -39px;
189
+ }
190
+
191
+ ul#bbAdminMenu li#bb-menu-appearance.bb-menu-current a div.bb-menu-icon,
192
+ ul#bbAdminMenu li#bb-menu-appearance a:hover div.bb-menu-icon {
193
+ background-position: -1px -7px;
194
+ }
195
+
196
+ ul#bbAdminMenu li#bb-menu-plugins a div.bb-menu-icon {
197
+ background-position: -181px -39px;
198
+ }
199
+
200
+ ul#bbAdminMenu li#bb-menu-plugins.bb-menu-current a div.bb-menu-icon,
201
+ ul#bbAdminMenu li#bb-menu-plugins a:hover div.bb-menu-icon {
202
+ background-position: -181px -7px;
203
+ }
204
+
205
+ ul#bbAdminMenu li#bb-menu-users a div.bb-menu-icon {
206
+ background-position: -303px -39px;
207
+ }
208
+
209
+ ul#bbAdminMenu li#bb-menu-users.bb-menu-current a div.bb-menu-icon,
210
+ ul#bbAdminMenu li#bb-menu-users a:hover div.bb-menu-icon {
211
+ background-position: -303px -7px;
212
+ }
213
+
214
+ ul#bbAdminMenu li#bb-menu-tools a div.bb-menu-icon {
215
+ background-position: -212px -39px;
216
+ }
217
+
218
+ ul#bbAdminMenu li#bb-menu-tools.bb-menu-current a div.bb-menu-icon,
219
+ ul#bbAdminMenu li#bb-menu-tools a:hover div.bb-menu-icon {
220
+ background-position: -212px -7px;
221
+ }
222
+
223
+ ul#bbAdminMenu li#bb-menu-settings a div.bb-menu-icon {
224
+ background-position: -241px -39px;
225
+ }
226
+
227
+ ul#bbAdminMenu li#bb-menu-settings.bb-menu-current a div.bb-menu-icon,
228
+ ul#bbAdminMenu li#bb-menu-settings a:hover div.bb-menu-icon {
229
+ background-position: -241px -7px;
230
+ }
231
+
232
+ ul#bbAdminMenu li.bb-menu.bb-menu-separator a {
233
+ background-position: -55px -34px;
234
+ cursor: e-resize;
235
+ }
236
+
237
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu.bb-menu-separator a {
238
+ background-position: 0 5px;
239
+ cursor: w-resize;
240
+ }
241
+
242
+ ul#bbAdminMenu li.bb-menu div.bb-menu-sub-wrap {
243
+ border-left-width: 1px;
244
+ border-right-width: 0;
245
+ }
246
+
247
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu div.bb-menu-sub-wrap {
248
+ left: auto;
249
+ right: 36px;
250
+ }
251
+
252
+ ul#bbAdminMenu li.bb-menu div.bb-menu-sub-wrap span {
253
+ font-family: "Times New Roman", Tahoma;
254
+ padding-right: 10px;
255
+ padding-left: 5px;
256
+ }
257
+
258
+ ul#bbAdminMenu li.bb-menu li.bb-menu-sub a {
259
+ font-family: Tahoma, "Times New Roman";
260
+ padding-right:12px;
261
+ padding-left: 5px;
262
+ background-image: url('images/menu-bits-rtl.gif');
263
+ background-position: 100% -306px;
264
+ }
265
+
266
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu li.bb-menu-sub a {
267
+ background-image: url('images/menu-bits-rtl.gif');
268
+ background-position: 100% -306px;
269
+ border-right-width: 0 !important;
270
+ border-left-width: 1px !important;
271
+ }
272
+
273
+ ul#bbAdminMenu li.bb-menu.bb-menu-current li.bb-menu-sub a {
274
+ background-image: url('images/menu-dark-rtl.gif');
275
+ background-position: 100% -20px !important;
276
+ }
277
+
278
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu.bb-menu-current li.bb-menu-sub a {
279
+ background-image: url('images/menu-dark-rtl.gif');
280
+ background-position: 100% -20px !important;
281
+ }
282
+
283
+ ul#bbAdminMenu li.bb-menu.bb-menu-current li.bb-menu-sub.bb-menu-sub-current a {
284
+ background-position: 100% 0 !important;
285
+ }
286
+
287
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu.bb-menu-current li.bb-menu-sub.bb-menu-sub-current a {
288
+ background-position: 100% 0 !important;
289
+ }
290
+
291
+ ul#bbAdminMenu li.bb-menu.bb-menu-open li.bb-menu-sub a {
292
+ background-position: 100% -306px;
293
+ }
294
+
295
+
296
+
297
+ /* Dashboard */
298
+
299
+ div.dashboard div.versions p.theme a.button {
300
+ float: left;
301
+ }
302
+
303
+
304
+
305
+ /* Search forms */
306
+
307
+ form.search-form fieldset {
308
+ float: right;
309
+ }
310
+
311
+ form.search-form fieldset div {
312
+ float: right;
313
+ margin-right: 0;
314
+ margin-left: 5px;
315
+ }
316
+
317
+
318
+
319
+ /* Table nav */
320
+
321
+ div.tablenav {
322
+ float: left;
323
+ }
324
+
325
+ span.displaying-num {
326
+ text-align: left;
327
+ }
328
+
329
+ span.displaying-pages {
330
+ float: left;
331
+ }
332
+
333
+ span.displaying-pages span,
334
+ span.displaying-pages a {
335
+ float: right;
336
+ }
337
+
338
+
339
+
340
+ /* Tabled info */
341
+
342
+ table#plugins-list.widefat tr.autoload td.plugin-name {
343
+ background-position: 0 0;
344
+ padding-right: 7px;
345
+ padding-left: 20px;
346
+ }
347
+
348
+
349
+
350
+ /* Forums */
351
+
352
+ ul#forum-list li ul li {
353
+ border-left-width: 0;
354
+ border-right: 1px dashed rgb(223, 223, 223);
355
+ }
356
+
357
+ ul#forum-list li ul.list-block {
358
+ padding: 0 30px 0 0;
359
+ }
360
+
361
+ ul#forum-list li img.sort-handle {
362
+ float: right;
363
+ margin: 0 -4px 0 3px;
364
+ }
365
+
366
+ #dragHelper img.sort-handle {
367
+ float: right;
368
+ margin: 0 0 0 3px;
369
+ }
370
+
371
+ #dragHelper div.row-description {
372
+ margin: 0 4px 0 0;
373
+ }
374
+
375
+
376
+
377
+ /* Themes */
378
+
379
+ table.theme-list td {
380
+ border-left: 1px solid rgb(221, 221, 221);
381
+ border-right-width: 0;
382
+ }
383
+
384
+ table.theme-list td.position-3 {
385
+ border-left: none;
386
+ }
387
+
388
+ table.theme-list-active td div.screen-shot {
389
+ float: right;
390
+ margin-right: 0;
391
+ margin-left: 15px;
392
+ }
393
+
394
+
395
+
396
+ /* Options */
397
+
398
+ form.settings div {
399
+ margin-right: 0;
400
+ margin-left: 10px;
401
+ }
402
+
403
+ form.settings div label,
404
+ form.settings div div.label {
405
+ float: right;
406
+ }
407
+
408
+ form.settings div.disabled label,
409
+ form.settings div.disabled div.label {
410
+ background-position: 0 0;
411
+ padding-right: 0;
412
+ padding-left: 20px;
413
+ }
414
+
415
+ form.settings div div.inputs {
416
+ margin: 0 210px 0 0;
417
+ }
418
+
419
+ form.settings div.table {
420
+ margin: 0 220px 0 0;
421
+ }
422
+
423
+ form.settings div p {
424
+ margin: 0 3em 0 0;
425
+ border-left-width: 0;
426
+ border-right: 1px solid rgb(223, 223, 223);
427
+ }
428
+
429
+ form.settings a.cancel {
430
+ float: right;
431
+ margin-right: 0;
432
+ margin-left: 6px;
433
+ }
434
+
435
+
436
+
437
+ /* Footer */
438
+
439
+ p#bbShowOff {
440
+ margin-right: 0;
441
+ margin-left: 8px;
442
+ float: left;
443
+ font-family: "Times New Roman", Tahoma;
444
+ }
445
+
446
+ div#bbFoot {
447
+ font-family: "Times New Roman", Tahoma;
448
+ }
449
+
450
+ p#bbThanks {
451
+ float: right;
452
+ }
453
+
454
+ p#bbVersion {
455
+ text-align: left;
456
+ }
bp-forums/bbpress/bb-admin/style.css ADDED
@@ -0,0 +1,1854 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Start with some basic resets
3
+ */
4
+
5
+ /*
6
+ Copyright (c) 2009, Yahoo! Inc. All rights reserved.
7
+ Code licensed under the BSD License:
8
+ http://developer.yahoo.net/yui/license.txt
9
+ version: 2.7.0
10
+ */
11
+ html{color:#000;background:#FFF;}
12
+ body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}
13
+ table{border-collapse:collapse;border-spacing:0;}
14
+ fieldset,img{border:0;}
15
+ address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit;}
16
+ del,ins{text-decoration:none;}
17
+ li{list-style:none;}
18
+ caption,th{text-align:left;}
19
+ h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}
20
+ q:before,q:after{content:'';}
21
+ abbr,acronym{border:0;font-variant:normal;}
22
+ sup{vertical-align:baseline;}
23
+ sub{vertical-align:baseline;}
24
+ legend{color:#000;}
25
+ input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}
26
+ input,button,textarea,select{*font-size:100%;}
27
+ body{font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}
28
+ select,input,button,textarea,button{font:99% arial,helvetica,clean,sans-serif;}
29
+ table{font-size:inherit;font:100%;}
30
+ pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}
31
+
32
+
33
+ html {
34
+ height: 100%;
35
+ background-color: rgb(249, 249, 249);
36
+ }
37
+
38
+ body {
39
+ height: 100%;
40
+ min-width: 785px;
41
+ color: rgb(51, 51, 51);
42
+ line-height: 1.4em;
43
+ font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
44
+ font-size: 0.8em;
45
+ }
46
+
47
+ a {
48
+ outline: none;
49
+ }
50
+
51
+ div#bbWrap {
52
+ height: auto;
53
+ min-height: 100%;
54
+ width: 100%;
55
+ }
56
+
57
+ div#bbContent {
58
+ height: 100%;
59
+ padding-bottom: 45px;
60
+ }
61
+
62
+
63
+ /* Header */
64
+
65
+ div#bbHead {
66
+ position: relative;
67
+ background-color: rgb(70, 70, 70);
68
+ }
69
+
70
+ div#bbHead h1 {
71
+ padding: 10px 0 5px 39px;
72
+ margin-left: 16px;
73
+ min-height: 31px;
74
+ background: transparent url('images/admin-header-logo.gif') no-repeat 0 8px;
75
+ font: normal normal normal 22px/normal Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;
76
+ color: white;
77
+ }
78
+
79
+ div#bbHead h1 a {
80
+ text-decoration: none;
81
+ }
82
+
83
+ div#bbHead h1 a span {
84
+ color: rgb(255, 255, 255);
85
+ }
86
+
87
+ div#bbHead h1 a:hover span {
88
+ text-decoration: underline;
89
+ }
90
+
91
+ div#bbHead h1 a em {
92
+ background: rgb(88, 88, 88) url('images/visit-site-button-grad.gif') repeat-x 0 0;
93
+ color: rgb(170, 170, 170);
94
+ text-shadow: rgb(63, 63, 63) 0px -1px 0px;
95
+ -moz-border-radius: 3px;
96
+ -khtml-border-radius: 3px;
97
+ -webkit-border-radius: 3px;
98
+ border-radius: 3px;
99
+ cursor: pointer;
100
+ display: inline-block;
101
+ font-size: 0.5em;
102
+ font-style: normal;
103
+ line-height: 17px;
104
+ margin-left: 5px;
105
+ padding: 0px 6px;
106
+ vertical-align: middle;
107
+ }
108
+
109
+ div#bbHead h1 a:hover em {
110
+ color: rgb(255, 255, 255);
111
+ }
112
+
113
+ div#bbHead h1 a:active em {
114
+ background-position: 0 -27px;
115
+ }
116
+
117
+ div#bbUserInfo {
118
+ position: absolute;
119
+ top: 14px;
120
+ right: 15px;
121
+ font-size: 0.95em;
122
+ color: rgb(153, 153, 153);
123
+ }
124
+
125
+ div#bbUserInfo a {
126
+ color: rgb(204, 204, 204);
127
+ text-decoration: none;
128
+ }
129
+
130
+ div#bbUserInfo a:hover {
131
+ color: rgb(255, 255, 255);
132
+ text-decoration: underline;
133
+ }
134
+
135
+
136
+
137
+
138
+ /* Body */
139
+
140
+ div#bbBody {
141
+ margin-left: 180px;
142
+ padding-right: 15px;
143
+ }
144
+
145
+ body.bb-menu-folded div#bbBody {
146
+ margin-left: 65px;
147
+ }
148
+
149
+ h2 {
150
+ display: block;
151
+ color: rgb(70, 70, 70);
152
+ font: italic normal normal 1.9em/1.45em Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;
153
+ padding: 14px 15px 3px 0;
154
+ text-shadow: rgb(255, 255, 255) 0px 1px 0px;
155
+ background: transparent none no-repeat 0 0;
156
+ margin-left: -5px;
157
+ }
158
+
159
+ h2 span.subtitle {
160
+ font-size: 0.75em;
161
+ padding-left: 25px;
162
+ }
163
+
164
+ body.bb-admin-dashboard h2 {
165
+ padding-left: 47px;
166
+ background-image: url('images/icons32.png');
167
+ background-position: 0 -172px;
168
+ }
169
+
170
+ body.bb-admin-forums h2 {
171
+ padding-left: 47px;
172
+ background-image: url('images/icons32.png');
173
+ background-position: 0 -981px;
174
+ }
175
+
176
+ body.bb-admin-topics h2 {
177
+ padding-left: 47px;
178
+ background-image: url('images/icons32.png');
179
+ background-position: 0 -1071px;
180
+ }
181
+
182
+ body.bb-admin-posts h2 {
183
+ padding-left: 47px;
184
+ background-image: url('images/icons32.png');
185
+ background-position: 0 -1161px;
186
+ }
187
+
188
+ body.bb-admin-appearance h2 {
189
+ padding-left: 47px;
190
+ background-image: url('images/icons32.png');
191
+ background-position: 0 8px;
192
+ }
193
+
194
+ body.bb-admin-plugins h2 {
195
+ padding-left: 47px;
196
+ background-image: url('images/icons32.png');
197
+ background-position: 0 -532px;
198
+ }
199
+
200
+ body.bb-admin-users h2 {
201
+ padding-left: 47px;
202
+ background-image: url('images/icons32.png');
203
+ background-position: 0 -891px;
204
+ }
205
+
206
+ body.bb-admin-tools h2 {
207
+ padding-left: 47px;
208
+ background-image: url('images/icons32.png');
209
+ background-position: 0 -621px;
210
+ }
211
+
212
+ body.bb-admin-settings h2 {
213
+ padding-left: 47px;
214
+ background-image: url('images/icons32.png');
215
+ background-position: 0 -712px;
216
+ }
217
+
218
+
219
+
220
+
221
+
222
+ /* Menu */
223
+ ul#bbAdminMenu * {
224
+ -webkit-user-select: none;
225
+ -moz-user-select: none;
226
+ -khtml-user-select: none;
227
+ user-select: none;
228
+ }
229
+
230
+ ul#bbAdminMenu {
231
+ float: left;
232
+ margin: 15px 5px 15px -165px;
233
+ position: relative;
234
+ width: 145px;
235
+ }
236
+
237
+ body.bb-menu-folded ul#bbAdminMenu {
238
+ margin-left: -50px;
239
+ width: auto;
240
+ }
241
+
242
+ ul#bbAdminMenu li.bb-menu {
243
+
244
+ }
245
+
246
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu {
247
+ position: relative;
248
+ }
249
+
250
+ ul#bbAdminMenu li.bb-menu a {
251
+ display: block;
252
+ color: rgb(0, 102, 0);
253
+ background: rgb(241, 241, 241) url('images/menu-bits.gif') repeat-x 0 -379px;
254
+ border: 1px solid rgb(227, 227, 227);
255
+ width: 133px;
256
+ padding: 5px;
257
+ font: normal normal normal 1em/1.4em Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;
258
+ text-decoration: none;
259
+ border-bottom-width: 0;
260
+ }
261
+
262
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu a {
263
+ height: 17px;
264
+ width: 17px;
265
+ background-image: none;
266
+ }
267
+
268
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu a span {
269
+ display: none;
270
+ }
271
+
272
+ ul#bbAdminMenu li.bb-menu.bb-menu-current a {
273
+ background-position: 0 0;
274
+ border-color: rgb(109, 109, 109);
275
+ color: rgb(255, 255, 255);
276
+ text-shadow: rgba(0, 0, 0, 0.4) 0px -1px 0px;
277
+ }
278
+
279
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu.bb-menu-current a {
280
+ background-color: rgb(230, 230, 230);
281
+ background-image: none;
282
+ border-color: rgb(227, 227, 227);
283
+ }
284
+
285
+ ul#bbAdminMenu li.bb-menu.bb-menu-current a:hover {
286
+ border-color: rgb(181, 181, 181);
287
+ color: rgb(255, 255, 255);
288
+ }
289
+
290
+ ul#bbAdminMenu li.bb-menu.bb-menu-first a {
291
+ -moz-border-radius-topleft: 6px;
292
+ -moz-border-radius-topright: 6px;
293
+ -khtml-border-top-left-radius: 6px;
294
+ -khtml-border-top-right-radius: 6px;
295
+ -webkit-border-top-left-radius: 6px;
296
+ -webkit-border-top-right-radius: 6px;
297
+ border-top-left-radius: 6px;
298
+ border-top-right-radius: 6px;
299
+ }
300
+
301
+ ul#bbAdminMenu li.bb-menu.bb-menu-last a {
302
+ -moz-border-radius-bottomleft: 6px;
303
+ -moz-border-radius-bottomright: 6px;
304
+ -khtml-border-bottom-left-radius: 6px;
305
+ -khtml-border-bottom-right-radius: 6px;
306
+ -webkit-border-bottom-left-radius: 6px;
307
+ -webkit-border-bottom-right-radius: 6px;
308
+ border-bottom-left-radius: 6px;
309
+ border-bottom-right-radius: 6px;
310
+ border-bottom-width: 1px;
311
+ }
312
+
313
+ ul#bbAdminMenu li.bb-menu.bb-menu-open.bb-menu-has-submenu a,
314
+ ul#bbAdminMenu li.bb-menu.bb-menu-open a {
315
+ -moz-border-radius-bottomleft: 0;
316
+ -moz-border-radius-bottomright: 0;
317
+ -khtml-border-bottom-left-radius: 0;
318
+ -khtml-border-bottom-right-radius: 0;
319
+ -webkit-border-bottom-left-radius: 0;
320
+ -webkit-border-bottom-right-radius: 0;
321
+ border-bottom-left-radius: 0;
322
+ border-bottom-right-radius: 0;
323
+ }
324
+
325
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu.bb-menu-last a {
326
+ -moz-border-radius-bottomleft: 6px;
327
+ -moz-border-radius-bottomright: 6px;
328
+ -khtml-border-bottom-left-radius: 6px;
329
+ -khtml-border-bottom-right-radius: 6px;
330
+ -webkit-border-bottom-left-radius: 6px;
331
+ -webkit-border-bottom-right-radius: 6px;
332
+ border-bottom-left-radius: 6px;
333
+ border-bottom-right-radius: 6px;
334
+ border-bottom-width: 1px;
335
+ }
336
+
337
+ ul#bbAdminMenu li.bb-menu.bb-menu-open a {
338
+ border-bottom-width: 0;
339
+ }
340
+
341
+ ul#bbAdminMenu li.bb-menu.bb-menu-current.bb-menu-has-submenu a:hover {
342
+ border-color: rgb(109, 109, 109);
343
+ }
344
+
345
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu.bb-menu-current.bb-menu-has-submenu a:hover {
346
+ border-color: rgb(227, 227, 227);
347
+ }
348
+
349
+ ul#bbAdminMenu li.bb-menu div.bb-menu-toggle {
350
+ float: right;
351
+ height: 27px;
352
+ width: 24px;
353
+ display: none;
354
+ background-image: url('images/menu-bits.gif');
355
+ background-repeat: no-repeat;
356
+ background-position: 0 -110px;
357
+ margin-top: -27px;
358
+ }
359
+
360
+ ul#bbAdminMenu li.bb-menu.bb-menu-last div.bb-menu-toggle {
361
+ margin-top: -28px;
362
+ }
363
+
364
+ ul#bbAdminMenu li.bb-menu.bb-menu-last.bb-menu-open div.bb-menu-toggle {
365
+ margin-top: -27px;
366
+ }
367
+
368
+ ul#bbAdminMenu li.bb-menu.bb-menu-has-submenu:hover div.bb-menu-toggle,
369
+ ul#bbAdminMenu li.bb-menu.bb-menu-has-submenu.bb-menu-open div.bb-menu-toggle {
370
+ display: block;
371
+ }
372
+
373
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu.bb-menu-has-submenu:hover div.bb-menu-toggle,
374
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu.bb-menu-has-submenu.bb-menu-open div.bb-menu-toggle {
375
+ display: none;
376
+ }
377
+
378
+ ul#bbAdminMenu li.bb-menu.bb-menu-has-submenu.bb-menu-current div.bb-menu-toggle {
379
+ background-position: 0 -208px;
380
+ }
381
+
382
+ ul#bbAdminMenu li.bb-menu a:hover,
383
+ ul#bbAdminMenu li.bb-menu a:active,
384
+ ul#bbAdminMenu li.bb-menu a:focus {
385
+ color: rgb(213, 78, 33);
386
+ }
387
+
388
+ ul#bbAdminMenu li.bb-menu a div.bb-menu-icon {
389
+ height: 22px;
390
+ width: 22px;
391
+ float: left;
392
+ background: transparent url('images/menu.png') no-repeat -337px -39px;
393
+ }
394
+
395
+ ul#bbAdminMenu li.bb-menu.bb-menu-current a div.bb-menu-icon,
396
+ ul#bbAdminMenu li.bb-menu a:hover div.bb-menu-icon {
397
+ background-position: -337px -7px;
398
+ }
399
+
400
+ ul#bbAdminMenu li#bb-menu-dashboard a div.bb-menu-icon {
401
+ background-position: -67px -39px;
402
+ }
403
+
404
+ ul#bbAdminMenu li#bb-menu-dashboard.bb-menu-current a div.bb-menu-icon,
405
+ ul#bbAdminMenu li#bb-menu-dashboard a:hover div.bb-menu-icon {
406
+ background-position: -67px -7px;
407
+ }
408
+
409
+ ul#bbAdminMenu li#bb-menu-forums a div.bb-menu-icon {
410
+ background-position: -367px -39px;
411
+ }
412
+
413
+ ul#bbAdminMenu li#bb-menu-forums.bb-menu-current a div.bb-menu-icon,
414
+ ul#bbAdminMenu li#bb-menu-forums a:hover div.bb-menu-icon {
415
+ background-position: -367px -7px;
416
+ }
417
+
418
+ ul#bbAdminMenu li#bb-menu-topics a div.bb-menu-icon {
419
+ background-position: -397px -39px;
420
+ }
421
+
422
+ ul#bbAdminMenu li#bb-menu-topics.bb-menu-current a div.bb-menu-icon,
423
+ ul#bbAdminMenu li#bb-menu-topics a:hover div.bb-menu-icon {
424
+ background-position: -397px -7px;
425
+ }
426
+
427
+ ul#bbAdminMenu li#bb-menu-posts a div.bb-menu-icon {
428
+ background-position: -427px -39px;
429
+ }
430
+
431
+ ul#bbAdminMenu li#bb-menu-posts.bb-menu-current a div.bb-menu-icon,
432
+ ul#bbAdminMenu li#bb-menu-posts a:hover div.bb-menu-icon {
433
+ background-position: -427px -7px;
434
+ }
435
+
436
+ ul#bbAdminMenu li#bb-menu-appearance a div.bb-menu-icon {
437
+ background-position: -6px -39px;
438
+ }
439
+
440
+ ul#bbAdminMenu li#bb-menu-appearance.bb-menu-current a div.bb-menu-icon,
441
+ ul#bbAdminMenu li#bb-menu-appearance a:hover div.bb-menu-icon {
442
+ background-position: -6px -7px;
443
+ }
444
+
445
+ ul#bbAdminMenu li#bb-menu-plugins a div.bb-menu-icon {
446
+ background-position: -186px -39px;
447
+ }
448
+
449
+ ul#bbAdminMenu li#bb-menu-plugins.bb-menu-current a div.bb-menu-icon,
450
+ ul#bbAdminMenu li#bb-menu-plugins a:hover div.bb-menu-icon {
451
+ background-position: -186px -7px;
452
+ }
453
+
454
+ ul#bbAdminMenu li#bb-menu-users a div.bb-menu-icon {
455
+ background-position: -308px -39px;
456
+ }
457
+
458
+ ul#bbAdminMenu li#bb-menu-users.bb-menu-current a div.bb-menu-icon,
459
+ ul#bbAdminMenu li#bb-menu-users a:hover div.bb-menu-icon {
460
+ background-position: -308px -7px;
461
+ }
462
+
463
+ ul#bbAdminMenu li#bb-menu-tools a div.bb-menu-icon {
464
+ background-position: -217px -39px;
465
+ }
466
+
467
+ ul#bbAdminMenu li#bb-menu-tools.bb-menu-current a div.bb-menu-icon,
468
+ ul#bbAdminMenu li#bb-menu-tools a:hover div.bb-menu-icon {
469
+ background-position: -217px -7px;
470
+ }
471
+
472
+ ul#bbAdminMenu li#bb-menu-settings a div.bb-menu-icon {
473
+ background-position: -246px -39px;
474
+ }
475
+
476
+ ul#bbAdminMenu li#bb-menu-settings.bb-menu-current a div.bb-menu-icon,
477
+ ul#bbAdminMenu li#bb-menu-settings a:hover div.bb-menu-icon {
478
+ background-position: -246px -7px;
479
+ }
480
+
481
+ ul#bbAdminMenu li.bb-menu.bb-menu-separator {
482
+
483
+ }
484
+
485
+ ul#bbAdminMenu li.bb-menu.bb-menu-separator a {
486
+ background: transparent url('images/menu-arrows.gif') no-repeat 0 5px;
487
+ border-width: 0;
488
+ padding: 0;
489
+ height: 21px;
490
+ cursor: w-resize;
491
+ width: 145px;
492
+ }
493
+
494
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu.bb-menu-separator a {
495
+ background: transparent url('images/menu-arrows.gif') no-repeat -171px -34px;
496
+ height: 21px;
497
+ cursor: e-resize;
498
+ width: 29px;
499
+ }
500
+
501
+ ul#bbAdminMenu li.bb-menu div.bb-menu-sub-wrap {
502
+ display: none;
503
+ border: 1px solid rgb(227, 227, 227);
504
+ border-bottom-width: 0;
505
+ border-left-width: 0;
506
+ }
507
+
508
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu div.bb-menu-sub-wrap {
509
+ display: none;
510
+ position: absolute;
511
+ left: 36px;
512
+ top: 0;
513
+ width: 145px;
514
+ z-index: 1000;
515
+ }
516
+
517
+ ul#bbAdminMenu li.bb-menu.bb-menu-current div.bb-menu-sub-wrap {
518
+ border-color: rgb(170, 170, 170);
519
+ border-bottom-width: 1px;
520
+ }
521
+
522
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu div.bb-menu-sub-wrap {
523
+ border-width: 0;
524
+ border-color: rgb(227, 227, 227);
525
+ border-style: solid;
526
+ border-bottom-width: 1px;
527
+ }
528
+
529
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu.bb-menu-current div.bb-menu-sub-wrap {
530
+ border-color: rgb(170, 170, 170);
531
+ }
532
+
533
+ ul#bbAdminMenu li.bb-menu.bb-menu-open div.bb-menu-sub-wrap {
534
+ display: block;
535
+ }
536
+
537
+ ul#bbAdminMenu li.bb-menu.bb-menu-last div.bb-menu-sub-wrap {
538
+ border-bottom-width: 1px;
539
+ }
540
+
541
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu div.bb-menu-sub-wrap.bb-menu-sub-open {
542
+ display: block;
543
+ border-bottom-width: 1px;
544
+ }
545
+
546
+ ul#bbAdminMenu li.bb-menu div.bb-menu-sub-wrap span {
547
+ display: none;
548
+ font: normal normal normal 1em/1.45em Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;
549
+ background-color: rgb(241, 241, 241);
550
+ border: 1px solid rgb(227, 227, 227);
551
+ -moz-border-radius-topleft: 6px;
552
+ -moz-border-radius-topright: 6px;
553
+ -khtml-border-top-left-radius: 6px;
554
+ -khtml-border-top-right-radius: 6px;
555
+ -webkit-border-top-left-radius: 6px;
556
+ -webkit-border-top-right-radius: 6px;
557
+ border-top-left-radius: 6px;
558
+ border-top-right-radius: 6px;
559
+ padding: 5px 5px 4px 10px;
560
+ cursor: default;
561
+ }
562
+
563
+ ul#bbAdminMenu li.bb-menu.bb-menu-current div.bb-menu-sub-wrap span {
564
+ background-color: rgb(234, 234, 234);
565
+ border-color: rgb(170, 170, 170);
566
+ }
567
+
568
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu div.bb-menu-sub-wrap span {
569
+ display: block;
570
+ }
571
+
572
+ ul#bbAdminMenu li.bb-menu li.bb-menu-sub a {
573
+ width: 127px !important;
574
+ -moz-border-radius: 0 !important;
575
+ -khtml-border-radius: 0 !important;
576
+ -webkit-border-radius: 0 !important;
577
+ border-radius: 0 !important;
578
+ border-width: 0 !important;
579
+ font: normal normal normal 0.85em/1.7em 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
580
+ padding: 1px 5px 3px 12px;
581
+ color: rgb(0, 102, 0);
582
+ text-shadow: none;
583
+ background: rgb(255, 255, 255) url('images/menu-bits.gif') no-repeat 0 -306px;
584
+ }
585
+
586
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu li.bb-menu-sub a {
587
+ height: auto;
588
+ background: rgb(255, 255, 255) url('images/menu-bits.gif') no-repeat 0 -306px;
589
+ border-right-width: 1px !important;
590
+ }
591
+
592
+ ul#bbAdminMenu li.bb-menu li.bb-menu-sub a:hover {
593
+ background-color: rgb(222, 236, 225) !important;
594
+ color: rgb(51, 51, 51);
595
+ }
596
+
597
+ ul#bbAdminMenu li.bb-menu.bb-menu-current li.bb-menu-sub a {
598
+ background-image: url('images/menu-dark.gif');
599
+ background-position: 0 -20px !important;
600
+ }
601
+
602
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu.bb-menu-current li.bb-menu-sub a {
603
+ background-image: url('images/menu-dark.gif');
604
+ background-position: 0 -20px !important;
605
+ border-color: rgb(170, 170, 170) !important;
606
+ }
607
+
608
+ ul#bbAdminMenu li.bb-menu.bb-menu-current li.bb-menu-sub.bb-menu-sub-current a {
609
+ color: rgb(51, 51, 51);
610
+ font-weight: bold;
611
+ background-color: rgb(245, 245, 245) !important;
612
+ background-position: 0 0 !important;
613
+ }
614
+
615
+ body.bb-menu-folded ul#bbAdminMenu li.bb-menu.bb-menu-current li.bb-menu-sub.bb-menu-sub-current a {
616
+ background-position: 0 0 !important;
617
+ }
618
+
619
+ ul#bbAdminMenu li.bb-menu.bb-menu-open li.bb-menu-sub a {
620
+ background-position: 0 -306px;
621
+ }
622
+
623
+ div.wrap {
624
+ float: left;
625
+ width: 100%;
626
+ }
627
+
628
+ div#message {
629
+ -moz-border-radius: 3px;
630
+ -khtml-border-radius: 3px;
631
+ -webkit-border-radius: 3px;
632
+ border-radius: 3px;
633
+ border-style: solid;
634
+ border-width: 1px;
635
+ margin: 5px 0 2px 0;
636
+ padding: 0 0.65em;
637
+ font-size: 0.9em;
638
+ }
639
+
640
+ div#message.updated {
641
+ background-color: rgb(255, 251, 204);
642
+ border-color: rgb(230, 219, 85);
643
+ }
644
+
645
+ div#message.error {
646
+ background-color: rgb(255, 235, 232);
647
+ border-color: rgb(204, 0, 0);
648
+ }
649
+
650
+ div#message p {
651
+ line-height: 1;
652
+ margin: 0.6em 0;
653
+ padding: 2px;
654
+ }
655
+
656
+ div#message p strong {
657
+ font-weight: bold;
658
+ }
659
+
660
+ div#message a {
661
+ color: rgb(0, 102, 0);
662
+ text-decoration: none;
663
+ }
664
+
665
+ div#message a:hover {
666
+ color: rgb(213, 78, 33);
667
+ }
668
+
669
+ div.plugin-error {
670
+ background-color: rgb(255, 235, 232);
671
+ border-color: rgb(204, 0, 0);
672
+ -moz-border-radius: 3px;
673
+ -khtml-border-radius: 3px;
674
+ -webkit-border-radius: 3px;
675
+ border-radius: 3px;
676
+ border-style: solid;
677
+ border-width: 1px;
678
+ margin: 5px 0 2px 0;
679
+ padding: 0;
680
+ height: 160px;
681
+ }
682
+
683
+ div.plugin-error iframe {
684
+ -moz-border-radius: 3px;
685
+ -khtml-border-radius: 3px;
686
+ -webkit-border-radius: 3px;
687
+ border-radius: 3px;
688
+ display: block;
689
+ width: 100%;
690
+ height: 100%;
691
+ margin: 0;
692
+ padding: 0;
693
+ border-width: 0;
694
+ }
695
+
696
+
697
+ /* Dashboard */
698
+
699
+ div.dashboard {
700
+ background-color: rgb(255, 255, 255);
701
+ border: 1px solid rgb(223, 223, 223);
702
+ -moz-border-radius: 6px;
703
+ -khtml-border-radius: 6px;
704
+ -webkit-border-radius: 6px;
705
+ border-radius: 6px;
706
+ margin: 10px 5px 20px 5px;
707
+ }
708
+
709
+ div.dashboard a {
710
+ color: rgb(0, 102, 0);
711
+ }
712
+
713
+ div.dashboard a:hover {
714
+ color: rgb(213, 78, 33);
715
+ }
716
+
717
+ div.dashboard h3 {
718
+ -moz-border-radius-topleft: 6px;
719
+ -moz-border-radius-topright: 6px;
720
+ -khtml-border-top-left-radius: 6px;
721
+ -khtml-border-top-right-radius: 6px;
722
+ -webkit-border-top-left-radius: 6px;
723
+ -webkit-border-top-right-radius: 6px;
724
+ border-top-left-radius: 6px;
725
+ border-top-right-radius: 6px;
726
+ background: url('images/gray-grad.png') repeat-x rgb(223, 223, 223);
727
+ text-shadow: rgb(255, 255, 255) 0px 1px 0px;
728
+ color: rgb(70, 70, 70);
729
+ font-size: 0.9em;
730
+ font-weight: bold;
731
+ line-height: 1;
732
+ margin: 0px;
733
+ padding: 7px 9px;
734
+ }
735
+
736
+ div.dashboard div.table {
737
+ border-bottom: 1px solid rgb(236, 236, 236);
738
+ background: rgb(249, 249, 249);
739
+ }
740
+
741
+ div.dashboard div.table table {
742
+ width: 100%;
743
+ }
744
+
745
+ div.dashboard div.table thead th {
746
+ color: rgb(119, 119, 119);
747
+ font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;
748
+ font-size: 1em;
749
+ font-style: italic;
750
+ padding: 3px 8px 4px;
751
+ background: rgb(255, 255, 255);
752
+ width: 50%;
753
+ }
754
+
755
+ div.dashboard div.table tbody td {
756
+ border-top: 1px solid rgb(236, 236, 236);
757
+ padding: 4px 16px;
758
+ white-space: nowrap;
759
+ font-size: 0.9em;
760
+ color: rgb(70, 70, 70);
761
+ }
762
+
763
+ div.dashboard div.table tbody td span {
764
+ font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;
765
+ font-size: 1.6em;
766
+ padding-right: 6px;
767
+ }
768
+
769
+ div.dashboard p {
770
+ color: rgb(51, 51, 51);
771
+ font-size: 0.85em;
772
+ margin: 8px;
773
+ }
774
+
775
+ div.dashboard div.versions p span.b {
776
+ font-weight: bold;
777
+ }
778
+
779
+ div.dashboard div.versions p a {
780
+ text-decoration: none;
781
+ font-weight: bold;
782
+ }
783
+
784
+ div.dashboard div.versions p.theme a.button {
785
+ display: block;
786
+ float: right;
787
+ font-weight: normal;
788
+ -moz-border-radius: 10px;
789
+ -khtml-border-radius: 10px;
790
+ -webkit-border-radius: 10px;
791
+ border-radius: 10px;
792
+ padding: 4px 10px;
793
+ background: url('images/white-grad.png') repeat-x scroll rgb(242, 242, 242);
794
+ border: 1px solid rgb(187, 187, 187);
795
+ color: rgb(70, 70, 70);
796
+ cursor: pointer;
797
+ font-size: 1em;
798
+ line-height: 1.2em;
799
+ }
800
+
801
+ div.dashboard div.versions p.theme a.button:hover {
802
+ border-color: rgb(102, 102, 102);
803
+ color: rgb(0, 0, 0);
804
+ }
805
+
806
+ div.dashboard div.versions p.theme a.button:active {
807
+ background: url('images/white-grad-active.png') repeat-x scroll rgb(238, 238, 238);
808
+ }
809
+
810
+ div.dashboard ul li {
811
+ color: rgb(51, 51, 51);
812
+ font-size: 0.85em;
813
+ margin: 8px;
814
+ }
815
+
816
+ div.dashboard ul li a {
817
+ text-decoration: none;
818
+ font-weight: bold;
819
+ }
820
+
821
+
822
+
823
+ /* Search forms */
824
+
825
+ form.search-form fieldset {
826
+ margin: 10px 0 0 0;
827
+ float: left;
828
+ }
829
+
830
+ form.search-form fieldset div {
831
+ float: left;
832
+ margin-right: 5px;
833
+ margin-top: 3px;
834
+ }
835
+
836
+ form.search-form fieldset div div {
837
+ float: none;
838
+ margin: 0;
839
+ }
840
+
841
+ form.search-form fieldset div label {
842
+ display: block;
843
+ line-height: 1;
844
+ padding: 0 0 3px 0;
845
+ font-size: 0.8em;
846
+ color: rgb(70, 70, 70);
847
+ }
848
+
849
+ form.search-form fieldset div div input.text-input {
850
+ width: 100px;
851
+ padding: 3px;
852
+ -moz-border-radius: 4px;
853
+ -khtml-border-radius: 4px;
854
+ -webkit-border-radius: 4px;
855
+ border-radius: 4px;
856
+ border: 1px solid rgb(223, 223, 223);
857
+ font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
858
+ font-size: 0.85em;
859
+ line-height: 1.3em;
860
+ }
861
+
862
+ form.search-form fieldset div div input.checkbox-input {
863
+ margin: 4px;
864
+ }
865
+
866
+ form.search-form fieldset div div select {
867
+ height: 2.1em;
868
+ margin: 0;
869
+ padding: 3px;
870
+ -moz-border-radius: 4px;
871
+ -khtml-border-radius: 4px;
872
+ -webkit-border-radius: 4px;
873
+ border-radius: 4px;
874
+ border: 1px solid rgb(223, 223, 223);
875
+ font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
876
+ font-size: 0.85em;
877
+ }
878
+
879
+ form.search-form fieldset div div option {
880
+ padding: 3px;
881
+ font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
882
+ font-size: 0.9em;
883
+ }
884
+
885
+ form.search-form div.submit label {
886
+ width: 0;
887
+ overflow: hidden;
888
+ }
889
+
890
+ form.search-form div.submit input.button {
891
+ font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
892
+ -moz-border-radius: 10px;
893
+ -khtml-border-radius: 10px;
894
+ -webkit-border-radius: 10px;
895
+ border-radius: 10px;
896
+ padding: 4px 9px 5px;
897
+ background: url('images/white-grad.png') repeat-x scroll rgb(242, 242, 242);
898
+ border: 1px solid rgb(187, 187, 187);
899
+ color: rgb(70, 70, 70);
900
+ cursor: pointer;
901
+ line-height: 1.1em;
902
+ font-size: 0.85em;
903
+ }
904
+
905
+ form.search-form div.submit input.button:hover {
906
+ border-color: rgb(102, 102, 102);
907
+ color: rgb(0, 0, 0);
908
+ }
909
+
910
+ form.search-form div.submit input.button:active {
911
+ background: url('images/white-grad-active.png') repeat-x scroll rgb(238, 238, 238);
912
+ }
913
+
914
+
915
+
916
+ /* Table nav */
917
+
918
+ div.tablenav {
919
+ float: right;
920
+ }
921
+
922
+ div.tablenav a {
923
+ color: rgb(0, 102, 0);
924
+ }
925
+
926
+ div.tablenav a:hover {
927
+ color: rgb(213, 78, 33);
928
+ }
929
+
930
+ div.tablenav-pages {
931
+ margin: 13px 0 0 0;
932
+ }
933
+
934
+ div.tablenav.bottom div.tablenav-pages {
935
+ margin: 0 0 16px 0;
936
+ }
937
+
938
+ span.displaying-num {
939
+ display: block;
940
+ text-align: right;
941
+ line-height: 1;
942
+ font-size: 0.8em;
943
+ color: rgb(70, 70, 70);
944
+ padding: 0 0 3px 0;
945
+ }
946
+
947
+ span.displaying-pages {
948
+ display: block;
949
+ float: right;
950
+ cursor: default;
951
+ color: rgb(85, 85, 85);
952
+ }
953
+
954
+ span.displaying-pages span,
955
+ span.displaying-pages a {
956
+ display: block;
957
+ float: left;
958
+ -moz-border-radius: 5px;
959
+ -khtml-border-radius: 5px;
960
+ -webkit-border-radius: 5px;
961
+ border-radius: 5px;
962
+ border: 1px solid rgb(211, 211, 211);
963
+ padding: 3px 7px;
964
+ text-decoration: none;
965
+ background-color: rgb(223, 223, 223);
966
+ font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
967
+ font-size: 0.85em;
968
+ line-height: 1.3em;
969
+ margin-left: 3px;
970
+ }
971
+
972
+ span.displaying-pages span.dots {
973
+ border-width: 0;
974
+ background-color: transparent;
975
+ padding: 4px 0 0 0;
976
+ font-weight: bold;
977
+ }
978
+
979
+ span.displaying-pages a {
980
+ font-weight: bold;
981
+ background: url('images/menu-bits.gif') repeat-x 0 -379px rgb(238, 238, 238);
982
+ border-color: rgb(227, 227, 227);
983
+ }
984
+
985
+ span.displaying-pages a:hover {
986
+ border-color: rgb(213, 78, 33);
987
+ }
988
+
989
+ span.displaying-pages a:active {
990
+ color: rgb(255, 255, 255);
991
+ }
992
+
993
+ div.table-filter {
994
+ color: rgb(102, 102, 102);
995
+ margin: 8px 0px 5px;
996
+ font-size: 0.85em;
997
+ }
998
+
999
+ div.table-filter a {
1000
+ color: rgb(0, 102, 0);
1001
+ text-decoration: none;
1002
+ }
1003
+
1004
+ div.table-filter a.current {
1005
+ color: rgb(0, 0, 0);
1006
+ font-weight: bold;
1007
+ }
1008
+
1009
+ div.table-filter a:hover {
1010
+ color: rgb(213, 78, 33);
1011
+ }
1012
+
1013
+ div.table-filter a span.count {
1014
+ color: rgb(153, 153, 153);
1015
+ font-weight: normal;
1016
+ }
1017
+
1018
+
1019
+
1020
+
1021
+ /* Tabled info */
1022
+
1023
+ p.no-results {
1024
+ margin: 10px 0;
1025
+ font-size: 0.85em;
1026
+ }
1027
+
1028
+ table.widefat {
1029
+ width: 100%;
1030
+ border: 1px solid rgb(223, 223, 223);
1031
+ -moz-border-radius: 4px;
1032
+ -khtml-border-radius: 4px;
1033
+ -webkit-border-radius: 4px;
1034
+ border-radius: 4px;
1035
+ border-collapse: separate;
1036
+ margin: 10px 0;
1037
+ }
1038
+
1039
+ table.widefat a {
1040
+ color: rgb(0, 102, 0);
1041
+ text-decoration: none;
1042
+ }
1043
+
1044
+ table.widefat a:hover {
1045
+ color: rgb(213, 78, 33);
1046
+ }
1047
+
1048
+ table.widefat tr td {
1049
+ width: 18%;
1050
+ vertical-align: top;
1051
+ padding: 3px 7px;
1052
+ font-size: 0.85em;
1053
+ border-bottom: 1px solid rgb(223, 223, 223);
1054
+ }
1055
+
1056
+ table.widefat tr.alt td {
1057
+ background-color: rgb(255, 255, 255);
1058
+ }
1059
+
1060
+ table.widefat tr.deleted td {
1061
+ background-color: rgb(245, 224, 224);
1062
+ }
1063
+
1064
+ table.widefat tr.deleted.alt td {
1065
+ background-color: rgb(248, 233, 233);
1066
+ }
1067
+
1068
+ table.widefat tr.spam td {
1069
+ background-color: rgb(238, 218, 204);
1070
+ }
1071
+
1072
+ table.widefat tr.spam.alt td {
1073
+ background-color: rgb(243, 228, 218);
1074
+ }
1075
+
1076
+ table#plugins-list.widefat tr.inactive td {
1077
+ background-color: rgb(238, 238, 238);
1078
+ }
1079
+
1080
+ table#plugins-list.widefat tr.active td {
1081
+ background-color: rgb(255, 255, 255);
1082
+ }
1083
+
1084
+ table#plugins-list.widefat tr.autoload td {
1085
+ background-color: rgb(249, 249, 249);
1086
+ }
1087
+
1088
+ table#plugins-list.widefat tr.autoload td.plugin-name {
1089
+ background-image: url('images/input-lock.png');
1090
+ background-repeat: no-repeat;
1091
+ background-position: 100% 0;
1092
+ padding-right: 20px;
1093
+ }
1094
+
1095
+ table.widefat tr th {
1096
+ background: url('images/gray-grad.png') repeat-x rgb(223, 223, 223);
1097
+ text-shadow: rgb(255, 255, 255) 0px 1px 0px;
1098
+ color: rgb(51, 51, 51);
1099
+ font-weight: bold;
1100
+ vertical-align: top;
1101
+ padding: 7px 7px 8px;
1102
+ font-size: 0.85em;
1103
+ line-height: 1.3em;
1104
+ border-bottom: 1px solid rgb(223, 223, 223);
1105
+ }
1106
+
1107
+ table.widefat tfoot tr th {
1108
+ border-bottom-width: 0;
1109
+ }
1110
+
1111
+ table#posts-list.widefat tr td.post {
1112
+ width: 46%;
1113
+ font-size: 0.9em;
1114
+ }
1115
+
1116
+ table#topics-list.widefat tr td.topic {
1117
+ width: 28%;
1118
+ font-size: 0.9em;
1119
+ }
1120
+
1121
+ table#plugins-list.widefat tr td.plugin-name {
1122
+ width: 25%;
1123
+ font-size: 0.9em;
1124
+ }
1125
+
1126
+ table#plugins-list.widefat tr td.plugin-description {
1127
+ width: 75%;
1128
+ }
1129
+
1130
+ table.widefat tr td.author img.avatar {
1131
+ vertical-align: top;
1132
+ border: 1px solid rgb(223, 223, 223);
1133
+ }
1134
+
1135
+ table.widefat tr td.post p {
1136
+ margin-bottom: 0.4em;
1137
+ }
1138
+
1139
+ table.widefat tr td.plugin-description p {
1140
+ margin-bottom: 0.8em;
1141
+ }
1142
+
1143
+ table.widefat tr td.plugin-description p.meta {
1144
+ margin-bottom: 0;
1145
+ }
1146
+
1147
+ table.widefat tr td.topic span.row-title,
1148
+ table.widefat tr td.user span.row-title {
1149
+ margin-bottom: 0.4em;
1150
+ display: block;
1151
+ font-weight: bold;
1152
+ }
1153
+
1154
+ table.widefat tr td.user img.avatar {
1155
+ display: block;
1156
+ float: left;
1157
+ margin: 3px 8px 3px -1px;
1158
+ border: 1px solid rgb(223, 223, 223);
1159
+ }
1160
+
1161
+ table.widefat tr td.plugin-name span.row-title {
1162
+ margin-bottom: 0.8em;
1163
+ display: block;
1164
+ font-weight: bold;
1165
+ }
1166
+
1167
+ table.widefat tr td.post div,
1168
+ table.widefat tr td.topic div,
1169
+ table.widefat tr td.plugin-name div {
1170
+ font-size: 0.85em;
1171
+ }
1172
+
1173
+ table.widefat tr span.row-actions {
1174
+ display: none;
1175
+ }
1176
+
1177
+ table#plugins-list.widefat tr span.row-actions {
1178
+ display: inline;
1179
+ }
1180
+
1181
+ table.widefat tr:hover span.row-actions {
1182
+ display: inline;
1183
+ }
1184
+
1185
+ table.widefat tr span.row-actions span.note {
1186
+ color: rgb(102, 102, 102);
1187
+ }
1188
+
1189
+ table.widefat tr a.post-undelete-link {
1190
+ display: none;
1191
+ }
1192
+
1193
+ table.widefat tr.deleted a.post-undelete-link {
1194
+ display: inline;
1195
+ }
1196
+
1197
+ table.widefat tr.deleted a.post-delete-link {
1198
+ display: none;
1199
+ }
1200
+
1201
+ table.widefat tr td em {
1202
+ font-style: italic;
1203
+ }
1204
+
1205
+ table.widefat tr td strong {
1206
+ font-weight: bold;
1207
+ }
1208
+
1209
+ table.widefat tr td code,
1210
+ table.widefat tr td kbd {
1211
+ font-family: Consolas, Monaco, Courier, monospace;
1212
+ font-size: 1.2em;
1213
+ background: rgb(234, 234, 234);
1214
+ margin: 0px 1px;
1215
+ padding: 1px 3px;
1216
+ color: rgb(51, 51, 51);
1217
+ }
1218
+
1219
+
1220
+
1221
+ /* Forums */
1222
+
1223
+ body.sorting {
1224
+ overflow-x: hidden;
1225
+ }
1226
+
1227
+ ul#forum-list {
1228
+ xwidth: 100%;
1229
+ border: 1px solid rgb(223, 223, 223);
1230
+ -moz-border-radius: 4px;
1231
+ -khtml-border-radius: 4px;
1232
+ -webkit-border-radius: 4px;
1233
+ border-radius: 4px;
1234
+ margin: 10px 0;
1235
+ }
1236
+
1237
+ ul#forum-list a {
1238
+ color: rgb(0, 102, 0);
1239
+ text-decoration: none;
1240
+ }
1241
+
1242
+ ul#forum-list a:hover {
1243
+ color: rgb(213, 78, 33);
1244
+ }
1245
+
1246
+ ul#forum-list li {
1247
+ border-top: 1px solid rgb(223, 223, 223);
1248
+ background-color: rgb(249, 249, 249);
1249
+ }
1250
+
1251
+ ul#forum-list li.alt {
1252
+ background-color: rgb(255, 255, 255);
1253
+ }
1254
+
1255
+ ul#forum-list li ul li {
1256
+ border-left: 1px dashed rgb(223, 223, 223);
1257
+ }
1258
+
1259
+ ul#forum-list li ul.list-block {
1260
+ padding: 0 0 0 30px;
1261
+ }
1262
+
1263
+ ul#forum-list li.list-block {
1264
+ padding: 3px 0 0 0;
1265
+ }
1266
+
1267
+ ul#forum-list li div.list-block {
1268
+ padding: 0 7px 3px 7px;
1269
+ }
1270
+
1271
+ ul#forum-list li.thead {
1272
+ background: url('images/gray-grad.png') repeat-x rgb(223, 223, 223);
1273
+ text-shadow: rgb(255, 255, 255) 0px 1px 0px;
1274
+ color: rgb(51, 51, 51);
1275
+ font-weight: bold;
1276
+ vertical-align: top;
1277
+ padding: 7px 7px 8px;
1278
+ font-size: 0.85em;
1279
+ line-height: 1.3em;
1280
+ border-top-width: 0;
1281
+ }
1282
+
1283
+ ul#forum-list li img.sort-handle {
1284
+ float: left;
1285
+ margin: 0 3px 0 -4px;
1286
+ cursor: move;
1287
+ }
1288
+
1289
+ ul#forum-list li div.row-title {
1290
+ font-size: 0.9em;
1291
+ font-weight: bold;
1292
+ }
1293
+
1294
+ ul#forum-list li p.row-description {
1295
+ font-size: 0.85em;
1296
+ }
1297
+
1298
+ ul#forum-list li div.list-block div.row-actions {
1299
+ font-size: 0.8em;
1300
+ margin-top: 0.4em;
1301
+ }
1302
+
1303
+ ul#forum-list li div.list-block div.row-actions span {
1304
+ display: none;
1305
+ }
1306
+
1307
+ ul#forum-list li div.list-block:hover div.row-actions span {
1308
+ display: inline;
1309
+ }
1310
+
1311
+ ul#forum-list.sorting li div.list-block div.row-actions span {
1312
+ display: none;
1313
+ }
1314
+
1315
+ ul#forum-list.sorting li div.list-block div.row-actions span {
1316
+ display: none;
1317
+ }
1318
+
1319
+ .helper {
1320
+ background-color: rgb(200, 250, 200);
1321
+ outline: 1px dashed #777;
1322
+ width: 100% !important;
1323
+ padding: 3px 0;
1324
+ }
1325
+
1326
+ #dragHelper {
1327
+ xwidth: auto !important;
1328
+ padding: 3px;
1329
+ }
1330
+
1331
+ #dragHelper img.sort-handle {
1332
+ float: left;
1333
+ margin: 0 3px 0 0;
1334
+ }
1335
+
1336
+ #dragHelper div.row-description {
1337
+ margin: 0 0 0 4px;
1338
+ }
1339
+
1340
+ #dragHelper div.row-actions span {
1341
+ display: none;
1342
+ }
1343
+
1344
+
1345
+
1346
+ /* Themes */
1347
+
1348
+ h3.themes {
1349
+ display: block;
1350
+ color: rgb(51, 51, 51);
1351
+ font-size: 1.17em;
1352
+ font-weight: bold;
1353
+ padding: 0 0 1em 0;
1354
+ margin-top: 10px;
1355
+ }
1356
+
1357
+ table.theme-list-active,
1358
+ table.theme-list {
1359
+ margin: 0 auto 40px;
1360
+ width: 100%;
1361
+ border-collapse: collapse;
1362
+ }
1363
+
1364
+ table.theme-list {
1365
+ margin-bottom: 20px;
1366
+ width: 100%;
1367
+ border-top: 1px solid rgb(221, 221, 221);
1368
+ border-bottom: 1px solid rgb(221, 221, 221);
1369
+ border-collapse: collapse;
1370
+ }
1371
+
1372
+ table.theme-list td {
1373
+ width: 240px;
1374
+ padding: 20px;
1375
+ border-bottom: 1px solid rgb(221, 221, 221);
1376
+ border-right: 1px solid rgb(221, 221, 221);
1377
+ vertical-align: top;
1378
+ }
1379
+
1380
+ table.theme-list td.position-3 {
1381
+ border-right: none;
1382
+ }
1383
+
1384
+ table.theme-list td h3.themes,
1385
+ table.theme-list-active td h3.themes {
1386
+ margin-top: 0;
1387
+ font-size: 1em;
1388
+ }
1389
+
1390
+ table.theme-list td div.screen-shot {
1391
+ border: 1px solid rgb(204, 204, 204);
1392
+ width: 240px;
1393
+ height: 180px;
1394
+ margin-bottom: 10px;
1395
+ -moz-border-radius: 4px;
1396
+ -khtml-border-radius: 4px;
1397
+ -webkit-border-radius: 4px;
1398
+ border-radius: 4px;
1399
+ }
1400
+
1401
+ table.theme-list td div.screen-shot img {
1402
+ width: 240px;
1403
+ height: 180px;
1404
+ -moz-border-radius: 4px;
1405
+ -khtml-border-radius: 4px;
1406
+ -webkit-border-radius: 4px;
1407
+ border-radius: 4px;
1408
+ }
1409
+
1410
+ table.theme-list-active td div.screen-shot {
1411
+ border: 1px solid rgb(153, 153, 153);
1412
+ width: 150px;
1413
+ height: 112px;
1414
+ float: left;
1415
+ margin-right: 15px;
1416
+ -moz-border-radius: 4px;
1417
+ -khtml-border-radius: 4px;
1418
+ -webkit-border-radius: 4px;
1419
+ border-radius: 4px;
1420
+ }
1421
+
1422
+ table.theme-list-active td div.screen-shot img {
1423
+ width: 150px;
1424
+ height: 112px;
1425
+ -moz-border-radius: 4px;
1426
+ -khtml-border-radius: 4px;
1427
+ -webkit-border-radius: 4px;
1428
+ border-radius: 4px;
1429
+ }
1430
+
1431
+ table.theme-list td div.description p,
1432
+ table.theme-list-active td div.description p {
1433
+ color: rgb(102, 102, 102);
1434
+ font-style: italic;
1435
+ margin: 0 0 1em 0;
1436
+ font-size: 0.9em;
1437
+ }
1438
+
1439
+ table.theme-list td div.description div.actions {
1440
+ margin: 0 0 1em 0;
1441
+ font-size: 1em;
1442
+ }
1443
+
1444
+ table.theme-list td div.description p.location,
1445
+ table.theme-list-active td div.description p.location {
1446
+ color: inherit;
1447
+ font-style: normal;
1448
+ margin: 0 0 0 0;
1449
+ }
1450
+
1451
+ table.theme-list td a,
1452
+ table.theme-list-active td a {
1453
+ color: rgb(0, 102, 0);
1454
+ }
1455
+
1456
+ table.theme-list td a:hover,
1457
+ table.theme-list-active td a:hover {
1458
+ color: rgb(213, 78, 33);
1459
+ }
1460
+
1461
+
1462
+
1463
+ /* Options */
1464
+
1465
+ form.settings fieldset {
1466
+ margin-top: 10px;
1467
+ margin-bottom: 20px;
1468
+ }
1469
+
1470
+ form.settings legend,
1471
+ div.settings h3 {
1472
+ display: block;
1473
+ color: rgb(51, 51, 51);
1474
+ font-size: 1.17em;
1475
+ font-weight: bold;
1476
+ padding: 0 0 1em 0;
1477
+ }
1478
+
1479
+ div.settings {
1480
+ margin-bottom: 20px;
1481
+ }
1482
+
1483
+ hr.settings {
1484
+ height: 1px;
1485
+ background-color: rgb(221, 221, 221);
1486
+ border-width: 0;
1487
+ margin-bottom: 20px;
1488
+ }
1489
+
1490
+ form.settings p,
1491
+ div.settings p {
1492
+ float: none;
1493
+ display: block;
1494
+ color: rgb(51, 51, 51);
1495
+ font-size: 0.9em;
1496
+ margin: 0 0 1em 0;
1497
+ }
1498
+
1499
+ form.settings ul,
1500
+ div.settings ul {
1501
+ float: none;
1502
+ display: block;
1503
+ color: rgb(51, 51, 51);
1504
+ font-size: 0.9em;
1505
+ margin: 0 4em 1em 4em;
1506
+ }
1507
+
1508
+ form.settings ul li,
1509
+ div.settings ul li {
1510
+ list-style: disc outside none;
1511
+ }
1512
+
1513
+ form.settings strong,
1514
+ div.settings strong {
1515
+ font-weight: bold;
1516
+ }
1517
+
1518
+ form.settings em,
1519
+ div.settings em {
1520
+ font-style: italic;
1521
+ }
1522
+
1523
+ form.settings code,
1524
+ form.settings kbd {
1525
+ font-family: Consolas, Monaco, Courier, monospace;
1526
+ font-size: 1.2em;
1527
+ background: rgb(234, 234, 234);
1528
+ margin: 0px 1px;
1529
+ padding: 1px 3px;
1530
+ color: rgb(51, 51, 51);
1531
+ }
1532
+
1533
+ form.settings a {
1534
+ color: rgb(0, 102, 0);
1535
+ }
1536
+
1537
+ form.settings a:hover {
1538
+ color: rgb(213, 78, 33);
1539
+ }
1540
+
1541
+ form.settings div {
1542
+ clear: both;
1543
+ padding: 10px;
1544
+ margin-right: 10px;
1545
+ }
1546
+
1547
+ form.settings div label {
1548
+ float: left;
1549
+ display: block;
1550
+ padding: 3px;
1551
+ width: 200px;
1552
+ color: rgb(34, 34, 34);
1553
+ text-shadow: rgb(255, 255, 255) 0px 1px 0px;
1554
+ }
1555
+
1556
+ form.settings div div.label {
1557
+ float: left;
1558
+ display: block;
1559
+ padding: 3px;
1560
+ width: 190px;
1561
+ color: rgb(34, 34, 34);
1562
+ text-shadow: rgb(255, 255, 255) 0px 1px 0px;
1563
+ }
1564
+
1565
+ form.settings div.disabled label,
1566
+ form.settings div.disabled div.label {
1567
+ background-image: url('images/input-lock.png');
1568
+ background-repeat: no-repeat;
1569
+ background-position: 100% 0;
1570
+ padding-right: 20px;
1571
+ width: 180px;
1572
+ }
1573
+
1574
+ form.settings div.disabled div.label {
1575
+ width: 170px;
1576
+ }
1577
+
1578
+ form.settings div div.inputs {
1579
+ clear: none;
1580
+ padding: 0;
1581
+ margin: 0 0 0 210px;
1582
+ }
1583
+
1584
+ form.settings div div.inputs label {
1585
+ float: none;
1586
+ clear: none;
1587
+ display: block;
1588
+ padding: 0;
1589
+ margin: 3px 0 6px 0;
1590
+ width: auto;
1591
+ color: rgb(51, 51, 51);
1592
+ text-shadow: none;
1593
+ font-size: 0.85em;
1594
+ }
1595
+
1596
+ form.settings div.disabled div.inputs label {
1597
+ background-image: none;
1598
+ }
1599
+
1600
+ form.settings div div.inputs label.radios img {
1601
+ margin: -2px 0 0 0;
1602
+ vertical-align: middle;
1603
+ border: 1px solid rgb(223, 223, 223);
1604
+ }
1605
+
1606
+ form.settings input.text,
1607
+ form.settings textarea {
1608
+ width: 300px;
1609
+ padding: 3px;
1610
+ -moz-border-radius: 4px;
1611
+ -khtml-border-radius: 4px;
1612
+ -webkit-border-radius: 4px;
1613
+ border-radius: 4px;
1614
+ border: 1px solid rgb(223, 223, 223);
1615
+ font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
1616
+ font-size: 1em;
1617
+ }
1618
+
1619
+ form.settings div.disabled input.text,
1620
+ form.settings div.disabled textarea {
1621
+ background-color: rgb(221, 221, 221);
1622
+ }
1623
+
1624
+ form.settings div input.text.short {
1625
+ width: 100px;
1626
+ }
1627
+
1628
+ form.settings div input.text.code {
1629
+ font-family: Consolas, Monaco, Courier, monospace;
1630
+ font-size: 1.2em;
1631
+ }
1632
+
1633
+ form.settings input.readonly,
1634
+ form.settings textarea.readonly {
1635
+ background-color: rgb(221, 221, 221);
1636
+ }
1637
+
1638
+ form.settings div.table {
1639
+ margin: 0 0 0 220px;
1640
+ padding: 3px;
1641
+ -moz-border-radius: 4px;
1642
+ -khtml-border-radius: 4px;
1643
+ -webkit-border-radius: 4px;
1644
+ border-radius: 4px;
1645
+ border: 1px solid rgb(223, 223, 223);
1646
+ background-color: rgb(221, 221, 221);
1647
+ width: 300px;
1648
+ }
1649
+
1650
+ form.settings div.table table {
1651
+ width: 100%;
1652
+ font-family: Consolas, Monaco, Courier, monospace;
1653
+ font-size: 1.2em;
1654
+ border-collapse: collapse;
1655
+ }
1656
+
1657
+ form.settings div.table table th {
1658
+ border-bottom: 1px dotted rgb(70, 70, 70);
1659
+ padding: 6px;
1660
+ }
1661
+
1662
+ form.settings div.table table td {
1663
+ padding: 6px;
1664
+ }
1665
+
1666
+ form.settings div span.after {
1667
+ font-size: 0.85em;
1668
+ }
1669
+
1670
+ form.settings div p {
1671
+ color: rgb(102, 102, 102);
1672
+ font-style: italic;
1673
+ margin: 0 0 0 3em;
1674
+ padding: 0.3em;
1675
+ border-left: 1px solid rgb(223, 223, 223);
1676
+ }
1677
+
1678
+ form.settings input.submit {
1679
+ font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
1680
+ -moz-border-radius: 11px;
1681
+ -khtml-border-radius: 11px;
1682
+ -webkit-border-radius: 11px;
1683
+ border-radius: 11px;
1684
+ border: 1px solid rgb(63, 163, 50);
1685
+ cursor: pointer;
1686
+ font-size: 11px;
1687
+ line-height: 16px;
1688
+ padding: 2px 8px;
1689
+ background: url('images/button-grad.png') 0 0 rgb(33, 117, 155);
1690
+ color: rgb(255, 255, 255);
1691
+ font-weight: bold;
1692
+ text-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0;
1693
+ }
1694
+
1695
+ form.settings input.submit:hover {
1696
+ border-color: rgb(0, 102, 0);
1697
+ }
1698
+
1699
+ form.settings input.submit:active {
1700
+ background-position: 0 30px;
1701
+ }
1702
+
1703
+ form.settings a.cancel {
1704
+ display: block;
1705
+ float: left;
1706
+ font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
1707
+ -moz-border-radius: 11px;
1708
+ -khtml-border-radius: 11px;
1709
+ -webkit-border-radius: 11px;
1710
+ border-radius: 11px;
1711
+ border: 1px solid rgb(187, 187, 187);
1712
+ cursor: pointer;
1713
+ font-size: 11px;
1714
+ line-height: 16px;
1715
+ padding: 2px 8px;
1716
+ background: url('images/white-grad.png') repeat-x scroll rgb(242, 242, 242);
1717
+ color: rgb(70, 70, 70);
1718
+ cursor: pointer;
1719
+ font-weight: bold;
1720
+ text-shadow: rgba(255, 255, 255, 0.7) 0 -1px 0;
1721
+ margin-right: 6px;
1722
+ text-decoration: none;
1723
+ }
1724
+
1725
+ form.settings a.cancel:hover {
1726
+ border-color: rgb(153, 51, 51);
1727
+ color: rgb(204, 51, 51);
1728
+ }
1729
+
1730
+ form.settings a.cancel:active {
1731
+ background: url('images/white-grad-active.png') repeat-x scroll rgb(238, 238, 238);
1732
+ }
1733
+
1734
+ form.settings div#option-mod-rewrite div.inputs label.radios span {
1735
+ display: inline-block;
1736
+ width: 7em;
1737
+ }
1738
+
1739
+ form.settings div#option-mod-rewrite div.inputs label.radios code {
1740
+ white-space: nowrap;
1741
+ }
1742
+
1743
+ form.settings textarea#rewrite-rules {
1744
+ width: 99%;
1745
+ }
1746
+
1747
+
1748
+ /* Footer */
1749
+
1750
+ p#bbShowOff {
1751
+ margin: 0 8px 8px 0;
1752
+ padding: 6px 8px;
1753
+ color: rgb(255, 255, 255);
1754
+ background-color: rgb(170, 170, 170);
1755
+ font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;
1756
+ font-size: 0.9em;
1757
+ font-style: italic;
1758
+ -moz-border-radius: 6px;
1759
+ -khtml-border-radius: 6px;
1760
+ -webkit-border-radius: 6px;
1761
+ border-radius: 6px;
1762
+ float: right;
1763
+ }
1764
+
1765
+ div#bbFoot {
1766
+ background-color: rgb(70, 70, 70);
1767
+ color: rgb(153, 153, 153);
1768
+ margin-top: -45px;
1769
+ clear: both;
1770
+ position: relative;
1771
+ width: 100%;
1772
+ font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;
1773
+ font-size: 0.9em;
1774
+ font-style: italic;
1775
+ }
1776
+
1777
+ div#bbFoot p {
1778
+ line-height: 15px;
1779
+ padding: 15px;
1780
+ }
1781
+
1782
+ div#bbFoot p a {
1783
+ color: rgb(204, 204, 204);
1784
+ text-decoration: none;
1785
+ }
1786
+
1787
+ p#bbThanks {
1788
+ float: left;
1789
+ }
1790
+
1791
+ p#bbVersion {
1792
+ text-align: right;
1793
+ }
1794
+
1795
+ div.clear {
1796
+ clear: both !important;
1797
+ height: 0;
1798
+ line-height: 0;
1799
+ font-size: 0;
1800
+ }
1801
+
1802
+
1803
+
1804
+
1805
+
1806
+
1807
+
1808
+
1809
+ /* Layout classes */
1810
+ /*
1811
+ .absleft {
1812
+ position: absolute;
1813
+ left: 0;
1814
+ }
1815
+
1816
+ .absright {
1817
+ position: absolute;
1818
+ right: 0;
1819
+ }
1820
+
1821
+ .abstop {
1822
+ position: absolute;
1823
+ top: 0;
1824
+ }
1825
+
1826
+ .posrel {
1827
+ position: relative;
1828
+ }
1829
+
1830
+ .alignleft {
1831
+ float: left;
1832
+ }
1833
+
1834
+ .alignright {
1835
+ float: right;
1836
+ }
1837
+ */
1838
+ /*
1839
+ .alternate, .alt {
1840
+ background: #f1f1f1;
1841
+ }
1842
+ */
1843
+ /*
1844
+ .active {
1845
+ background-color: rgb(200, 250, 200);
1846
+ }
1847
+ */
1848
+
1849
+
1850
+
1851
+
1852
+ /* List Blocks */
1853
+
1854
+
bp-forums/bbpress/bb-admin/tag-destroy.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require('admin.php');
3
+
4
+ if ( !bb_current_user_can('manage_tags') )
5
+ bb_die(__('You are not allowed to manage tags.'));
6
+
7
+ $tag_id = (int) $_POST['id' ];
8
+
9
+ bb_check_admin_referer( 'destroy-tag_' . $tag_id );
10
+
11
+ $old_tag = bb_get_tag( $tag_id );
12
+ if ( !$old_tag )
13
+ bb_die(__('Tag not found.'));
14
+
15
+ if ( $destroyed = bb_destroy_tag( $tag_id ) ) {
16
+ printf(__("Rows deleted from tags table: %d <br />\n"), $destroyed['tags']);
17
+ printf(__("Rows deleted from tagged table: %d <br />\n"), $destroyed['tagged']);
18
+ printf(__('<a href="%s">Home</a>'), bb_get_uri());
19
+ } else {
20
+ die(printf(__("Something odd happened when attempting to destroy that tag.<br />\n<a href=\"%s\">Try Again?</a>"), wp_get_referer()));
21
+ }
22
+ ?>
bp-forums/bbpress/bb-admin/tag-merge.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require('admin.php');
3
+
4
+ if ( !bb_current_user_can('manage_tags') )
5
+ bb_die(__('You are not allowed to manage tags.'));
6
+
7
+ $old_id = (int) $_POST['id' ];
8
+ $tag = $_POST['tag'];
9
+
10
+ bb_check_admin_referer( 'merge-tag_' . $old_id );
11
+
12
+ if ( ! $tag = bb_get_tag( $tag ) )
13
+ bb_die(__('Tag specified not found.'));
14
+
15
+ if ( ! bb_get_tag( $old_id ) )
16
+ bb_die(__('Tag to be merged not found.'));
17
+
18
+ if ( $merged = bb_merge_tags( $old_id, $tag->tag_id ) ) {
19
+ printf(__("Number of topics from which the old tag was removed: %d <br />\n"), $merged['old_count']);
20
+ printf(__("Number of topics to which the new tag was added: %d <br />\n"),$merged['diff_count']);
21
+ printf(__("Number of rows deleted from tags table:%d <br />\n"),$merged['destroyed']['tags']);
22
+ printf(__('<a href="%s">New Tag</a>'), bb_get_tag_link());
23
+ } else {
24
+ die(printf(__("Something odd happened when attempting to merge those tags.<br />\n<a href=\"%s\">Try Again?</a>"), wp_get_referer()));
25
+ }
26
+ ?>
bp-forums/bbpress/bb-admin/tag-rename.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require('admin.php');
3
+
4
+ if ( !bb_current_user_can('manage_tags') )
5
+ bb_die(__('You are not allowed to manage tags.'));
6
+
7
+ $tag_id = (int) $_POST['id' ];
8
+ $tag = $_POST['tag'];
9
+
10
+ bb_check_admin_referer( 'rename-tag_' . $tag_id );
11
+
12
+ $old_tag = bb_get_tag( $tag_id );
13
+ if ( !$old_tag )
14
+ bb_die(__('Tag not found.'));
15
+
16
+ $tag = stripslashes( $tag );
17
+ if ( $tag = bb_rename_tag( $tag_id, $tag ) )
18
+ wp_redirect( bb_get_tag_link() );
19
+ else
20
+ die(printf(__('There already exists a tag by that name or the name is invalid. <a href="%s">Try Again</a>'), wp_get_referer()));
21
+ exit;
22
+ ?>
bp-forums/bbpress/bb-admin/themes.php ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once('admin.php');
3
+
4
+ $themes = bb_get_themes();
5
+
6
+ $activetheme = bb_get_option('bb_active_theme');
7
+ if (!$activetheme) {
8
+ $activetheme = BB_DEFAULT_THEME;
9
+ }
10
+
11
+ if ( isset($_GET['theme']) ) {
12
+ if ( !bb_current_user_can( 'manage_themes' ) ) {
13
+ wp_redirect( bb_get_uri(null, null, BB_URI_CONTEXT_HEADER) );
14
+ exit;
15
+ }
16
+
17
+ bb_check_admin_referer( 'switch-theme' );
18
+ do_action( 'bb_deactivate_theme_' . $activetheme );
19
+
20
+ $theme = stripslashes($_GET['theme']);
21
+ $theme_data = bb_get_theme_data( $theme );
22
+ if ($theme_data['Name']) {
23
+ $name = $theme_data['Name'];
24
+ } else {
25
+ $name = preg_replace( '/^([a-z0-9_-]+#)/i', '', $theme);
26
+ }
27
+ if ($theme == BB_DEFAULT_THEME) {
28
+ bb_delete_option( 'bb_active_theme' );
29
+ } else {
30
+ bb_update_option( 'bb_active_theme', $theme );
31
+ }
32
+ do_action( 'bb_activate_theme_' . $theme );
33
+ wp_redirect( bb_get_uri('bb-admin/themes.php', array('activated' => 1, 'name' => urlencode( $name ) ), BB_URI_CONTEXT_HEADER + BB_URI_CONTEXT_BB_ADMIN ) );
34
+ exit;
35
+ }
36
+
37
+ if ( isset($_GET['activated']) )
38
+ $theme_notice = bb_admin_notice( sprintf( __( '<strong>Theme "%s" activated</strong>' ), esc_attr($_GET['name'])) );
39
+
40
+ if ( !in_array($activetheme, $themes) ) {
41
+ if ($activetheme == BB_DEFAULT_THEME) {
42
+ remove_action( 'bb_admin_notices', $theme_notice );
43
+ bb_admin_notice( __( '<strong>Default theme is missing.</strong>' ), 'error' );
44
+ } else {
45
+ bb_delete_option( 'bb_active_theme' );
46
+ remove_action( 'bb_admin_notices', $theme_notice );
47
+ bb_admin_notice( __( '<strong>Theme not found. Default theme applied.</strong>' ), 'error' );
48
+ }
49
+ }
50
+
51
+ function bb_admin_theme_row( $theme, $position ) {
52
+ $theme_directory = bb_get_theme_directory( $theme );
53
+ $theme_data = file_exists( $theme_directory . 'style.css' ) ? bb_get_theme_data( $theme ) : false;
54
+ $screen_shot = file_exists( $theme_directory . 'screenshot.png' ) ? esc_url( bb_get_theme_uri( $theme ) . 'screenshot.png' ) : false;
55
+ $activation_url = bb_get_uri('bb-admin/themes.php', array('theme' => urlencode($theme)), BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN);
56
+ $activation_url = esc_url( bb_nonce_url( $activation_url, 'switch-theme' ) );
57
+
58
+ if ( 1 === $position || 0 === $position ) {
59
+ echo '<tr>';
60
+ }
61
+ ?>
62
+ <td class="position-<?php echo( (int) $position ); ?>">
63
+ <div class="screen-shot"><?php if ( $screen_shot ) : ?><a href="<?php echo $activation_url; ?>" title="<?php echo esc_attr( sprintf( __( 'Activate "%s"' ), $theme_data['Title'] ) ); ?>"><img alt="<?php echo esc_attr( $theme_data['Title'] ); ?>" src="<?php echo $screen_shot; ?>" /></a><?php endif; ?></div>
64
+ <div class="description">
65
+ <h3 class="themes">
66
+ <?php
67
+ printf(
68
+ __( '%1$s %2$s by <cite>%3$s</cite>' ),
69
+ $theme_data['Title'],
70
+ $theme_data['Version'],
71
+ $theme_data['Author']
72
+ );
73
+ ?>
74
+ </h3>
75
+
76
+ <?php
77
+ if ( $theme_data['Porter'] ) {
78
+ ?>
79
+ <p>
80
+ <?php
81
+ printf(
82
+ __( 'Ported by <cite>%s</cite>' ),
83
+ $theme_data['Porter']
84
+ );
85
+ ?>
86
+ </p>
87
+ <?php
88
+ }
89
+ ?>
90
+
91
+ <?php echo $theme_data['Description']; // Description is autop'ed ?>
92
+ <?php
93
+ if ( 0 !== $position ) {
94
+ ?>
95
+ <div class="actions">
96
+ <a href="<?php echo $activation_url; ?>" title="<?php echo esc_attr( sprintf( __( 'Activate "%s"' ), $theme_data['Title'] ) ); ?>"><?php _e( 'Activate' ); ?></a>
97
+ </div>
98
+ <?php
99
+ }
100
+ ?>
101
+ <p class="location"><?php printf(__('All of this theme\'s files are located in the "%s" themes directory.'), $theme_data['Location']); ?></p>
102
+ </div>
103
+ </td>
104
+ <?php
105
+
106
+ if ( 3 === $position || 0 === $position ) {
107
+ echo '</tr>';
108
+ }
109
+ }
110
+
111
+ if ( isset( $bb->safemode ) && $bb->safemode === true ) {
112
+ bb_admin_notice( __( '<strong>"Safe mode" is on, the default theme will be used instead of the active theme indicated below.</strong>' ), 'error' );
113
+ }
114
+
115
+ $bb_admin_body_class = ' bb-admin-appearance';
116
+
117
+ bb_get_admin_header();
118
+ ?>
119
+
120
+ <h2><?php _e('Manage Themes'); ?></h2>
121
+ <?php do_action( 'bb_admin_notices' ); ?>
122
+
123
+ <h3 class="themes"><?php _e('Current Theme'); ?></h3>
124
+ <div>
125
+ <table class="theme-list-active">
126
+ <?php bb_admin_theme_row( $themes[$activetheme], 0 ); unset($themes[$activetheme] ); ?>
127
+ </table>
128
+ </div>
129
+
130
+ <?php if ( !empty($themes) ) : ?>
131
+
132
+ <h3 class="themes"><?php _e('Available Themes'); ?></h3>
133
+ <div>
134
+ <table class="theme-list">
135
+ <?php
136
+ $i = 0;
137
+ foreach ( $themes as $theme ) {
138
+ $position = 1 + ( $i % 3 );
139
+
140
+ bb_admin_theme_row( $theme, $position );
141
+
142
+ $i++;
143
+ }
144
+
145
+ switch ( $position ) {
146
+ case 1:
147
+ echo '<td class="position-2"></td><td class="position-3"></td></tr>';
148
+ break;
149
+ case 2:
150
+ echo '<td class="position-3"></td></tr>';
151
+ break;
152
+ case 3:
153
+ break;
154
+ }
155
+ ?>
156
+ </table>
157
+ </div>
158
+
159
+ <?php endif; bb_get_admin_footer(); ?>
bp-forums/bbpress/bb-admin/tools-recount.php ADDED
@@ -0,0 +1,211 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once('admin.php');
3
+
4
+ if ( 'post' == strtolower( $_SERVER['REQUEST_METHOD'] ) ) {
5
+ bb_check_admin_referer( 'do-counts' );
6
+
7
+ $messages = array();
8
+ if ( isset($_POST['topic-posts']) && 1 == $_POST['topic-posts'] ) {
9
+ if ( $topics = (array) $bbdb->get_results("SELECT topic_id, COUNT(post_id) AS count FROM $bbdb->posts WHERE post_status = '0' GROUP BY topic_id") ) {
10
+ $messages[] = __('Counted posts');
11
+ foreach ($topics as $topic) {
12
+ $topic_id = (int) $topic->topic_id;
13
+ $bbdb->query( $bbdb->prepare( "UPDATE $bbdb->topics SET topic_posts = %s WHERE topic_id = %s" ), $topic->count, $topic_id );
14
+ }
15
+ unset($topics, $topic, $topic_id);
16
+ }
17
+ }
18
+
19
+ if ( isset($_POST['topic-voices']) && 1 == $_POST['topic-voices'] ) {
20
+ if ( $topics = (array) $bbdb->get_results("SELECT topic_id FROM $bbdb->topics ORDER BY topic_id") ) {
21
+ $messages[] = __('Counted voices');
22
+ foreach ($topics as $topic) {
23
+ $topic_id = (int) $topic->topic_id;
24
+ if ( $voices = $bbdb->get_col( $bbdb->prepare( "SELECT DISTINCT poster_id FROM $bbdb->posts WHERE topic_id = %s AND post_status = '0';", $topic_id ) ) ) {
25
+ $voices = count( $voices );
26
+ bb_update_topicmeta( $topic_id, 'voices_count', $voices );
27
+ }
28
+ }
29
+ unset($topics, $topic, $topic_id);
30
+ }
31
+ }
32
+
33
+ if ( isset($_POST['topic-deleted-posts']) && 1 == $_POST['topic-deleted-posts'] ) {
34
+ $old = (array) $bbdb->get_col("SELECT object_id FROM $bbdb->meta WHERE object_type = 'bb_topics' AND meta_key = 'deleted_posts'");
35
+ $old = array_flip($old);
36
+ if ( $topics = (array) $bbdb->get_results("SELECT topic_id, COUNT(post_id) AS count FROM $bbdb->posts WHERE post_status != '0' GROUP BY topic_id") ) {
37
+ $messages[] = __('Counting deleted posts&#8230;');
38
+ foreach ( $topics as $topic ) {
39
+ bb_update_topicmeta( $topic->topic_id, 'deleted_posts', $topic->count );
40
+ unset($old[$topic->topic_id]);
41
+ }
42
+ unset($topics, $topic);
43
+ }
44
+ if ( $old ) {
45
+ $old = join(',', array_flip($old));
46
+ $bbdb->query("DELETE FROM $bbdb->meta WHERE object_type = 'bb_topic' AND object_id IN ($old) AND meta_key = 'deleted_posts'");
47
+ $messages[] = __('&#8230;counted deleted posts');
48
+ } else {
49
+ $messages[] = __('&#8230;no deleted posts to count');
50
+ }
51
+ }
52
+
53
+ if ( isset($_POST['forums']) && 1 == $_POST['forums'] ) {
54
+ if ( $all_forums = (array) $bbdb->get_col("SELECT forum_id FROM $bbdb->forums") ) {
55
+ $messages[] = __('Counted forum topics and posts');
56
+ $all_forums = array_flip( $all_forums );
57
+ $forums = $bbdb->get_results("SELECT forum_id, COUNT(topic_id) AS topic_count, SUM(topic_posts) AS post_count FROM $bbdb->topics WHERE topic_status = 0 GROUP BY forum_id");
58
+ foreach ( (array) $forums as $forum ) {
59
+ $bbdb->query("UPDATE $bbdb->forums SET topics = '$forum->topic_count', posts = '$forum->post_count' WHERE forum_id = '$forum->forum_id'");
60
+ unset($all_forums[$forum->forum_id]);
61
+ }
62
+ if ( $all_forums ) {
63
+ $all_forums = implode(',', array_flip( $all_forums ) );
64
+ $bbdb->query("UPDATE $bbdb->forums SET topics = 0, posts = 0 WHERE forum_id IN ($all_forums)");
65
+ }
66
+ unset($all_forums, $forums, $forum);
67
+ }
68
+ }
69
+
70
+ if ( isset($_POST['topics-replied']) && 1 == $_POST['topics-replied'] ) {
71
+ if ( $users = (array) $bbdb->get_col("SELECT ID FROM $bbdb->users") ) {
72
+ $messages[] = __('Counted topics to which each user has replied');
73
+ foreach ( $users as $user )
74
+ bb_update_topics_replied( $user );
75
+ unset($users, $user);
76
+ }
77
+ }
78
+
79
+ if ( isset($_POST['topic-tag-count']) && 1 == $_POST['topic-tag-count'] ) {
80
+ // Reset tag count to zero
81
+ $bbdb->query( "UPDATE $bbdb->topics SET tag_count = 0" );
82
+
83
+ // Get all tags
84
+ $terms = $wp_taxonomy_object->get_terms( 'bb_topic_tag' );
85
+
86
+ if ( !is_wp_error( $terms ) && is_array( $terms ) ) {
87
+ $messages[] = __('Counted topic tags');
88
+ foreach ( $terms as $term ) {
89
+ $topic_ids = bb_get_tagged_topic_ids( $term->term_id );
90
+ if ( !is_wp_error( $topic_ids ) && is_array( $topic_ids ) ) {
91
+ $bbdb->query(
92
+ "UPDATE $bbdb->topics SET tag_count = tag_count + 1 WHERE topic_id IN (" . join( ',', $topic_ids ) . ")"
93
+ );
94
+ }
95
+ unset( $topic_ids );
96
+ }
97
+ }
98
+ unset( $terms, $term );
99
+ }
100
+
101
+ if ( isset($_POST['tags-tag-count']) && 1 == $_POST['tags-tag-count'] ) {
102
+ // Get all tags
103
+ $terms = $wp_taxonomy_object->get_terms( 'bb_topic_tag', array( 'hide_empty' => false ) );
104
+
105
+ if ( !is_wp_error( $terms ) && is_array( $terms ) ) {
106
+ $messages[] = __('Counted tagged topics');
107
+ $_terms = array();
108
+ foreach ( $terms as $term ) {
109
+ $_terms[] = $term->term_id;
110
+ }
111
+ if ( count( $_terms ) ) {
112
+ $wp_taxonomy_object->update_term_count( $_terms, 'bb_topic_tag' );
113
+ }
114
+ }
115
+ unset( $term, $_terms );
116
+ }
117
+
118
+ if ( isset($_POST['tags-delete-empty']) && 1 == $_POST['tags-delete-empty'] ) {
119
+ // Get all tags
120
+ if ( !isset( $terms ) ) {
121
+ $terms = $wp_taxonomy_object->get_terms( 'bb_topic_tag', array( 'hide_empty' => false ) );
122
+ }
123
+
124
+ if ( !is_wp_error( $terms ) && is_array( $terms ) ) {
125
+ $messages[] = __('Deleted tags with no topics');
126
+ foreach ( $terms as $term ) {
127
+ $topic_ids = bb_get_tagged_topic_ids( $term->term_id );
128
+ if ( !is_wp_error( $topic_ids ) && is_array( $topic_ids ) ) {
129
+ if ( false === $topic_ids || ( is_array( $topic_ids ) && !count( $topic_ids ) ) ) {
130
+ bb_destroy_tag( $term->term_taxonomy_id );
131
+ }
132
+ }
133
+ unset( $topic_ids );
134
+ }
135
+ }
136
+ unset( $terms, $term );
137
+ }
138
+
139
+ if ( isset($_POST['clean-favorites']) && 1 == $_POST['clean-favorites'] ) {
140
+ $favorites_key = $bbdb->prefix . 'favorites';
141
+ if ( $users = $bbdb->get_results("SELECT user_id AS id, meta_value AS favorites FROM $bbdb->usermeta WHERE meta_key = '" . $favorites_key . "'") ) {
142
+ $messages[] = __('Removed deleted topics from users\' favorites');
143
+ $topics = $bbdb->get_col("SELECT topic_id FROM $bbdb->topics WHERE topic_status = '0'");
144
+ foreach ( $users as $user ) {
145
+ foreach ( explode(',', $user->favorites) as $favorite ) {
146
+ if ( !in_array($favorite, $topics) ) {
147
+ bb_remove_user_favorite( $user->id, $favorite );
148
+ }
149
+ }
150
+ }
151
+ unset($topics, $users, $user, $favorite);
152
+ }
153
+ }
154
+
155
+ bb_recount_list();
156
+ foreach ( (array) $recount_list as $item ) {
157
+ if ( isset($item[2]) && isset($_POST[$item[0]]) && 1 == $_POST[$item[0]] && is_callable($item[2]) ) {
158
+ call_user_func( $item[2] );
159
+ }
160
+ }
161
+
162
+ if ( count( $messages ) ) {
163
+ $messages = join( '</p>' . "\n" . '<p>', $messages );
164
+ bb_admin_notice( $messages );
165
+ }
166
+ }
167
+
168
+
169
+ $bb_admin_body_class = ' bb-admin-tools';
170
+
171
+ bb_get_admin_header();
172
+ ?>
173
+ <h2><?php _e('Tools') ?></h2>
174
+ <?php do_action( 'bb_admin_notices' ); ?>
175
+
176
+ <form class="settings" method="post" action="<?php bb_uri('bb-admin/tools-recount.php', null, BB_URI_CONTEXT_FORM_ACTION + BB_URI_CONTEXT_BB_ADMIN); ?>">
177
+ <fieldset>
178
+ <legend><?php _e( 'Re-count' ) ?></legend>
179
+ <p><?php _e( 'To minimize database queries, bbPress keeps it\'s own count of various items like posts in each topic and topics in each forum. Occasionally these internal counters may become incorrect, you can manually re-count these items using this form.' ) ?></p>
180
+ <p><?php _e( 'You can also clean out some stale items here, like empty tags.' ) ?></p>
181
+ <?php
182
+ bb_recount_list();
183
+ if ( $recount_list ) {
184
+ ?>
185
+ <div id="option-counts">
186
+ <div class="label">
187
+ <?php _e( 'Items to re-count' ); ?>
188
+ </div>
189
+ <div class="inputs">
190
+ <?php
191
+ foreach ( $recount_list as $item ) {
192
+ echo '<label class="checkboxs"><input type="checkbox" class="checkbox" name="' . esc_attr( $item[0] ) . '" id="' . esc_attr( str_replace( '_', '-', $item[0] ) ) . '" value="1" /> ' . esc_html( $item[1] ) . '</label>' . "\n";
193
+ }
194
+ ?>
195
+ </div>
196
+ </div>
197
+ <?php
198
+ } else {
199
+ ?>
200
+ <p><?php _e( 'There are no re-count tools available.' ) ?></p>
201
+ <?php
202
+ }
203
+ ?>
204
+ </fieldset>
205
+ <fieldset class="submit">
206
+ <?php bb_nonce_field( 'do-counts' ); ?>
207
+ <input class="submit" type="submit" name="submit" value="<?php _e('Recount Items') ?>" />
208
+ </fieldset>
209
+ </form>
210
+
211
+ <?php bb_get_admin_footer(); ?>
bp-forums/bbpress/bb-admin/topic-move.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once('admin-action.php');
3
+
4
+ $topic_id = absint( $_POST['topic_id'] );
5
+ $forum_id = absint( $_POST['forum_id'] );
6
+
7
+ if ( !is_numeric($topic_id) || !is_numeric($forum_id) )
8
+ bb_die(__('Invalid topic or forum.'));
9
+
10
+ if ( !bb_current_user_can( 'move_topic', $topic_id, $forum_id ) ) {
11
+ wp_redirect( bb_get_uri(null, null, BB_URI_CONTEXT_HEADER) );
12
+ exit;
13
+ }
14
+
15
+ bb_check_admin_referer( 'move-topic_' . $topic_id );
16
+
17
+ $topic = get_topic( $topic_id );
18
+ $forum = bb_get_forum( $forum_id );
19
+
20
+ if ( !$topic || !$forum )
21
+ bb_die(__('Your topic or forum caused all manner of confusion'));
22
+
23
+ bb_move_topic( $topic_id, $forum_id );
24
+
25
+ if ( !$redirect = wp_get_referer() )
26
+ $redirect = get_topic_link( $topic_id );
27
+
28
+ bb_safe_redirect( $redirect );
29
+ exit;
30
+ ?>
bp-forums/bbpress/bb-admin/topic-toggle.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require('admin-action.php');
3
+
4
+ $topic_id = (int) $_GET['id'];
5
+ $topic = get_topic ( $topic_id );
6
+
7
+ if ( !$topic )
8
+ bb_die(__('There is a problem with that topic, pardner.'));
9
+
10
+ if ( !bb_current_user_can( 'close_topic', $topic_id ) ) {
11
+ wp_redirect( bb_get_uri(null, null, BB_URI_CONTEXT_HEADER) );
12
+ exit;
13
+ }
14
+
15
+ bb_check_admin_referer( 'close-topic_' . $topic_id );
16
+
17
+ if ( topic_is_open( $topic_id ) ) {
18
+ bb_close_topic( $topic_id );
19
+ $message = 'closed';
20
+ } else {
21
+ bb_open_topic ( $topic_id );
22
+ $message = 'opened';
23
+ }
24
+
25
+ if ( $sendto = wp_get_referer() ) {
26
+ $sendto = remove_query_arg( 'message', $sendto );
27
+ $sendto = add_query_arg( 'message', $message, $sendto );
28
+ } else {
29
+ $sendto = get_topic_link( $topic_id );
30
+ }
31
+
32
+ bb_safe_redirect( $sendto );
33
+ exit;
bp-forums/bbpress/bb-admin/topics.php ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once('admin.php');
3
+
4
+ if ( !empty( $_GET['message'] ) ) {
5
+ switch ( (string) $_GET['message'] ) {
6
+ case 'undeleted':
7
+ bb_admin_notice( __( '<strong>Topic undeleted.</strong>' ) );
8
+ break;
9
+ case 'deleted':
10
+ bb_admin_notice( __( '<strong>Topic deleted.</strong>' ) );
11
+ break;
12
+ case 'opened':
13
+ bb_admin_notice( __( '<strong>Topic opened.</strong>' ) );
14
+ break;
15
+ case 'closed':
16
+ bb_admin_notice( __( '<strong>Topic closed.</strong>' ) );
17
+ break;
18
+ }
19
+ }
20
+
21
+ $bb_admin_body_class = ' bb-admin-topics';
22
+
23
+ bb_get_admin_header();
24
+
25
+ if ( !bb_current_user_can('browse_deleted') )
26
+ die(__("Now how'd you get here? And what did you think you'd being doing?")); //This should never happen.
27
+ add_filter( 'topic_link', 'bb_make_link_view_all' );
28
+ add_filter( 'topic_last_post_link', 'bb_make_link_view_all' );
29
+ $topic_query_vars = array( 'topic_status' => 'normal', 'open' => 'open', 'count' => true, 'per_page' => 20 );
30
+ if ( isset($_POST['search']) && $_POST['search'] ) {
31
+ $topic_query_vars['post_status'] = 'all';
32
+ } elseif ( isset($_GET['search']) && $_GET['search'] ) {
33
+ $topic_query_vars['post_status'] = 'all';
34
+ }
35
+ $topic_query = new BB_Query_Form( 'topic', $topic_query_vars );
36
+ $topics = $topic_query->results;
37
+ ?>
38
+
39
+ <div class="wrap">
40
+
41
+ <h2><?php _e( 'Topics' ); ?>
42
+ <?php
43
+ $h2_search = $topic_query->get( 'search' );
44
+ $h2_forum = $topic_query->get( 'forum_id' );
45
+ $h2_tag = $topic_query->get( 'tag_id' );
46
+ $h2_author = $topic_query->get( 'topic_author_id' );
47
+
48
+ $h2_search = $h2_search ? ' ' . sprintf( __('containing &#8220;%s&#8221;'), esc_html( $h2_search ) ) : '';
49
+ $h2_forum = $h2_forum ? ' ' . sprintf( __('in &#8220;%s&#8221;') , get_forum_name( $h2_forum ) ) : '';
50
+ $h2_tag = $h2_tag ? ' ' . sprintf( __('with tag &#8220;%s&#8221;'), esc_html( bb_get_tag_name( $h2_tag ) ) ) : '';
51
+ $h2_author = $h2_author ? ' ' . sprintf( __('by %s') , esc_html( get_user_name( $h2_author ) ) ) : '';
52
+
53
+ if ( $h2_search || $h2_forum || $h2_tag || $h2_author ) {
54
+ echo '<span class="subtitle">';
55
+
56
+ printf( __( '%1$s%2$s%3$s%4$s' ), $h2_search, $h2_forum, $h2_tag, $h2_author );
57
+
58
+ echo '</span>';
59
+ }
60
+ ?>
61
+ </h2>
62
+ <?php do_action( 'bb_admin_notices' ); ?>
63
+
64
+ <?php $topic_query->form( array('tag' => true, 'topic_author' => true, 'topic_status' => true, 'open' => true, 'submit' => __('Filter')) ); ?>
65
+
66
+ <div class="tablenav">
67
+ <?php if ( $topic_query->found_rows ) : ?>
68
+ <div class="tablenav-pages">
69
+ <span class="displaying-num"><?php echo $displaying_num = sprintf(
70
+ __( '%1$s to %2$s of %3$s' ),
71
+ bb_number_format_i18n( ( $page - 1 ) * $topic_query->get( 'per_page' ) + 1 ),
72
+ $page * $topic_query->get( 'per_page' ) < $topic_query->found_rows ? bb_number_format_i18n( $page * $topic_query->get( 'per_page' ) ) : '<span class="total-type-count">' . bb_number_format_i18n( $topic_query->found_rows ) . '</span>',
73
+ '<span class="total-type-count">' . bb_number_format_i18n( $topic_query->found_rows ) . '</span>'
74
+ ); ?></span><span class="displaying-pages">
75
+ <?php
76
+ $_page_link_args = array(
77
+ 'page' => $page,
78
+ 'total' => $topic_query->found_rows,
79
+ 'per_page' => $topic_query->get( 'per_page' ),
80
+ 'mod_rewrite' => false,
81
+ 'prev_text' => __( '&laquo;' ),
82
+ 'next_text' => __( '&raquo;' )
83
+ );
84
+ echo $page_number_links = get_page_number_links( $_page_link_args );
85
+ ?></span>
86
+ <div class="clear"></div>
87
+ </div>
88
+ <?php endif; ?>
89
+ </div>
90
+ <div class="clear"></div>
91
+
92
+ <?php if ( !$topics ) : ?>
93
+
94
+ <p class="no-results"><?php _e('No topics found.'); ?></p>
95
+
96
+ <?php else : bb_cache_first_posts( $topics ); bb_cache_last_posts( $topics ); ?>
97
+
98
+ <table id="topics-list" class="widefat">
99
+ <thead>
100
+ <tr>
101
+ <th scope="col"><?php _e('Topic') ?></th>
102
+ <th scope="col"><?php _e('Author') ?></th>
103
+ <th scope="col"><?php _e('Posts') ?></th>
104
+ <th scope="col"><?php _e('Date') ?></th>
105
+ <th scope="col"><?php _e('Freshness') ?></th>
106
+ </tr>
107
+ </thead>
108
+ <tfoot>
109
+ <tr>
110
+ <th scope="col"><?php _e('Topic') ?></th>
111
+ <th scope="col"><?php _e('Author') ?></th>
112
+ <th scope="col"><?php _e('Posts') ?></th>
113
+ <th scope="col"><?php _e('Date') ?></th>
114
+ <th scope="col"><?php _e('Freshness') ?></th>
115
+ </tr>
116
+ </thead>
117
+
118
+ <tbody>
119
+ <?php foreach ( $topics as $topic ) : $first_post = bb_get_first_post( $topic ); ?>
120
+ <tr id="topic-<?php echo $topic->topic_id; ?>"<?php topic_class(); ?>>
121
+ <td class="topic">
122
+ <span class="row-title"><?php bb_topic_labels(); ?> <a href="<?php topic_link(); ?>"><?php topic_title(); ?></a></span>
123
+ <div>
124
+ <span class="row-actions">
125
+ <a href="<?php topic_link(); ?>"><?php _e( 'View' ); ?></a> |
126
+ <?php if ( $first_post ) : post_edit_link( $first_post->post_id ); ?> |
127
+ <?php endif; topic_close_link( array( 'id' => $topic->topic_id, 'before' => '', 'after' => '', 'close_text' => __( 'Close' ), 'open_text' => _x( 'Open', 'action' ) ) ); ?> |
128
+ <?php topic_delete_link( array( 'id' => $topic->topic_id, 'before' => '', 'after' => '', 'delete_text' => __( 'Delete' ), 'undelete_text' => __( 'Undelete' ) ) ); ?>
129
+ </span>&nbsp;
130
+ </div>
131
+ </td>
132
+ <td class="author">
133
+ <a class="author-link" href="<?php user_profile_link( $topic->topic_poster ); ?>">
134
+ <?php echo bb_get_avatar( $topic->topic_poster, '16' ); ?>
135
+ <?php topic_author(); ?>
136
+ </a>
137
+ </td>
138
+ <td class="posts num"><?php topic_posts(); ?></td>
139
+ <td class="date num">
140
+ <?php
141
+ if ( get_topic_start_time( 'U' ) < ( time() - 86400 ) ) {
142
+ topic_start_time( 'Y/m/d\<\b\r \/\>H:i:s' );
143
+ } else {
144
+ printf( __( '%s ago' ), get_topic_start_time( 'since' ) );
145
+ }
146
+ ?>
147
+ </td>
148
+ <td class="freshness num"><a href="<?php topic_last_post_link(); ?>" title="<?php echo esc_attr( sprintf( __( 'Last post by %s' ), get_topic_last_poster() ) ); ?>">
149
+ <?php
150
+ if ( get_topic_time( 'U' ) < ( time() - 86400 ) ) {
151
+ topic_time( 'Y/m/d\<\b\r \/\>H:i:s' );
152
+ } else {
153
+ printf( __( '%s ago' ), get_topic_time( 'since' ) );
154
+ }
155
+ ?>
156
+
157
+ <?php //topic_time( bb_get_datetime_formatstring_i18n() ); ?>
158
+
159
+
160
+ </a></td>
161
+ </tr>
162
+ <?php endforeach; ?>
163
+ </tbody>
164
+ </table>
165
+
166
+ <?php endif; ?>
167
+
168
+ <div class="tablenav bottom">
169
+ <?php if ( $topic_query->found_rows ) : ?>
170
+ <div class="tablenav-pages">
171
+ <span class="displaying-pages"><?php echo $page_number_links; ?></span>
172
+ <div class="clear"></div>
173
+ </div>
174
+ <?php endif; ?>
175
+ </div>
176
+ <div class="clear"></div>
177
+
178
+ </div>
179
+
180
+ <?php bb_get_admin_footer(); ?>
bp-forums/bbpress/bb-admin/upgrade.php ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Remove these lines if you want to upgrade and are using safe mode
3
+ if ( ini_get('safe_mode') )
4
+ die("You're running in safe mode which does not allow this upgrade
5
+ script to set a running time limit. Depending on the size of your
6
+ database and on which parts of the script you are running, the script
7
+ can take quite some time to run (or it could take just a few seconds).
8
+ To throw caution to the wind and run the script in safe mode anyway,
9
+ remove the first few lines of code in the <code>bb-admin/upgrade.php</code>
10
+ file. Backups are always a good idea.");
11
+ // Stop removing lines
12
+
13
+ // Very old (pre 0.7) installs may need further upgrade utilities.
14
+ // Post to http://lists.bbpress.org/mailman/listinfo/bbdev if needed
15
+
16
+ require('../bb-load.php');
17
+ require( BB_PATH . 'bb-admin/includes/functions.bb-upgrade.php' );
18
+
19
+ $step = 'unrequired';
20
+
21
+ $forced = false;
22
+ if ( isset( $_POST['force'] ) && 1 == $_POST['force'] ) {
23
+ $forced = true;
24
+ } elseif ( isset( $_GET['force'] ) && 1 == $_GET['force'] ) {
25
+ $forced = true;
26
+ }
27
+
28
+ if ( bb_get_option( 'bb_db_version' ) > bb_get_option_from_db( 'bb_db_version' ) || $forced ) {
29
+
30
+ $forced_input = '';
31
+ if ( $forced ) {
32
+ $forced_input = '<input type="hidden" name="force" value="1" />';
33
+ }
34
+
35
+ $step = 'required';
36
+
37
+ if ( strtolower( $_SERVER['REQUEST_METHOD']) == 'post' ) {
38
+
39
+ bb_check_admin_referer( 'bbpress-upgrader' );
40
+
41
+ define('BB_UPGRADING', true);
42
+
43
+ $bbdb->hide_errors();
44
+
45
+ $messages = bb_upgrade_all();
46
+
47
+ $bbdb->show_errors();
48
+
49
+ $upgrade_log = array(__('Beginning upgrade&hellip;'));
50
+ if (is_array($messages['messages'])) {
51
+ $upgrade_log = array_merge($upgrade_log, $messages['messages']);
52
+ }
53
+ $upgrade_log[] = '>>> ' . __('Done');
54
+
55
+ $error_log = array();
56
+ if (is_array($messages['errors'])) {
57
+ $error_log = $messages['errors'];
58
+ }
59
+
60
+ if ( bb_get_option( 'bb_db_version' ) === bb_get_option_from_db( 'bb_db_version' ) && !count($error_log) ) {
61
+ $step = 'complete';
62
+ } else {
63
+ $step = 'error';
64
+ }
65
+
66
+ wp_cache_flush();
67
+ }
68
+
69
+ }
70
+
71
+ bb_install_header( __('bbPress database upgrade'), false, true );
72
+ ?>
73
+ <script type="text/javascript" charset="utf-8">
74
+ function toggleAdvanced(toggle, target) {
75
+ var toggleObj = document.getElementById(toggle);
76
+ var targetObj = document.getElementById(target);
77
+ if (toggleObj.checked) {
78
+ targetObj.style.display = 'block';
79
+ } else {
80
+ targetObj.style.display = 'none';
81
+ }
82
+ }
83
+ </script>
84
+ <?php
85
+ switch ($step) {
86
+ case 'unrequired':
87
+ ?>
88
+ <p class="last">
89
+ <?php printf( __('Nothing to upgrade. <a href="%s">Get back to work!</a>'), bb_get_uri('bb-admin/', null, BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN) ); ?>
90
+ </p>
91
+ <?php
92
+ break;
93
+
94
+ case 'required'
95
+ ?>
96
+ <div class="open">
97
+ <h2><?php _e('Database upgrade required'); ?></h2>
98
+ <div>
99
+ <form action="<?php bb_uri('bb-admin/upgrade.php', null, BB_URI_CONTEXT_FORM_ACTION + BB_URI_CONTEXT_BB_ADMIN); ?>" method="post">
100
+ <p class="error">
101
+ <?php _e('It looks like your database is out-of-date. You can upgrade it here.'); ?>
102
+ </p>
103
+ <fieldset class="buttons">
104
+ <?php bb_nonce_field( 'bbpress-upgrader' ); ?>
105
+ <?php echo $forced_input; ?>
106
+ <label for="upgrade_next" class="forward">
107
+ <input class="button" id="upgrade_next" type="submit" value="<?php _e( 'Upgrade database' ); ?>" />
108
+ </label>
109
+ </fieldset>
110
+ </form>
111
+ </div>
112
+ </div>
113
+ <?php
114
+ break;
115
+
116
+ case 'complete':
117
+ ?>
118
+ <div class="open">
119
+ <h2><?php _e('Database upgrade complete'); ?></h2>
120
+ <div>
121
+ <form action="<?php bb_uri('bb-admin/', null, BB_URI_CONTEXT_FORM_ACTION + BB_URI_CONTEXT_BB_ADMIN); ?>" method="get">
122
+ <p class="message">
123
+ <?php _e('Your database has been successfully upgraded, enjoy!'); ?>
124
+ </p>
125
+ <fieldset>
126
+ <label class="has-label for-toggle" for="upgrade_log_container_toggle">
127
+ <span>
128
+ <?php _e('Show upgrade messages'); ?>
129
+ <input class="checkbox" type="checkbox" id="upgrade_log_container_toggle" value="1" onclick="toggleAdvanced('upgrade_log_container_toggle', 'upgrade_log_container');" />
130
+ </span>
131
+ <div class="clear"></div>
132
+ </label>
133
+ </fieldset>
134
+ <div class="toggle" id="upgrade_log_container" style="display:none;">
135
+ <fieldset>
136
+ <label class="has-label for-textarea" for="upgrade_log">
137
+ <span><?php _e('Upgrade log'); ?></span>
138
+ <textarea id="upgrade_log" class="short"><?php echo(join("\n", $upgrade_log)); ?></textarea>
139
+ </label>
140
+ </fieldset>
141
+ </div>
142
+ <fieldset class="buttons">
143
+ <label for="upgrade_next" class="back">
144
+ <input class="button" id="upgrade_back" type="button" value="<?php _e( '&laquo; Go back to forums' ); ?>" onclick="location.href='<?php echo esc_js( bb_get_uri() ); ?>'; return false;" />
145
+ </label>
146
+ <label for="upgrade_next" class="forward">
147
+ <input class="button" id="upgrade_next" type="submit" value="<?php _e( 'Go to admin' ); ?>" />
148
+ </label>
149
+ </fieldset>
150
+ </form>
151
+ </div>
152
+ </div>
153
+ <?php
154
+ break;
155
+
156
+ case 'error':
157
+ ?>
158
+ <div class="open">
159
+ <h2><?php _e('Database upgrade failed'); ?></h2>
160
+ <div>
161
+ <form action="<?php bb_uri('bb-admin/upgrade.php', null, BB_URI_CONTEXT_FORM_ACTION + BB_URI_CONTEXT_BB_ADMIN); ?>" method="post">
162
+ <p class="error">
163
+ <?php _e('The upgrade process seems to have failed. Check the upgrade messages below for more information.<br /><br />Attempting to go to the admin area without resolving the listed errors will return you to this upgrade page.'); ?>
164
+ </p>
165
+ <fieldset>
166
+ <?php bb_nonce_field( 'bbpress-upgrader' ); ?>
167
+ <?php echo $forced_input; ?>
168
+ <label class="has-label for-toggle" for="upgrade_log_container_toggle" style="margin-bottom: 1.9em;">
169
+ <span>
170
+ <?php _e('Show upgrade messages'); ?>
171
+ <input class="checkbox" type="checkbox" id="upgrade_log_container_toggle" value="1" onclick="toggleAdvanced('upgrade_log_container_toggle', 'upgrade_log_container');" />
172
+ </span>
173
+ <div class="clear"></div>
174
+ </label>
175
+ </fieldset>
176
+ <div class="toggle" id="upgrade_log_container" style="display:none;">
177
+ <fieldset>
178
+ <?php
179
+ if (count($error_log)) {
180
+ ?>
181
+ <label class="has-label for-textarea" for="error_log">
182
+ <span><?php _e('Error log'); ?></span>
183
+ <textarea id="error_log" class="short"><?php echo(join("\n", $error_log)); ?></textarea>
184
+ </label>
185
+ <?php
186
+ }
187
+ ?>
188
+ <label class="has-label for-textarea" for="upgrade_log">
189
+ <span><?php _e('Upgrade log'); ?></span>
190
+ <textarea id="upgrade_log" class="short"><?php echo(join("\n", $upgrade_log)); ?></textarea>
191
+ </label>
192
+ </fieldset>
193
+ </div>
194
+ <fieldset class="buttons">
195
+ <label for="upgrade_next" class="back">
196
+ <input class="button" id="upgrade_back" type="button" value="<?php _e( '&laquo; Go back to forums' ); ?>" onclick="location.href='<?php echo esc_js( bb_get_uri() ); ?>'; return false;" />
197
+ </label>
198
+ <label for="upgrade_next" class="forward">
199
+ <input class="button" id="upgrade_next" type="submit" value="<?php _e( 'Try again' ); ?>" />
200
+ </label>
201
+ </fieldset>
202
+ </form>
203
+ </div>
204
+ </div>
205
+ <?php
206
+ break;
207
+ }
208
+
209
+ bb_install_footer();
210
+ ?>
bp-forums/bbpress/bb-admin/users.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once('admin.php');
3
+
4
+ // Query the users
5
+ $bb_user_search = new BB_User_Search(@$_GET['usersearch'], @$_GET['page'], @$_GET['userrole']);
6
+
7
+ $bb_admin_body_class = ' bb-admin-users';
8
+
9
+ bb_get_admin_header();
10
+ ?>
11
+
12
+ <div class="wrap">
13
+
14
+ <?php
15
+ $bb_user_search->display( true, bb_current_user_can( 'edit_users' ) );
16
+ ?>
17
+
18
+ </div>
19
+
20
+ <?php
21
+ bb_get_admin_footer();
22
+ ?>
bp-forums/bbpress/bb-config-sample.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The base configurations of bbPress.
4
+ *
5
+ * This file has the following configurations: MySQL settings, Table Prefix,
6
+ * Secret Keys and bbPress Language. You can get the MySQL settings from your
7
+ * web host.
8
+ *
9
+ * This file is used by the installer during installation.
10
+ *
11
+ * @package bbPress
12
+ */
13
+
14
+ // ** MySQL settings - You can get this info from your web host ** //
15
+ /** The name of the database for bbPress */
16
+ define( 'BBDB_NAME', 'bbpress' );
17
+
18
+ /** MySQL database username */
19
+ define( 'BBDB_USER', 'username' );
20
+
21
+ /** MySQL database password */
22
+ define( 'BBDB_PASSWORD', 'password' );
23
+
24
+ /** MySQL hostname */
25
+ define( 'BBDB_HOST', 'localhost' );
26
+
27
+ /** Database Charset to use in creating database tables. */
28
+ define( 'BBDB_CHARSET', 'utf8' );
29
+
30
+ /** The Database Collate type. Don't change this if in doubt. */
31
+ define( 'BBDB_COLLATE', '' );
32
+
33
+ /**#@+
34
+ * Authentication Unique Keys.
35
+ *
36
+ * Change these to different unique phrases!
37
+ * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/bbpress/ WordPress.org secret-key service}
38
+ *
39
+ * @since 1.0
40
+ */
41
+ define( 'BB_AUTH_KEY', 'put your unique phrase here' );
42
+ define( 'BB_SECURE_AUTH_KEY', 'put your unique phrase here' );
43
+ define( 'BB_LOGGED_IN_KEY', 'put your unique phrase here' );
44
+ define( 'BB_NONCE_KEY', 'put your unique phrase here' );
45
+ /**#@-*/
46
+
47
+ /**
48
+ * bbPress Database Table prefix.
49
+ *
50
+ * You can have multiple installations in one database if you give each a unique
51
+ * prefix. Only numbers, letters, and underscores please!
52
+ */
53
+ $bb_table_prefix = 'bb_';
54
+
55
+ /**
56
+ * bbPress Localized Language, defaults to English.
57
+ *
58
+ * Change this to localize bbPress. A corresponding MO file for the chosen
59
+ * language must be installed to a directory called "my-languages" in the root
60
+ * directory of bbPress. For example, install de.mo to "my-languages" and set
61
+ * BB_LANG to 'de' to enable German language support.
62
+ */
63
+ define( 'BB_LANG', '' );
64
+ ?>
bp-forums/bbpress/bb-cron.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * bbPress Cron Implementation for hosts, which do not offer CRON or for which
4
+ * the user has not setup a CRON job pointing to this file.
5
+ *
6
+ * The HTTP request to this file will not slow down the visitor who happens to
7
+ * visit when the cron job is needed to run.
8
+ *
9
+ * @package bbPress
10
+ */
11
+
12
+ ignore_user_abort( true );
13
+
14
+ /**
15
+ * Tell bbPress we are doing the CRON task.
16
+ *
17
+ * @var bool
18
+ */
19
+ define( 'DOING_CRON', true );
20
+
21
+ /** Setup bbPress environment */
22
+ require_once( './bb-load.php' );
23
+
24
+ if ( $_GET['check'] != backpress_get_option( 'cron_check' ) ) {
25
+ exit;
26
+ }
27
+
28
+ if ( bb_get_option( 'doing_cron' ) > time() ) {
29
+ exit;
30
+ }
31
+
32
+ bb_update_option( 'doing_cron', time() + 30 );
33
+
34
+ $crons = _get_cron_array();
35
+ $keys = array_keys( $crons );
36
+ if ( !is_array( $crons ) || $keys[0] > time() ) {
37
+ return;
38
+ }
39
+
40
+ foreach ( $crons as $timestamp => $cronhooks ) {
41
+ if ( $timestamp > time() ) {
42
+ break;
43
+ }
44
+ foreach ( $cronhooks as $hook => $keys ) {
45
+ foreach ( $keys as $key => $args ) {
46
+ $schedule = $args['schedule'];
47
+ if ( $schedule != false ) {
48
+ $new_args = array( $timestamp, $schedule, $hook, $args['args'] );
49
+ call_user_func_array( 'wp_reschedule_event' , $new_args );
50
+ }
51
+ wp_unschedule_event( $timestamp, $hook, $args['args'] );
52
+ do_action_ref_array( $hook, $args['args'] );
53
+ }
54
+ }
55
+ }
56
+
57
+ bb_update_option( 'doing_cron', 0 );
bp-forums/bbpress/bb-edit.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require('./bb-load.php');
3
+
4
+ bb_auth('logged_in');
5
+
6
+ $post_id = (int) $_POST['post_id'];
7
+
8
+ $bb_post = bb_get_post( $post_id );
9
+
10
+ if ( !$bb_post ) {
11
+ wp_redirect( bb_get_uri(null, null, BB_URI_CONTEXT_HEADER) );
12
+ die();
13
+ }
14
+
15
+ if ( !bb_current_user_can( 'edit_post', $post_id ) )
16
+ bb_die(__('Sorry, post is too old.'));
17
+
18
+ bb_check_admin_referer( 'edit-post_' . $post_id );
19
+
20
+ if ( 0 != $bb_post->post_status && 'all' == $_GET['view'] ) // We're trying to edit a deleted post
21
+ add_filter('bb_is_first_where', 'bb_no_where');
22
+
23
+ if ( bb_is_first( $bb_post->post_id ) && bb_current_user_can( 'edit_topic', $bb_post->topic_id ) ) {
24
+ bb_insert_topic( array(
25
+ 'topic_title' => stripslashes( $_POST['topic'] ),
26
+ 'topic_id' => $bb_post->topic_id
27
+ ) );
28
+ }
29
+
30
+ bb_insert_post( array(
31
+ 'post_text' => stripslashes( $_POST['post_content'] ),
32
+ 'post_id' => $post_id,
33
+ 'topic_id' => $bb_post->topic_id
34
+ ) );
35
+
36
+ if ( $post_id ) {
37
+ if ( $_REQUEST['view'] === 'all' ) {
38
+ add_filter( 'get_post_link', 'bb_make_link_view_all' );
39
+ }
40
+ $post_link = get_post_link( $post_id );
41
+ wp_redirect( $post_link );
42
+ } else {
43
+ wp_redirect( bb_get_uri(null, null, BB_URI_CONTEXT_HEADER) );
44
+ }
45
+ exit;
46
+ ?>
bp-forums/bbpress/bb-includes/backpress/class.bp-log.php ADDED
@@ -0,0 +1,550 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ /**
5
+ * BackPress logging level constants
6
+ */
7
+ define('BP_LOG_NONE', 0);
8
+ define('BP_LOG_FAIL', 1);
9
+ define('BP_LOG_ERROR', 2);
10
+ define('BP_LOG_WARNING', 4);
11
+ define('BP_LOG_NOTICE', 8);
12
+ define('BP_LOG_DEBUG', 16);
13
+
14
+ /**
15
+ * Combination of all errors (excluding none and debug)
16
+ */
17
+ define('BP_LOG_ALL', BP_LOG_FAIL + BP_LOG_ERROR + BP_LOG_WARNING + BP_LOG_NOTICE);
18
+
19
+
20
+
21
+ /**
22
+ * Provides easy and abstracted logging facilities
23
+ *
24
+ * @package BackPress
25
+ */
26
+ class BP_Log
27
+ {
28
+ /**
29
+ * The logging level
30
+ *
31
+ * @var integer
32
+ */
33
+ var $level = BP_LOG_NONE;
34
+
35
+ /**
36
+ * The type of logging
37
+ *
38
+ * @var string
39
+ */
40
+ var $type = 'php';
41
+
42
+ /**
43
+ * The types of logging available
44
+ *
45
+ * @var array
46
+ */
47
+ var $types = array('php', 'file', 'display', 'console');
48
+
49
+ /**
50
+ * The filename of the file to log messages to when type is "file"
51
+ *
52
+ * @var string
53
+ */
54
+ var $filename = '';
55
+
56
+ /**
57
+ * Whether or not the javascript functions are available
58
+ *
59
+ * @var boolean
60
+ **/
61
+ var $console_javascript_loaded = false;
62
+
63
+ /**
64
+ * Console log messages which are queued up to be displayed on page load
65
+ *
66
+ * @var array
67
+ **/
68
+ var $console_javascript_onloads = array();
69
+
70
+ /**
71
+ * Initialises the logging
72
+ *
73
+ * @return void
74
+ */
75
+ function BP_log($level = false, $type = false, $filename = false)
76
+ {
77
+ $this->set_level($level);
78
+ $this->set_type($type);
79
+ $this->set_filename($filename);
80
+ }
81
+
82
+ /**
83
+ * Sets the logging level
84
+ *
85
+ * @return integer|boolean The old level on success or false
86
+ * @uses BP_LOG_LEVEL
87
+ */
88
+ function set_level($level)
89
+ {
90
+ $old_level = $this->level;
91
+
92
+ if (is_integer($level)) {
93
+ $this->level = $level;
94
+ } elseif (defined('BP_LOG_LEVEL') && is_integer(BP_LOG_LEVEL)) {
95
+ $this->level = BP_LOG_LEVEL;
96
+ } else {
97
+ return false;
98
+ }
99
+
100
+ return $old_level;
101
+ }
102
+
103
+ /**
104
+ * Sets the logging type
105
+ *
106
+ * @return string|false The old type on success or false
107
+ * @uses BP_LOG_TYPE
108
+ */
109
+ function set_type($type)
110
+ {
111
+ $old_type = $this->type;
112
+ $type = strtolower($type);
113
+
114
+ if (in_array($type, $this->types)) {
115
+ $this->type = $type;
116
+ } elseif (defined('BP_LOG_TYPE') && in_array(BP_LOG_TYPE, $this->types)) {
117
+ $this->type = BP_LOG_TYPE;
118
+ } else {
119
+ return false;
120
+ }
121
+
122
+ return $old_type;
123
+ }
124
+
125
+ /**
126
+ * Sets the logging filename
127
+ *
128
+ * @return string|boolean The old filename on success or false
129
+ * @uses BP_LOG_FILENAME
130
+ */
131
+ function set_filename($filename)
132
+ {
133
+ $old_filename = $this->filename;
134
+
135
+ if (is_string($filename)) {
136
+ $_filename = $filename;
137
+ } elseif (defined('BP_LOG_FILENAME') && is_string(BP_LOG_FILENAME)) {
138
+ $_filename = BP_LOG_FILENAME;
139
+ } else {
140
+ return false;
141
+ }
142
+
143
+ if (isset($_filename) && file_exists($_filename) && is_file($_filename) && is_writable($_filename)) {
144
+ $this->filename = $_filename;
145
+ } else {
146
+ return false;
147
+ }
148
+
149
+ return $old_filename;
150
+ }
151
+
152
+ /**
153
+ * Sends a message to the log
154
+ *
155
+ * @return boolean True on success, false on failure
156
+ */
157
+ function send($message = '', $level = BP_LOG_DEBUG, $type = false, $prefix = false)
158
+ {
159
+ // Make sure the level of this message is set to be logged
160
+ if (($level & $this->level) === 0) {
161
+ return;
162
+ }
163
+
164
+ // Format the message into an array of lines to be logged
165
+ $lines = $this->format_message($message, $level, $prefix);
166
+
167
+ // Do some validation on the type
168
+ if ($type && in_array($type, $this->types)) {
169
+ $_type = $type;
170
+ } else {
171
+ $_type = $this->type;
172
+ }
173
+
174
+ // Get a name for the level
175
+ if ($level) {
176
+ $_level = $this->get_level_from_integer($level);
177
+ }
178
+
179
+ // Setup strings to prepend to some of the types
180
+ $prepend = $_level . ': ';
181
+ if ($prefix) {
182
+ $prepend .= $prefix . ': ';
183
+ }
184
+ $pad = str_repeat(' ', strlen($prepend) - 2) . '| ';
185
+
186
+ // Switch over the four types
187
+ switch ($_type) {
188
+ case 'php':
189
+ $php_fail = false;
190
+
191
+ // Check that the error_log() function is available
192
+ if (function_exists('error_log') && is_callable('error_log')) {
193
+ foreach ($lines as $key => $line) {
194
+ if ($key === 0) {
195
+ $_prepend = $prepend;
196
+ } else {
197
+ $_prepend = $pad;
198
+ }
199
+ if (!error_log($_prepend . $line, 0)) {
200
+ $php_fail = true;
201
+ break;
202
+ }
203
+ }
204
+ } else {
205
+ $php_fail = true;
206
+ }
207
+
208
+ if ($php_fail) {
209
+ // The PHP error log process failed, path of least resistance is to write to display
210
+ $this->send($message, $level, 'display', $prefix);
211
+ return;
212
+ }
213
+ break;
214
+
215
+ case 'file':
216
+ $file_fail = false;
217
+
218
+ // We've already done the prerequisite checks on the file by now so just write to it
219
+ if (!$file_handle = fopen($this->filename, 'a')) {
220
+ $file_fail = true;
221
+ } else {
222
+ // Prepare a string to write
223
+ $_lines = array(
224
+ '[' . date('c') . ']',
225
+ '[client ' . $_SERVER['REMOTE_ADDR'] . ']',
226
+ $prepend,
227
+ join("\n", $lines)
228
+ );
229
+ }
230
+ if (fwrite($file_handle, join(' ', $_lines) . "\n") === false) {
231
+ $file_fail = true;
232
+ }
233
+ if ($file_handle) {
234
+ fclose($file_handle);
235
+ }
236
+ if ($file_fail) {
237
+ // Writing to file failed, output to display
238
+ $this->send($message, $level, 'display', $prefix);
239
+ return;
240
+ }
241
+ break;
242
+
243
+ case 'display':
244
+ $_lines = array();
245
+ foreach ($lines as $key => $line) {
246
+ if ($key === 0) {
247
+ $_lines[] = $prepend . $line;
248
+ } else {
249
+ $_lines[] = $pad . $line;
250
+ }
251
+ }
252
+ echo '<div class="bplog_message bplog_level_' . strtolower($_level) . '"><pre>' . join("\n", $_lines) . '</pre></div>' . "\n";
253
+ break;
254
+
255
+ case 'console':
256
+ $_lines = array();
257
+ foreach ($lines as $key => $line) {
258
+ if ($key === 0 && $prefix) {
259
+ $_lines[] = $prefix . ': ' . $line;
260
+ } else {
261
+ $_lines[] = $line;
262
+ }
263
+ }
264
+
265
+ $_lines = $ident . $_level . ' ~\n' . str_replace('\'', '\\\'', join('\n', $_lines));
266
+
267
+ if (!$this->console_javascript_loaded) {
268
+ // Queue it for logging onload
269
+ $this->console_javascript_onloads[] = array('message' => $_lines, 'level' => $level, 'time' => date('c'));
270
+ } else {
271
+ // Log it now
272
+ echo '<script type="text/javascript" charset="utf-8">bp_log_add(\'' . $this->_esc_js_log( $_lines ) . '\', ' . $this->_esc_js_log( $level ) . ', \'' . $this->_esc_js_log( date('c') ) . '\');</script>' . "\n";
273
+ }
274
+ break;
275
+ }
276
+
277
+ return true;
278
+ }
279
+
280
+ /**
281
+ * Gets the name of the log level from an integer
282
+ *
283
+ * @return string The logging level
284
+ */
285
+ function get_level_from_integer($integer)
286
+ {
287
+ switch ($integer) {
288
+ case BP_LOG_NONE:
289
+ return 'BP_LOG_NONE';
290
+ break;
291
+ case BP_LOG_FAIL:
292
+ return 'BP_LOG_FAIL';
293
+ break;
294
+ case BP_LOG_ERROR:
295
+ return 'BP_LOG_ERROR';
296
+ break;
297
+ case BP_LOG_WARNING:
298
+ return 'BP_LOG_WARNING';
299
+ break;
300
+ case BP_LOG_NOTICE:
301
+ return 'BP_LOG_NOTICE';
302
+ break;
303
+ case BP_LOG_DEBUG:
304
+ return 'BP_LOG_DEBUG';
305
+ break;
306
+ default:
307
+ return 'BP_LOG_UNDEFINED';
308
+ break;
309
+ }
310
+ }
311
+
312
+ /**
313
+ * Formats a message for output to a log file
314
+ *
315
+ * @return boolean True on success, false on failure
316
+ */
317
+ function format_message($message, $level = BP_LOG_DEBUG, $prefix = false, $tabs = 0)
318
+ {
319
+ $lines = array();
320
+
321
+ if (is_null($message)) {
322
+ $lines[] = 'null (' . var_export($message, true) . ')';
323
+ return $lines;
324
+ }
325
+
326
+ if (is_bool($message)) {
327
+ $lines[] = 'bool (' . var_export($message, true) . ')';
328
+ return $lines;
329
+ }
330
+
331
+ if (is_string($message)) {
332
+ if ($level === BP_LOG_DEBUG || $message === '') {
333
+ $lines[] = 'string(' . strlen($message) . ') ("' . $message . '")';
334
+ } else {
335
+ $lines[] = $message;
336
+ }
337
+ return $lines;
338
+ }
339
+
340
+ if (is_array($message) || is_object($message)) {
341
+ if (is_array($message)) {
342
+ $lines[] = 'array(' . count($message) . ') (';
343
+ } else {
344
+ $lines[] = 'object(' . get_class($message) . ') (';
345
+ }
346
+ $tabs++;
347
+ foreach ($message as $key => $value) {
348
+ $array = $this->format_message($value, $level, false, $tabs);
349
+ if (is_array($array)) {
350
+ $array[0] = str_repeat(' ', $tabs) . $key . ' => ' . $array[0];
351
+ $lines = array_merge($lines, $array);
352
+ } else {
353
+ $lines[] = str_repeat(' ', $tabs) . $key . ' => ' . $array;
354
+ }
355
+ }
356
+ $tabs--;
357
+ $lines[] = str_repeat(' ', $tabs) . ')';
358
+ return $lines;
359
+ }
360
+
361
+ if (is_int($message)) {
362
+ $lines[] = 'int (' . $message . ')';
363
+ return $lines;
364
+ }
365
+
366
+ if (is_float($message)) {
367
+ $lines[] = 'float (' . $message . ')';
368
+ return $lines;
369
+ }
370
+
371
+ if (is_resource($message)) {
372
+ $lines[] = 'resource (' . get_resource_type($message) . ')';
373
+ return $lines;
374
+ }
375
+
376
+ $lines[] = 'unknown (' . $message . ')';
377
+ return $lines;
378
+ }
379
+
380
+ /**
381
+ * Send a debug message
382
+ *
383
+ * @return boolean True on success, false on failure
384
+ */
385
+ function debug($message, $prefix = false)
386
+ {
387
+ $this->send($message, BP_LOG_DEBUG, false, $prefix);
388
+ }
389
+
390
+ /**
391
+ * Send a notice message
392
+ *
393
+ * If the message is an array, then it sends each index as a separate message
394
+ *
395
+ * @return boolean True on success, false on failure
396
+ */
397
+ function notice($message)
398
+ {
399
+ if (is_array($message)) {
400
+ foreach ($message as $value) {
401
+ $this->send($value, BP_LOG_NOTICE);
402
+ }
403
+ } else {
404
+ $this->send($message, BP_LOG_NOTICE);
405
+ }
406
+ }
407
+
408
+ /**
409
+ * Send a warning message
410
+ *
411
+ * If the message is an array, then it sends each index as a separate message
412
+ *
413
+ * @return boolean True on success, false on failure
414
+ */
415
+ function warning($message)
416
+ {
417
+ if (is_array($message)) {
418
+ foreach ($message as $value) {
419
+ $this->send($value, BP_LOG_WARNING);
420
+ }
421
+ } else {
422
+ $this->send($message, BP_LOG_WARNING);
423
+ }
424
+ }
425
+
426
+ /**
427
+ * Send an error message
428
+ *
429
+ * If the message is an array, then it sends each index as a separate message
430
+ *
431
+ * @return boolean True on success, false on failure
432
+ */
433
+ function error($message)
434
+ {
435
+ if (is_array($message)) {
436
+ foreach ($message as $value) {
437
+ $this->send($value, BP_LOG_ERROR);
438
+ }
439
+ } else {
440
+ $this->send($message, BP_LOG_ERROR);
441
+ }
442
+ }
443
+
444
+ /**
445
+ * Send an error message and die
446
+ *
447
+ * If the message is an array, then it sends each index as a separate message
448
+ *
449
+ * @return boolean True on success, false on failure
450
+ */
451
+ function fail($message)
452
+ {
453
+ if (is_array($message)) {
454
+ foreach ($message as $value) {
455
+ $this->send($value, BP_LOG_FAIL);
456
+ }
457
+ } else {
458
+ $this->send($message, BP_LOG_FAIL);
459
+ }
460
+
461
+ die();
462
+ }
463
+
464
+ /**
465
+ * Outputs javascript functions for the head of the html document
466
+ *
467
+ * Must be included in the head of the debug document somehow when using 'console' type.
468
+ *
469
+ * @return void
470
+ **/
471
+ function console_javascript()
472
+ {
473
+ if ($this->type !== 'console') {
474
+ return;
475
+ }
476
+
477
+ $this->console_javascript_loaded = true;
478
+ ?>
479
+
480
+ <script type="text/javascript" charset="utf-8">
481
+ var BP_LOG_NONE = 0;
482
+ var BP_LOG_FAIL = 1;
483
+ var BP_LOG_ERROR = 2;
484
+ var BP_LOG_WARNING = 4;
485
+ var BP_LOG_NOTICE = 8;
486
+ var BP_LOG_DEBUG = 16;
487
+
488
+ function bp_log_send(message, level, time) {
489
+ if (window.console) {
490
+ // Works in later Safari and Firefox with Firebug
491
+ switch (level) {
492
+ case BP_LOG_NONE:
493
+ // This shouldn't happen really
494
+ break;
495
+ case BP_LOG_FAIL:
496
+ case BP_LOG_ERROR:
497
+ window.console.error("[" + time + "] " + message);
498
+ break;
499
+ case BP_LOG_WARNING:
500
+ window.console.warn("[" + time + "] " + message);
501
+ break;
502
+ case BP_LOG_NOTICE:
503
+ window.console.info("[" + time + "] " + message);
504
+ break;
505
+ case BP_LOG_DEBUG:
506
+ window.console.log("[" + time + "] " + message);
507
+ break;
508
+ default:
509
+ break;
510
+ }
511
+ }
512
+ }
513
+
514
+ var bp_log_queue = new Array();
515
+
516
+ function bp_log_add(message, level, time) {
517
+ bp_log_queue.push(new Array(message, level, time));
518
+ }
519
+
520
+ function bp_log_process() {
521
+ while (item = bp_log_queue.shift()) {
522
+ bp_log_send(item[0], item[1], item[2]);
523
+ }
524
+ }
525
+
526
+ function bp_log_onload() {
527
+ <?php
528
+ foreach ($this->console_javascript_onloads as $onload) {
529
+ echo "\t\t\t" . 'bp_log_send(\'' . $this->_esc_js_log( $onload['message'] ) . '\', ' . $this->_esc_js_log( $onload['level'] ) . ', \'' . $this->_esc_js_log( $onload['time'] ) . '\');' . "\n";
530
+ }
531
+ ?>
532
+ bp_log_process();
533
+ }
534
+
535
+ window.onload = bp_log_onload;
536
+ </script>
537
+
538
+ <?php
539
+ }
540
+
541
+ function _esc_js_log( $message )
542
+ {
543
+ return str_replace(
544
+ array( '\'', "\n" ),
545
+ array( '\\\'', '\n' ),
546
+ $message
547
+ );
548
+ }
549
+
550
+ } // END class BP_Log
bp-forums/bbpress/bb-includes/backpress/class.bp-roles.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class BP_Roles {
4
+ var $role_objects = array();
5
+ var $role_names = array();
6
+
7
+ function BP_Roles() {
8
+ $this->__construct();
9
+ }
10
+
11
+ function __construct() {
12
+ do_action_ref_array('init_roles', array(&$this) );
13
+ }
14
+
15
+ function add_role($role, $display_name, $capabilities = '') {
16
+ if ( isset($this->role_objects[$role]) )
17
+ return;
18
+
19
+ $this->role_objects[$role] = new BP_Role($role, $capabilities, $this);
20
+ $this->role_names[$role] = $display_name;
21
+ return $this->role_objects[$role];
22
+ }
23
+
24
+ function remove_role($role) {
25
+ if ( ! isset($this->role_objects[$role]) )
26
+ return;
27
+
28
+ unset($this->role_objects[$role]);
29
+ unset($this->role_names[$role]);
30
+ }
31
+
32
+ function add_cap($role, $cap, $grant = true) {
33
+ if ( isset($this->role_objects[$role]) )
34
+ $this->role_objects[$role]->add_cap($cap, $grant);
35
+ }
36
+
37
+ function remove_cap($role, $cap) {
38
+ if ( isset($this->role_objects[$role]) )
39
+ $this->role_objects[$role]->remove_cap($cap, $grant);
40
+ }
41
+
42
+ function &get_role($role) {
43
+ if ( isset($this->role_objects[$role]) )
44
+ return $this->role_objects[$role];
45
+ else
46
+ return null;
47
+ }
48
+
49
+ function get_names() {
50
+ return $this->role_names;
51
+ }
52
+
53
+ function is_role($role) {
54
+ return isset($this->role_names[$role]);
55
+ }
56
+
57
+ function map_meta_cap( $cap, $user_id ) {
58
+ $args = array_slice(func_get_args(), 2);
59
+ return apply_filters( 'map_meta_cap', array( $cap ), $cap, $user_id, $args );
60
+ }
61
+ }
62
+
63
+ class BP_Role {
64
+ var $name;
65
+ var $capabilities;
66
+
67
+ function BP_Role($role, $capabilities) {
68
+ $this->name = $role;
69
+ $this->capabilities = $capabilities;
70
+ }
71
+
72
+ function add_cap($cap, $grant = true) {
73
+ $this->capabilities[$cap] = $grant;
74
+ }
75
+
76
+ function remove_cap($cap) {
77
+ unset($this->capabilities[$cap]);
78
+ }
79
+
80
+ function has_cap($cap) {
81
+ $capabilities = apply_filters('role_has_cap', $this->capabilities, $cap, $this->name);
82
+ $grant = !empty( $capabilities[$cap] );
83
+ return apply_filters("{$this->name}_has_cap", $grant);
84
+ }
85
+
86
+ }
bp-forums/bbpress/bb-includes/backpress/class.bp-sql-schema-parser.php ADDED
@@ -0,0 +1,615 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Parses SQL schema statements for comparison to real table structures
4
+ *
5
+ * @package BackPress
6
+ **/
7
+ class BP_SQL_Schema_Parser
8
+ {
9
+ /**
10
+ * Builds a column definition as used in CREATE TABLE statements from
11
+ * an array such as those returned by DESCRIBE `foo` statements
12
+ */
13
+ function get_column_definition( $column_data )
14
+ {
15
+ if ( !is_array( $column_data ) ) {
16
+ return $column_data;
17
+ }
18
+
19
+ $null = '';
20
+ if ( $column_data['Null'] == 'NO' ) {
21
+ $null = 'NOT NULL';
22
+ }
23
+
24
+ $default = '';
25
+
26
+ // Defaults aren't allowed at all on certain column types
27
+ if ( !in_array(
28
+ strtolower( $column_data['Type'] ),
29
+ array( 'tinytext', 'text', 'mediumtext', 'longtext', 'blob', 'mediumblob', 'longblob' )
30
+ ) ) {
31
+ if ( $column_data['Null'] == 'YES' && $column_data['Default'] === null ) {
32
+ $default = 'default NULL';
33
+ } elseif ( preg_match( '@^\d+$@', $column_data['Default'] ) ) {
34
+ $default = 'default ' . $column_data['Default'];
35
+ } elseif ( is_string( $column_data['Default'] ) || is_float( $column_data['Default'] ) ) {
36
+ $default = 'default \'' . $column_data['Default'] . '\'';
37
+ }
38
+ }
39
+
40
+ $column_definition = '`' . $column_data['Field'] . '` ' . $column_data['Type'] . ' ' . $null . ' ' . $column_data['Extra'] . ' ' . $default;
41
+ return preg_replace( '@\s+@', ' ', trim( $column_definition ) );
42
+ }
43
+
44
+ /**
45
+ * Builds an index definition as used in CREATE TABLE statements from
46
+ * an array similar to those returned by SHOW INDEX FROM `foo` statements
47
+ */
48
+ function get_index_definition( $index_data )
49
+ {
50
+ if ( !is_array( $index_data ) ) {
51
+ return $index_data;
52
+ }
53
+
54
+ if ( !count( $index_data ) ) {
55
+ return $index_data;
56
+ }
57
+
58
+ $_name = '`' . $index_data[0]['Key_name'] . '`';
59
+
60
+ if ( $index_data[0]['Index_type'] == 'BTREE' && $index_data[0]['Key_name'] == 'PRIMARY' ) {
61
+ $_type = 'PRIMARY KEY';
62
+ $_name = '';
63
+ } elseif ( $index_data[0]['Index_type'] == 'BTREE' && !$index_data[0]['Non_unique'] ) {
64
+ $_type = 'UNIQUE KEY';
65
+ } elseif ( $index_data[0]['Index_type'] == 'FULLTEXT' ) {
66
+ $_type = 'FULLTEXT KEY';
67
+ } else {
68
+ $_type = 'KEY';
69
+ }
70
+
71
+ $_columns = array();
72
+ foreach ( $index_data as $_index ) {
73
+ if ( $_index['Sub_part'] ) {
74
+ $_columns[] = '`' . $_index['Column_name'] . '`(' . $_index['Sub_part'] . ')';
75
+ } else {
76
+ $_columns[] = '`' . $_index['Column_name'] . '`';
77
+ }
78
+ }
79
+ $_columns = join( ', ', $_columns );
80
+
81
+ $index_definition = $_type . ' ' . $_name . ' (' . $_columns . ')';
82
+ return preg_replace( '@\s+@', ' ', $index_definition );
83
+ }
84
+
85
+ /**
86
+ * Returns a table structure from a raw sql query of the form "CREATE TABLE foo" etc.
87
+ * The resulting array contains the original query, the columns as would be returned by DESCRIBE `foo`
88
+ * and the indices as would be returned by SHOW INDEX FROM `foo` on a real table
89
+ */
90
+ function describe_table( $query )
91
+ {
92
+ // Retrieve the table structure from the query
93
+ if ( !preg_match( '@^CREATE\s+TABLE(\s+IF\s+NOT\s+EXISTS)?\s+`?([^\s|`]+)`?\s+\((.*)\)\s*([^\)|;]*)\s*;?@ims', $query, $_matches ) ) {
94
+ return $query;
95
+ }
96
+
97
+ $_if_not_exists = $_matches[1];
98
+
99
+ // Tidy up the table name
100
+ $_table_name = trim( $_matches[2] );
101
+
102
+ // Tidy up the table columns/indices
103
+ $_columns_indices = trim( $_matches[3], " \t\n\r\0\x0B," );
104
+ // Split by commas not followed by a closing parenthesis ")", using fancy lookaheads
105
+ $_columns_indices = preg_split( '@,(?!(?:[^\(]+\)))@ms', $_columns_indices );
106
+ $_columns_indices = array_map( 'trim', $_columns_indices );
107
+
108
+ // Tidy the table attributes
109
+ $_attributes = preg_replace( '@\s+@', ' ', trim( $_matches[4] ) );
110
+ unset( $_matches );
111
+
112
+ // Initialise some temporary arrays
113
+ $_columns = array();
114
+ $_indices = array();
115
+
116
+ // Loop over the columns/indices
117
+ foreach ( $_columns_indices as $_column_index ) {
118
+ if ( preg_match( '@^(PRIMARY\s+KEY|UNIQUE\s+(?:KEY|INDEX)|FULLTEXT\s+(?:KEY|INDEX)|KEY|INDEX)\s+(?:`?(\w+)`?\s+)*\((.+?)\)$@im', $_column_index, $_matches ) ) {
119
+ // It's an index
120
+
121
+ // Tidy the type
122
+ $_index_type = strtoupper( preg_replace( '@\s+@', ' ', trim( $_matches[1] ) ) );
123
+ $_index_type = str_replace( 'INDEX', 'KEY', $_index_type );
124
+ // Set the index name
125
+ $_index_name = ( 'PRIMARY KEY' == $_matches[1] ) ? 'PRIMARY' : $_matches[2];
126
+ // Split into columns
127
+ $_index_columns = array_map( 'trim', explode( ',', $_matches[3] ) );
128
+
129
+ foreach ( $_index_columns as $_index_columns_index => $_index_column ) {
130
+ preg_match( '@`?(\w+)`?(?:\s*\(\s*(\d+)\s*\))?@i', $_index_column, $_matches_column );
131
+
132
+ $_indices[$_index_name][] = array(
133
+ 'Table' => $_table_name,
134
+ 'Non_unique' => ( 'UNIQUE KEY' == $_index_type || 'PRIMARY' == $_index_name ) ? '0' : '1',
135
+ 'Key_name' => $_index_name,
136
+ 'Seq_in_index' => (string) ( $_index_columns_index + 1 ),
137
+ 'Column_name' => $_matches_column[1],
138
+ 'Sub_part' => ( isset( $_matches_column[2] ) && $_matches_column[2] ) ? $_matches_column[2] : null,
139
+ 'Index_type' => ( 'FULLTEXT KEY' == $_index_type ) ? 'FULLTEXT' : 'BTREE'
140
+ );
141
+ }
142
+ unset( $_index_type, $_index_name, $_index_columns, $_index_columns_index, $_index_column, $_matches_column );
143
+
144
+ } elseif ( preg_match( "@^`?(\w+)`?\s+(?:(\w+)(?:\s*\(\s*(\d+)\s*\))?(?:\s+(unsigned)){0,1})(?:\s+(NOT\s+NULL))?(?:\s+(auto_increment))?(?:\s+(default)\s+(?:(NULL|'[^']*'|\d+)))?@im", $_column_index, $_matches ) ) {
145
+ // It's a column
146
+
147
+ // Tidy the NOT NULL
148
+ $_matches[5] = isset( $_matches[5] ) ? strtoupper( preg_replace( '@\s+@', ' ', trim( $_matches[5] ) ) ) : '';
149
+
150
+ $_columns[$_matches[1]] = array(
151
+ 'Field' => $_matches[1],
152
+ 'Type' => ( is_numeric( $_matches[3] ) ) ? $_matches[2] . '(' . $_matches[3] . ')' . ( ( isset( $_matches[4] ) && strtolower( $_matches[4] ) == 'unsigned' ) ? ' unsigned' : '' ) : $_matches[2],
153
+ 'Null' => ( 'NOT NULL' == strtoupper( $_matches[5] ) ) ? 'NO' : 'YES',
154
+ 'Default' => ( isset( $_matches[7] ) && 'default' == strtolower( $_matches[7] ) && 'NULL' !== strtoupper( $_matches[8] ) ) ? trim( $_matches[8], "'" ) : null,
155
+ 'Extra' => ( isset( $_matches[6] ) && 'auto_increment' == strtolower( $_matches[6] ) ) ? 'auto_increment' : ''
156
+ );
157
+ }
158
+ }
159
+ unset( $_matches, $_columns_indices, $_column_index );
160
+
161
+ // Tidy up the original query
162
+ $_tidy_query = 'CREATE TABLE';
163
+ if ( $_if_not_exists ) {
164
+ $_tidy_query .= ' IF NOT EXISTS';
165
+ }
166
+ $_tidy_query .= ' `' . $_table_name . '` (' . "\n";
167
+ foreach ( $_columns as $_column ) {
168
+ $_tidy_query .= "\t" . BP_SQL_Schema_Parser::get_column_definition( $_column ) . ",\n";
169
+ }
170
+ unset( $_column );
171
+ foreach ( $_indices as $_index ) {
172
+ $_tidy_query .= "\t" . BP_SQL_Schema_Parser::get_index_definition( $_index ) . ",\n";
173
+ }
174
+ $_tidy_query = substr( $_tidy_query, 0, -2 ) . "\n" . ') ' . $_attributes . ';';
175
+
176
+ // Add to the query array using the table name as the index
177
+ $description = array(
178
+ 'query_original' => $query,
179
+ 'query_tidy' => $_tidy_query,
180
+ 'columns' => $_columns,
181
+ 'indices' => $_indices
182
+ );
183
+ unset( $_table_name, $_columns, $_indices, $_tidy_query );
184
+
185
+ return $description;
186
+ }
187
+
188
+ /**
189
+ * Helper function to flatten arrays
190
+ */
191
+ function _flatten_array( $array, $cut_branch = 0, $keep_child_array_keys = true )
192
+ {
193
+ if ( !is_array( $array ) ) {
194
+ return $array;
195
+ }
196
+
197
+ if ( empty( $array ) ) {
198
+ return null;
199
+ }
200
+
201
+ $temp = array();
202
+ foreach ( $array as $k => $v ) {
203
+ if ( $cut_branch && $k == $cut_branch )
204
+ continue;
205
+ if ( is_array( $v ) ) {
206
+ if ( $keep_child_array_keys ) {
207
+ $temp[$k] = true;
208
+ }
209
+ $temp += BP_SQL_Schema_Parser::_flatten_array( $v, $cut_branch, $keep_child_array_keys );
210
+ } else {
211
+ $temp[$k] = $v;
212
+ }
213
+ }
214
+ return $temp;
215
+ }
216
+
217
+ /**
218
+ * Splits grouped SQL statements into queries within a highly structured array
219
+ * Only supports CREATE TABLE, INSERT and UPDATE
220
+ */
221
+ function parse( $sql )
222
+ {
223
+ // Only accept strings or arrays
224
+ if ( is_string( $sql ) ) {
225
+ // Just pop strings into an array to start with
226
+ $queries = array( $sql );
227
+ } elseif ( is_array( $sql ) ) {
228
+ // Flatten the array
229
+ $queries = BP_SQL_Schema_Parser::_flatten_array( $sql, 0, false );
230
+ // Remove empty nodes
231
+ $queries = array_filter( $queries );
232
+ } else {
233
+ return false;
234
+ }
235
+
236
+ // Clean up the queries
237
+ $_clean_queries = array();
238
+ foreach ( $queries as $_query ) {
239
+ // Trim space and semi-colons
240
+ $_query = trim( $_query, "; \t\n\r\0\x0B" );
241
+ // If it exists and isn't a number
242
+ if ( $_query && !is_numeric( $_query ) ) {
243
+ // Is it more than one query?
244
+ if ( strpos( ';', $_query ) !== false ) {
245
+ // Explode by semi-colon
246
+ foreach ( explode( ';', $_query ) as $_part ) {
247
+ $_part = trim( $_part );
248
+ if ( $_part && !is_numeric( $_part ) ) {
249
+ // Pull out any commented code
250
+ // Can't properly deal with /*!4321 FOO `bar` */ version specific inclusion, just includes it regardless of version
251
+ $_part = preg_replace( '@/\*![0-9]*([^\*]*)\*/@', '$1', $_part );
252
+ $_part = preg_replace( '@/\*[^\*]*\*/@', '', $_part );
253
+ $_part = preg_replace( '@[\-\-|#].*$@m', '', $_part );
254
+ $_clean_queries[] = trim( $_part ) . ';';
255
+ }
256
+ }
257
+ unset( $_part );
258
+ } else {
259
+ $_clean_queries[] = $_query . ';';
260
+ }
261
+ }
262
+ }
263
+ unset( $_query );
264
+ if ( !count( $_clean_queries ) ) {
265
+ return false;
266
+ }
267
+ $queries = $_clean_queries;
268
+ unset( $_clean_queries );
269
+
270
+ $_queries = array();
271
+ foreach ( $queries as $_query ) {
272
+ // Only process table creation, inserts and updates, capture the table/database name while we are at it
273
+ if ( !preg_match( '@^(CREATE\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?|INSERT\s+INTO|UPDATE)\s+`?([^\s|`]+)`?@im', $_query, $_matches ) ) {
274
+ continue;
275
+ }
276
+
277
+ // Tidy up the type so we can switch it
278
+ $_type = strtoupper( preg_replace( '@\s+@', ' ', trim( $_matches[1] ) ) );
279
+ $_table_name = trim( $_matches[2] );
280
+ unset( $_matches );
281
+
282
+ switch ( $_type ) {
283
+ case 'CREATE TABLE':
284
+ case 'CREATE TABLE IF NOT EXISTS':
285
+ $_description = BP_SQL_Schema_Parser::describe_table( $_query );
286
+ if ( is_array( $_description ) ) {
287
+ $_queries['tables'][$_table_name] = $_description;
288
+ }
289
+ break;
290
+
291
+ case 'INSERT INTO':
292
+ // Just add the query as is for now
293
+ $_queries['insert'][$_table_name][] = $_query;
294
+ break;
295
+
296
+ case 'UPDATE':
297
+ // Just add the query as is for now
298
+ $_queries['update'][$_table_name][] = $_query;
299
+ break;
300
+ }
301
+ unset( $_type, $_table_name );
302
+ }
303
+ unset( $_query );
304
+
305
+ if ( !count( $_queries ) ) {
306
+ return false;
307
+ }
308
+ return $_queries;
309
+ }
310
+
311
+ /**
312
+ * Evaluates the difference between a given set of SQL queries and real database structure
313
+ */
314
+ function delta( $db_object, $queries, $ignore = false, $execute = true )
315
+ {
316
+ if ( !$db_object || !is_object( $db_object ) || !( is_a( $db_object, 'BPDB' ) || is_a( $db_object, 'BPDB_Multi' ) || is_a( $db_object, 'BPDB_Hyper' ) ) ) {
317
+ return __( 'Passed variable is not a BackPress database object.' );
318
+ }
319
+
320
+ if ( !$_queries = BP_SQL_Schema_Parser::parse( $queries ) ) {
321
+ return __( 'No schema available.' );
322
+ }
323
+
324
+ // Set up default elements to ignore
325
+ $ignore_defaults = array(
326
+ 'tables' => array(), // Just a list of tablenames, including prefix. Does not affect INSERT and UPDATE queries.
327
+ 'columns' => array(), // Arrays of column names, keyed with the table names, including prefix.
328
+ 'indices' => array() // Arrays of index names, keyed with the table names, including prefix.
329
+ );
330
+
331
+ // Add the elements to ignore that were passed to the function
332
+ if ( !$ignore || !is_array( $ignore ) ) {
333
+ $ignore = $ignore_defaults;
334
+ } else {
335
+ if ( isset( $ignore['tables'] ) && is_array( $ignore['tables'] ) ) {
336
+ $ignore['tables'] = array_merge( $ignore_defaults['tables'], $ignore['tables'] );
337
+ }
338
+ if ( isset( $ignore['columns'] ) && is_array( $ignore['columns'] ) ) {
339
+ $ignore['columns'] = array_merge( $ignore_defaults['columns'], $ignore['columns'] );
340
+ }
341
+ if ( isset( $ignore['indices'] ) && is_array( $ignore['indices'] ) ) {
342
+ $ignore['indices'] = array_merge( $ignore_defaults['indices'], $ignore['indices'] );
343
+ }
344
+ }
345
+
346
+ // Build an array of $db_object registered tables and their database identifiers
347
+ $_tables = $db_object->tables;
348
+ $db_object_tables = array();
349
+ foreach ( $_tables as $_table_id => $_table_name ) {
350
+ if ( is_array( $_table_name ) && isset( $db_object->db_servers['dbh_' . $_table_name[0]] ) ) {
351
+ $db_object_tables[$db_object->$_table_id] = 'dbh_' . $_table_name[0];
352
+ } else {
353
+ $db_object_tables[$db_object->$_table_id] = 'dbh_global';
354
+ }
355
+ }
356
+ unset( $_tables, $_table_id, $_table_name );
357
+
358
+ $alterations = array();
359
+
360
+ // Loop through table queries
361
+ if ( isset( $_queries['tables'] ) ) {
362
+ foreach ( $_queries['tables'] as $_new_table_name => $_new_table_data ) {
363
+ if ( in_array( $_new_table_name, $ignore['tables'] ) ) {
364
+ continue;
365
+ }
366
+
367
+ // See if the table is custom and registered in $db_object under a custom database
368
+ if (
369
+ isset( $db_object_tables[$_new_table_name] ) &&
370
+ $db_object_tables[$_new_table_name] != 'dbh_global' &&
371
+ isset( $db_object->db_servers[$db_object_tables[$_new_table_name]]['ds'] )
372
+ ) {
373
+ // Force the database connection
374
+ $_dbhname = $db_object->db_servers[$db_object_tables[$_new_table_name]]['ds'];
375
+ $db_object->_force_dbhname = $_dbhname;
376
+ } else {
377
+ $_dbhname = 'dbh_global';
378
+ }
379
+
380
+ // Fetch the existing table column structure from the database
381
+ $db_object->suppress_errors();
382
+ if ( !$_existing_table_columns = $db_object->get_results( 'DESCRIBE `' . $_new_table_name . '`;', ARRAY_A ) ) {
383
+ $db_object->suppress_errors( false );
384
+ // The table doesn't exist, add it and then continue to the next table
385
+ $alterations[$_dbhname][$_new_table_name][] = array(
386
+ 'action' => 'create_table',
387
+ 'message' => __( 'Creating table' ),
388
+ 'query' => $_new_table_data['query_tidy']
389
+ );
390
+ continue;
391
+ }
392
+ $db_object->suppress_errors( false );
393
+
394
+ // Add an index to the existing columns array
395
+ $__existing_table_columns = array();
396
+ foreach ( $_existing_table_columns as $_existing_table_column ) {
397
+ // Remove 'Key' from returned column structure
398
+ unset( $_existing_table_column['Key'] );
399
+ $__existing_table_columns[$_existing_table_column['Field']] = $_existing_table_column;
400
+ }
401
+ $_existing_table_columns = $__existing_table_columns;
402
+ unset( $__existing_table_columns );
403
+
404
+ // Loop over the columns in this table and look for differences
405
+ foreach ( $_new_table_data['columns'] as $_new_column_name => $_new_column_data ) {
406
+ if ( isset( $ignore['columns'][$_new_table_name] ) && in_array( $_new_column_name, $ignore['columns'][$_new_table_name] ) ) {
407
+ continue;
408
+ }
409
+
410
+ if ( !in_array( $_new_column_data, $_existing_table_columns ) ) {
411
+ // There is a difference
412
+ if ( !isset( $_existing_table_columns[$_new_column_name] ) ) {
413
+ // The column doesn't exist, so add it
414
+ $alterations[$_dbhname][$_new_table_name][] = array(
415
+ 'action' => 'add_column',
416
+ 'message' => sprintf( __( 'Adding column: %s' ), $_new_column_name ),
417
+ 'column' => $_new_column_name,
418
+ 'query' => 'ALTER TABLE `' . $_new_table_name . '` ADD COLUMN ' . BP_SQL_Schema_Parser::get_column_definition( $_new_column_data ) . ';'
419
+ );
420
+ continue;
421
+ }
422
+
423
+ // Adjust defaults on columns that allow defaults
424
+ if (
425
+ $_new_column_data['Default'] !== $_existing_table_columns[$_new_column_name]['Default'] &&
426
+ !in_array(
427
+ strtolower( $_new_column_data['Type'] ),
428
+ array( 'tinytext', 'text', 'mediumtext', 'longtext', 'blob', 'mediumblob', 'longblob' )
429
+ )
430
+ ) {
431
+ // Change the default value for the column
432
+ $alterations[$_dbhname][$_new_table_name][] = array(
433
+ 'action' => 'set_default',
434
+ 'message' => sprintf( __( 'Setting default on column: %s' ), $_new_column_name ),
435
+ 'column' => $_new_column_name,
436
+ 'query' => 'ALTER TABLE `' . $_new_table_name . '` ALTER COLUMN `' . $_new_column_name . '` SET DEFAULT \'' . $_new_column_data['Default'] . '\';'
437
+ );
438
+ // Don't continue, overwrite this if the next conditional is met
439
+ }
440
+
441
+ if (
442
+ $_new_column_data['Type'] !== $_existing_table_columns[$_new_column_name]['Type'] ||
443
+ $_new_column_data['Null'] !== $_existing_table_columns[$_new_column_name]['Null'] ||
444
+ $_new_column_data['Extra'] !== $_existing_table_columns[$_new_column_name]['Extra']
445
+ ) {
446
+ // Change the structure for the column
447
+ $alterations[$_dbhname][$_new_table_name][] = array(
448
+ 'action' => 'change_column',
449
+ 'message' => sprintf( __( 'Changing column: %s' ), $_new_column_name ),
450
+ 'column' => $_new_column_name,
451
+ 'query' => 'ALTER TABLE `' . $_new_table_name . '` CHANGE COLUMN `' . $_new_column_name . '` ' . BP_SQL_Schema_Parser::get_column_definition( $_new_column_data ) . ';'
452
+ );
453
+ }
454
+ }
455
+ }
456
+ unset( $_existing_table_columns, $_new_column_name, $_new_column_data );
457
+
458
+ // Fetch the table index structure from the database
459
+ if ( !$_existing_table_indices = $db_object->get_results( 'SHOW INDEX FROM `' . $_new_table_name . '`;', ARRAY_A ) ) {
460
+ continue;
461
+ }
462
+
463
+ // Add an index to the existing columns array and organise by index name
464
+ $__existing_table_indices = array();
465
+ foreach ( $_existing_table_indices as $_existing_table_index ) {
466
+ // Remove unused parts from returned index structure
467
+ unset(
468
+ $_existing_table_index['Collation'],
469
+ $_existing_table_index['Cardinality'],
470
+ $_existing_table_index['Packed'],
471
+ $_existing_table_index['Null'],
472
+ $_existing_table_index['Comment']
473
+ );
474
+ $__existing_table_indices[$_existing_table_index['Key_name']][] = $_existing_table_index;
475
+ }
476
+ $_existing_table_indices = $__existing_table_indices;
477
+ unset( $__existing_table_indices );
478
+
479
+ // Loop over the indices in this table and look for differences
480
+ foreach ( $_new_table_data['indices'] as $_new_index_name => $_new_index_data ) {
481
+ if ( isset( $ignore['indices'][$_new_table_name] ) && in_array( $_new_index_name, $ignore['indices'][$_new_table_name] ) ) {
482
+ continue;
483
+ }
484
+
485
+ if ( !in_array( $_new_index_data, $_existing_table_indices ) ) {
486
+ // There is a difference
487
+ if ( !isset( $_existing_table_indices[$_new_index_name] ) ) {
488
+ // The index doesn't exist, so add it
489
+ $alterations[$_dbhname][$_new_table_name][] = array(
490
+ 'action' => 'add_index',
491
+ 'message' => sprintf( __( 'Adding index: %s' ), $_new_index_name ),
492
+ 'index' => $_new_index_name,
493
+ 'query' => 'ALTER TABLE `' . $_new_table_name . '` ADD ' . BP_SQL_Schema_Parser::get_index_definition( $_new_index_data ) . ';'
494
+ );
495
+ continue;
496
+ }
497
+
498
+ if ( $_new_index_data !== $_existing_table_indices[$_new_index_name] ) {
499
+ // The index is incorrect, so drop it and add the new one
500
+ if ( $_new_index_name == 'PRIMARY' ) {
501
+ $_drop_index_name = 'PRIMARY KEY';
502
+ } else {
503
+ $_drop_index_name = 'INDEX `' . $_new_index_name . '`';
504
+ }
505
+ $alterations[$_dbhname][$_new_table_name][] = array(
506
+ 'action' => 'drop_index',
507
+ 'message' => sprintf( __( 'Dropping index: %s' ), $_new_index_name ),
508
+ 'index' => $_new_index_name,
509
+ 'query' => 'ALTER TABLE `' . $_new_table_name . '` DROP ' . $_drop_index_name . ';'
510
+ );
511
+ unset( $_drop_index_name );
512
+ $alterations[$_dbhname][$_new_table_name][] = array(
513
+ 'action' => 'add_index',
514
+ 'message' => sprintf( __( 'Adding index: %s' ), $_new_index_name ),
515
+ 'index' => $_new_index_name,
516
+ 'query' => 'ALTER TABLE `' . $_new_table_name . '` ADD ' . BP_SQL_Schema_Parser::get_index_definition( $_new_index_data ) . ';'
517
+ );
518
+ }
519
+ }
520
+ }
521
+ unset( $_new_index_name, $_new_index_data );
522
+
523
+ // Go back to the default database connection
524
+ $db_object->_force_dbhname = false;
525
+ }
526
+ unset( $_new_table_name, $_new_table_data, $_dbhname );
527
+ }
528
+
529
+ // Now deal with the sundry INSERT and UPDATE statements (if any)
530
+ if ( isset( $_queries['insert'] ) && is_array( $_queries['insert'] ) && count( $_queries['insert'] ) ) {
531
+ foreach ( $_queries['insert'] as $_table_name => $_inserts ) {
532
+ foreach ( $_inserts as $_insert ) {
533
+ $alterations['dbh_global'][$_table_name][] = array(
534
+ 'action' => 'insert',
535
+ 'message' => __( 'Inserting data' ),
536
+ 'query' => $_insert
537
+ );
538
+ }
539
+ unset( $_insert );
540
+ }
541
+ unset( $_table_name, $_inserts );
542
+ }
543
+ if ( isset( $_queries['update'] ) && is_array( $_queries['update'] ) && count( $_queries['update'] ) ) {
544
+ foreach ( $_queries['update'] as $_table_name => $_updates ) {
545
+ foreach ( $_updates as $_update ) {
546
+ $alterations['dbh_global'][$_table_name][] = array(
547
+ 'action' => 'update',
548
+ 'message' => __( 'Updating data' ),
549
+ 'query' => $_update
550
+ );
551
+ }
552
+ unset( $_update );
553
+ }
554
+ unset( $_table_name, $_updates );
555
+ }
556
+
557
+ // Initialise an array to hold the output messages
558
+ $messages = array();
559
+ $errors = array();
560
+
561
+ foreach ( $alterations as $_dbhname => $_tables ) {
562
+ // Force the database connection (this was already checked to be valid in the previous loop)
563
+ $db_object->_force_dbhname = $_dbhname;
564
+
565
+ // Note the database in the return messages
566
+ $messages[] = '>>> ' . sprintf( __( 'Modifying database: %s (%s)' ), $db_object->db_servers[$_dbhname]['name'], $db_object->db_servers[$_dbhname]['host'] );
567
+
568
+ foreach ( $_tables as $_table_name => $_alterations ) {
569
+ // Note the table in the return messages
570
+ $messages[] = '>>>>>> ' . sprintf( __( 'Table: %s' ), $_table_name );
571
+
572
+ foreach ( $_alterations as $_alteration ) {
573
+ // If there is no query, then skip
574
+ if ( !$_alteration['query'] ) {
575
+ continue;
576
+ }
577
+
578
+ // Note the action in the return messages
579
+ $messages[] = '>>>>>>>>> ' . $_alteration['message'];
580
+
581
+ if ( !$execute ) {
582
+ $messages[] = '>>>>>>>>>>>> ' . __( 'Skipped' );
583
+ continue;
584
+ }
585
+
586
+ // Run the query
587
+ $_result = $db_object->query( $_alteration['query'] );
588
+ $_result_error = $db_object->get_error();
589
+
590
+ if ( $_result_error ) {
591
+ // There was an error
592
+ $_result =& $_result_error;
593
+ unset( $_result_error );
594
+ $messages[] = '>>>>>>>>>>>> ' . __( 'SQL ERROR! See the error log for more detail' );
595
+ $errors[] = __( 'SQL ERROR!' );
596
+ $errors[] = '>>> ' . sprintf( __( 'Database: %s (%s)' ), $db_object->db_servers[$_dbhname]['name'], $db_object->db_servers[$_dbhname]['host'] );
597
+ $errors[] = '>>>>>> ' . $_result->error_data['db_query']['query'];
598
+ $errors[] = '>>>>>> ' . $_result->error_data['db_query']['error'];
599
+ } else {
600
+ $messages[] = '>>>>>>>>>>>> ' . __( 'Done' );
601
+ }
602
+ unset( $_result );
603
+ }
604
+ unset( $_alteration );
605
+ }
606
+ unset( $_table_name, $_alterations );
607
+ }
608
+ unset( $_dbhname, $_tables );
609
+
610
+ // Reset the database connection
611
+ $db_object->_force_dbhname = false;
612
+
613
+ return array( 'messages' => $messages, 'errors' => $errors );
614
+ }
615
+ } // END class BP_SQL_Schema_Parser
bp-forums/bbpress/bb-includes/backpress/class.bp-user.php ADDED
@@ -0,0 +1,398 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Last sync [WP11537]
3
+
4
+ /**
5
+ * BackPress User class.
6
+ *
7
+ * @since 2.0.0
8
+ * @package BackPress
9
+ * @subpackage User
10
+ */
11
+ class BP_User {
12
+ /**
13
+ * User data container.
14
+ *
15
+ * This will be set as properties of the object.
16
+ *
17
+ * @since 2.0.0
18
+ * @access private
19
+ * @var array
20
+ */
21
+ var $data;
22
+
23
+ /**
24
+ * The user's ID.
25
+ *
26
+ * @since 2.1.0
27
+ * @access public
28
+ * @var int
29
+ */
30
+ var $ID = 0;
31
+
32
+ /**
33
+ * The deprecated user's ID.
34
+ *
35
+ * @since 2.0.0
36
+ * @access public
37
+ * @deprecated Use BP_User::$ID
38
+ * @see BP_User::$ID
39
+ * @var int
40
+ */
41
+ var $id = 0;
42
+
43
+ /**
44
+ * The individual capabilities the user has been given.
45
+ *
46
+ * @since 2.0.0
47
+ * @access public
48
+ * @var array
49
+ */
50
+ var $caps = array();
51
+
52
+ /**
53
+ * User metadata option name.
54
+ *
55
+ * @since 2.0.0
56
+ * @access public
57
+ * @var string
58
+ */
59
+ var $cap_key;
60
+
61
+ /**
62
+ * The roles the user is part of.
63
+ *
64
+ * @since 2.0.0
65
+ * @access public
66
+ * @var array
67
+ */
68
+ var $roles = array();
69
+
70
+ /**
71
+ * All capabilities the user has, including individual and role based.
72
+ *
73
+ * @since 2.0.0
74
+ * @access public
75
+ * @var array
76
+ */
77
+ var $allcaps = array();
78
+
79
+ /**
80
+ * First name of the user.
81
+ *
82
+ * Created to prevent notices.
83
+ *
84
+ * @since 2.7.0
85
+ * @access public
86
+ * @var string
87
+ */
88
+ var $first_name = '';
89
+
90
+ /**
91
+ * Last name of the user.
92
+ *
93
+ * Created to prevent notices.
94
+ *
95
+ * @since 2.7.0
96
+ * @access public
97
+ * @var string
98
+ */
99
+ var $last_name = '';
100
+
101
+ /**
102
+ * PHP4 Constructor - Sets up the object properties.
103
+ *
104
+ * Retrieves the userdata and then assigns all of the data keys to direct
105
+ * properties of the object. Calls {@link BP_User::_init_caps()} after
106
+ * setting up the object's user data properties.
107
+ *
108
+ * @since 2.0.0
109
+ * @access public
110
+ *
111
+ * @param int|string $id User's ID or username
112
+ * @param int $name Optional. User's username
113
+ * @return BP_User
114
+ */
115
+ function BP_User( $id, $name = '' ) {
116
+ global $wp_users_object;
117
+
118
+ if ( empty( $id ) && empty( $name ) )
119
+ return;
120
+
121
+ if ( ! is_numeric( $id ) ) {
122
+ $name = $id;
123
+ $id = 0;
124
+ }
125
+
126
+ if ( ! empty( $id ) )
127
+ $this->data = $wp_users_object->get_user( $id );
128
+ else
129
+ $this->data = $wp_users_object->get_user( $name, array( 'by' => 'login' ) );
130
+
131
+ if ( empty( $this->data->ID ) )
132
+ return;
133
+
134
+ foreach ( get_object_vars( $this->data ) as $key => $value ) {
135
+ $this->{$key} = $value;
136
+ }
137
+
138
+ $this->id = $this->ID;
139
+ $this->_init_caps();
140
+ }
141
+
142
+ /**
143
+ * Setup capability object properties.
144
+ *
145
+ * Will set the value for the 'cap_key' property to current database table
146
+ * prefix, followed by 'capabilities'. Will then check to see if the
147
+ * property matching the 'cap_key' exists and is an array. If so, it will be
148
+ * used.
149
+ *
150
+ * @since 2.1.0
151
+ * @access protected
152
+ */
153
+ function _init_caps() {
154
+ global $wp_users_object;
155
+ $this->cap_key = $wp_users_object->db->prefix . 'capabilities';
156
+ $this->caps = &$this->{$this->cap_key};
157
+ if ( ! is_array( $this->caps ) )
158
+ $this->caps = array();
159
+ $this->get_role_caps();
160
+ }
161
+
162
+ /**
163
+ * Retrieve all of the role capabilities and merge with individual capabilities.
164
+ *
165
+ * All of the capabilities of the roles the user belongs to are merged with
166
+ * the users individual roles. This also means that the user can be denied
167
+ * specific roles that their role might have, but the specific user isn't
168
+ * granted permission to.
169
+ *
170
+ * @since 2.0.0
171
+ * @uses $wp_roles
172
+ * @access public
173
+ */
174
+ function get_role_caps() {
175
+ global $wp_roles, $wp_users_object;
176
+
177
+ if ( ! isset( $wp_roles ) )
178
+ $wp_roles = new BP_Roles( $wp_users_object->db );
179
+
180
+ //Filter out caps that are not role names and assign to $this->roles
181
+ if ( is_array( $this->caps ) )
182
+ $this->roles = array_filter( array_keys( $this->caps ), array( &$wp_roles, 'is_role' ) );
183
+
184
+ //Build $allcaps from role caps, overlay user's $caps
185
+ $this->allcaps = array();
186
+ foreach ( (array) $this->roles as $role ) {
187
+ $role =& $wp_roles->get_role( $role );
188
+ $this->allcaps = array_merge( (array) $this->allcaps, (array) $role->capabilities );
189
+ }
190
+ $this->allcaps = array_merge( (array) $this->allcaps, (array) $this->caps );
191
+ }
192
+
193
+ /**
194
+ * Add role to user.
195
+ *
196
+ * Updates the user's meta data option with capabilities and roles.
197
+ *
198
+ * @since 2.0.0
199
+ * @access public
200
+ *
201
+ * @param string $role Role name.
202
+ */
203
+ function add_role( $role ) {
204
+ $this->caps[$role] = true;
205
+ $this->update_user();
206
+ }
207
+
208
+ /**
209
+ * Remove role from user.
210
+ *
211
+ * @since 2.0.0
212
+ * @access public
213
+ *
214
+ * @param string $role Role name.
215
+ */
216
+ function remove_role( $role ) {
217
+ if ( empty( $this->caps[$role] ) || ( count( $this->caps ) <= 1 ) )
218
+ return;
219
+ unset( $this->caps[$role] );
220
+ $this->update_user();
221
+ }
222
+
223
+ /**
224
+ * Set the role of the user.
225
+ *
226
+ * This will remove the previous roles of the user and assign the user the
227
+ * new one. You can set the role to an empty string and it will remove all
228
+ * of the roles from the user.
229
+ *
230
+ * @since 2.0.0
231
+ * @access public
232
+ *
233
+ * @param string $role Role name.
234
+ */
235
+ function set_role( $role ) {
236
+ foreach ( (array) $this->roles as $oldrole )
237
+ unset( $this->caps[$oldrole] );
238
+ if ( !empty( $role ) ) {
239
+ $this->caps[$role] = true;
240
+ $this->roles = array( $role => true );
241
+ } else {
242
+ $this->roles = false;
243
+ }
244
+ $this->update_user();
245
+ }
246
+
247
+ function update_user() {
248
+ global $wp_users_object;
249
+ $wp_users_object->update_meta( array( 'id' => $this->ID, 'meta_key' => $this->cap_key, 'meta_value' => $this->caps ) );
250
+ $this->get_role_caps();
251
+ //$this->update_user_level_from_caps(); // WP
252
+ }
253
+
254
+ /**
255
+ * Choose the maximum level the user has.
256
+ *
257
+ * Will compare the level from the $item parameter against the $max
258
+ * parameter. If the item is incorrect, then just the $max parameter value
259
+ * will be returned.
260
+ *
261
+ * Used to get the max level based on the capabilities the user has. This
262
+ * is also based on roles, so if the user is assigned the Administrator role
263
+ * then the capability 'level_10' will exist and the user will get that
264
+ * value.
265
+ *
266
+ * @since 2.0.0
267
+ * @access public
268
+ *
269
+ * @param int $max Max level of user.
270
+ * @param string $item Level capability name.
271
+ * @return int Max Level.
272
+ */
273
+ /*
274
+ function level_reduction( $max, $item ) {
275
+ if ( preg_match( '/^level_(10|[0-9])$/i', $item, $matches ) ) {
276
+ $level = intval( $matches[1] );
277
+ return max( $max, $level );
278
+ } else {
279
+ return $max;
280
+ }
281
+ }
282
+ */
283
+
284
+ /**
285
+ * Update the maximum user level for the user.
286
+ *
287
+ * Updates the 'user_level' user metadata (includes prefix that is the
288
+ * database table prefix) with the maximum user level. Gets the value from
289
+ * the all of the capabilities that the user has.
290
+ *
291
+ * @since 2.0.0
292
+ * @access public
293
+ */
294
+ /*
295
+ function update_user_level_from_caps() {
296
+ global $wp_users_object;
297
+ $this->user_level = array_reduce( array_keys( $this->allcaps ), array( &$this, 'level_reduction' ), 0 );
298
+ update_usermeta( $this->ID, $wpdb->prefix.'user_level', $this->user_level );
299
+ }
300
+ */
301
+
302
+ /*
303
+ function translate_level_to_cap($level) {
304
+ return 'level_' . $level;
305
+ }
306
+ */
307
+
308
+ /**
309
+ * Add capability and grant or deny access to capability.
310
+ *
311
+ * @since 2.0.0
312
+ * @access public
313
+ *
314
+ * @param string $cap Capability name.
315
+ * @param bool $grant Whether to grant capability to user.
316
+ */
317
+ function add_cap( $cap, $grant = true ) {
318
+ $this->caps[$cap] = $grant;
319
+ $this->update_user();
320
+ }
321
+
322
+ /**
323
+ * Remove capability from user.
324
+ *
325
+ * @since 2.0.0
326
+ * @access public
327
+ *
328
+ * @param string $cap Capability name.
329
+ */
330
+ function remove_cap( $cap ) {
331
+ if ( empty( $this->caps[$cap] ) ) return;
332
+ unset( $this->caps[$cap] );
333
+ $this->update_user();
334
+ }
335
+
336
+ /**
337
+ * Remove all of the capabilities of the user.
338
+ *
339
+ * @since 2.1.0
340
+ * @access public
341
+ */
342
+ function remove_all_caps() {
343
+ global $wp_users_object;
344
+ $this->caps = array();
345
+ $wp_users_object->delete_meta( $this->ID, $this->cap_key );
346
+ $this->get_role_caps();
347
+ }
348
+
349
+ /**
350
+ * Whether user has capability or role name.
351
+ *
352
+ * This is useful for looking up whether the user has a specific role
353
+ * assigned to the user. The second optional parameter can also be used to
354
+ * check for capabilities against a specfic post.
355
+ *
356
+ * @since 2.0.0
357
+ * @access public
358
+ *
359
+ * @param string|int $cap Capability or role name to search.
360
+ * @param int $post_id Optional. Post ID to check capability against specific post.
361
+ * @return bool True, if user has capability; false, if user does not have capability.
362
+ */
363
+ function has_cap( $cap ) {
364
+ global $wp_roles;
365
+
366
+ if ( is_numeric( $cap ) )
367
+ $cap = $this->translate_level_to_cap( $cap );
368
+
369
+ $args = array_slice( func_get_args(), 1 );
370
+ $args = array_merge( array( $cap, $this->ID ), $args );
371
+ $caps = call_user_func_array( array(&$wp_roles, 'map_meta_cap'), $args );
372
+ // Must have ALL requested caps
373
+ $capabilities = apply_filters( 'user_has_cap', $this->allcaps, $caps, $args );
374
+ foreach ( (array) $caps as $cap ) {
375
+ //echo "Checking cap $cap<br />";
376
+ if ( empty( $capabilities[$cap] ) || !$capabilities[$cap] )
377
+ return false;
378
+ }
379
+
380
+ return true;
381
+ }
382
+
383
+ /**
384
+ * Convert numeric level to level capability name.
385
+ *
386
+ * Prepends 'level_' to level number.
387
+ *
388
+ * @since 2.0.0
389
+ * @access public
390
+ *
391
+ * @param int $level Level number, 1 to 10.
392
+ * @return string
393
+ */
394
+ function translate_level_to_cap( $level ) {
395
+ return 'level_' . $level;
396
+ }
397
+
398
+ }
bp-forums/bbpress/bb-includes/backpress/class.bpdb-multi.php ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // backPress Multi DB Class
3
+
4
+ // ORIGINAL CODE FROM:
5
+ // Justin Vincent (justin@visunet.ie)
6
+ // http://php.justinvincent.com
7
+
8
+ require( BACKPRESS_PATH . 'class.bpdb.php' );
9
+
10
+ class BPDB_Multi extends BPDB {
11
+ /**
12
+ * Associative array (dbhname => dbh) for established mysql connections
13
+ * @var array
14
+ */
15
+ var $dbhs = array();
16
+
17
+ var $_force_dbhname = false;
18
+ var $last_table = '';
19
+ var $db_tables = array();
20
+ var $db_servers = array();
21
+
22
+ // function BPDB_Multi() {} // Not used - rely on PHP4 constructor from BPDB to call BPDB_Multi::__construct
23
+
24
+ function __construct() {
25
+ $args = func_get_args();
26
+ $args = call_user_func_array( array(&$this, '_init'), $args );
27
+
28
+ if ( $args['host'] ) {
29
+ $this->db_servers['dbh_global'] = $args;
30
+ $this->db_connect( '/* */' );
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Figure out which database server should handle the query, and connect to it.
36
+ * @param string query
37
+ * @return resource mysql database connection
38
+ */
39
+ function &db_connect( $query = '' ) {
40
+ $false = false;
41
+ if ( empty( $query ) )
42
+ return $false;
43
+
44
+ $this->last_table = $table = $this->get_table_from_query( $query );
45
+
46
+ // We can attempt to force the connection identifier in use
47
+ if ( $this->_force_dbhname && isset($this->db_servers[$this->_force_dbhname]) )
48
+ $dbhname = $this->_force_dbhname;
49
+
50
+ if ( !isset($dbhname) ) {
51
+ if ( isset( $this->db_tables[$table] ) )
52
+ $dbhname = $this->db_tables[$table];
53
+ else
54
+ $dbhname = 'dbh_global';
55
+ }
56
+
57
+ if ( !isset($this->db_servers[$dbhname]) )
58
+ return $false;
59
+
60
+ if ( isset($this->dbhs[$dbhname]) && is_resource($this->dbhs[$dbhname]) ) // We're already connected!
61
+ return $this->dbhs[$dbhname];
62
+
63
+ $success = $this->db_connect_host( $this->db_servers[$dbhname] );
64
+
65
+ if ( $success && is_resource($this->dbh) ) {
66
+ $this->dbhs[$dbhname] =& $this->dbh;
67
+ } else {
68
+ unset($this->dbhs[$dbhname]);
69
+ unset($this->dbh);
70
+ return $false;
71
+ }
72
+
73
+ return $this->dbhs[$dbhname];
74
+ }
75
+
76
+ /**
77
+ * Sets the prefix of the database tables
78
+ * @param string prefix
79
+ * @param false|array tables (optional: false)
80
+ * table identifiers are array keys
81
+ * array values
82
+ * empty: set prefix: array( 'posts' => false, 'users' => false, ... )
83
+ * string: set to that array value: array( 'posts' => 'my_posts', 'users' => 'my_users' )
84
+ * array: array[0] is DB identifier, array[1] is table name: array( 'posts' => array( 'global', 'my_posts' ), 'users' => array( 'users', 'my_users' ) )
85
+ * OR array values (with numeric keys): array( 'posts', 'users', ... )
86
+ *
87
+ * @return string the previous prefix (mostly only meaningful if all $table parameter was false)
88
+ */
89
+ function set_prefix( $prefix, $tables = false ) {
90
+ $old_prefix = parent::set_prefix( $prefix, $tables );
91
+ if ( !$old_prefix || is_wp_error($old_prefix) ) {
92
+ return $old_prefix;
93
+ }
94
+
95
+ if ( $tables && is_array($tables) ) {
96
+ $_tables = $tables;
97
+ } else {
98
+ $_tables = $this->tables;
99
+ }
100
+
101
+ foreach ( $_tables as $key => $value ) {
102
+ // array( 'posts' => array( 'global', 'my_posts' ), 'users' => array( 'users', 'my_users' ) )
103
+ if ( is_array($value) && isset($this->db_servers['dbh_' . $value[0]]) ) {
104
+ $this->add_db_table( $value[0], $value[1] );
105
+ $this->$key = $value[1];
106
+ }
107
+ }
108
+
109
+ return $old_prefix;
110
+ }
111
+
112
+ /**
113
+ * Find the first table name referenced in a query
114
+ * @param string query
115
+ * @return string table
116
+ */
117
+ function get_table_from_query ( $q ) {
118
+ // Remove characters that can legally trail the table name
119
+ rtrim($q, ';/-#');
120
+
121
+ // Quickly match most common queries
122
+ if ( preg_match('/^\s*(?:'
123
+ . 'SELECT.*?\s+FROM'
124
+ . '|INSERT(?:\s+IGNORE)?(?:\s+INTO)?'
125
+ . '|REPLACE(?:\s+INTO)?'
126
+ . '|UPDATE(?:\s+IGNORE)?'
127
+ . '|DELETE(?:\s+IGNORE)?(?:\s+FROM)?'
128
+ . ')\s+`?(\w+)`?/is', $q, $maybe) )
129
+ return $maybe[1];
130
+
131
+ // Refer to the previous query
132
+ if ( preg_match('/^\s*SELECT.*?\s+FOUND_ROWS\(\)/is', $q) )
133
+ return $this->last_table;
134
+
135
+ // Big pattern for the rest of the table-related queries in MySQL 5.0
136
+ if ( preg_match('/^\s*(?:'
137
+ . '(?:EXPLAIN\s+(?:EXTENDED\s+)?)?SELECT.*?\s+FROM'
138
+ . '|INSERT(?:\s+LOW_PRIORITY|\s+DELAYED|\s+HIGH_PRIORITY)?(?:\s+IGNORE)?(?:\s+INTO)?'
139
+ . '|REPLACE(?:\s+LOW_PRIORITY|\s+DELAYED)?(?:\s+INTO)?'
140
+ . '|UPDATE(?:\s+LOW_PRIORITY)?(?:\s+IGNORE)?'
141
+ . '|DELETE(?:\s+LOW_PRIORITY|\s+QUICK|\s+IGNORE)*(?:\s+FROM)?'
142
+ . '|DESCRIBE|DESC|EXPLAIN|HANDLER'
143
+ . '|(?:LOCK|UNLOCK)\s+TABLE(?:S)?'
144
+ . '|(?:RENAME|OPTIMIZE|BACKUP|RESTORE|CHECK|CHECKSUM|ANALYZE|OPTIMIZE|REPAIR).*\s+TABLE'
145
+ . '|TRUNCATE(?:\s+TABLE)?'
146
+ . '|CREATE(?:\s+TEMPORARY)?\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?'
147
+ . '|ALTER(?:\s+IGNORE)?'
148
+ . '|DROP\s+TABLE(?:\s+IF\s+EXISTS)?'
149
+ . '|CREATE(?:\s+\w+)?\s+INDEX.*\s+ON'
150
+ . '|DROP\s+INDEX.*\s+ON'
151
+ . '|LOAD\s+DATA.*INFILE.*INTO\s+TABLE'
152
+ . '|(?:GRANT|REVOKE).*ON\s+TABLE'
153
+ . '|SHOW\s+(?:.*FROM|.*TABLE)'
154
+ . ')\s+`?(\w+)`?/is', $q, $maybe) )
155
+ return $maybe[1];
156
+
157
+ // All unmatched queries automatically fall to the global master
158
+ return '';
159
+ }
160
+
161
+ /**
162
+ * Add a database server's information. Does not automatically connect.
163
+ * @param string $ds Dataset: the name of the dataset.
164
+ * @param array $args
165
+ * name => string DB name (required)
166
+ * user => string DB user (optional: false)
167
+ * password => string DB user password (optional: false)
168
+ * host => string DB hostname (optional: 'localhost')
169
+ * charset => string DB default charset. Used in a SET NAMES query. (optional)
170
+ * collate => string DB default collation. If charset supplied, optionally added to the SET NAMES query (optional)
171
+ */
172
+ function add_db_server( $ds, $args = null ) {
173
+ $defaults = array(
174
+ 'user' => false,
175
+ 'password' => false,
176
+ 'name' => false,
177
+ 'host' => 'localhost',
178
+ 'charset' => false,
179
+ 'collate' => false
180
+ );
181
+
182
+ $args = wp_parse_args( $args, $defaults );
183
+ $args['ds'] = 'dbh_' . $ds;
184
+
185
+ $this->db_servers['dbh_' . $ds] = $args;
186
+ }
187
+
188
+ /**
189
+ * Maps a table to a dataset.
190
+ * @param string $ds Dataset: the name of the dataset.
191
+ * @param string $table
192
+ */
193
+ function add_db_table( $ds, $table ) {
194
+ $this->db_tables[$table] = 'dbh_' . $ds;
195
+ }
196
+ }
bp-forums/bbpress/bb-includes/backpress/class.bpdb.php ADDED
@@ -0,0 +1,1164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // backPress DB Class
3
+
4
+ // ORIGINAL CODE FROM:
5
+ // Justin Vincent (justin@visunet.ie)
6
+ // http://php.justinvincent.com
7
+
8
+ define( 'EZSQL_VERSION', 'BP1.25' );
9
+ define( 'OBJECT', 'OBJECT', true );
10
+ define( 'OBJECT_K', 'OBJECT_K', false );
11
+ define( 'ARRAY_A', 'ARRAY_A', false );
12
+ define( 'ARRAY_K', 'ARRAY_K', false );
13
+ define( 'ARRAY_N', 'ARRAY_N', false );
14
+
15
+ if ( !defined( 'SAVEQUERIES' ) ) {
16
+ define( 'SAVEQUERIES', false );
17
+ }
18
+
19
+ if ( !defined( 'BPDB__ERROR_STRING' ) ) {
20
+ define( 'BPDB__ERROR_STRING', 'DB Error: %s, %s: %s' );
21
+ }
22
+ if ( !defined( 'BPDB__ERROR_HTML' ) ) {
23
+ define( 'BPDB__ERROR_HTML', '<div class="error"><p><strong>DB Error in %3$s:</strong> %1$s</p><pre>%2$s</pre></div>' );
24
+ }
25
+ if ( !defined( 'BPDB__CONNECT_ERROR_MESSAGE' ) ) {
26
+ define( 'BPDB__CONNECT_ERROR_MESSAGE', 'DB Error: cannot connect' );
27
+ }
28
+ if ( !defined( 'BPDB__SELECT_ERROR_MESSAGE' ) ) {
29
+ define( 'BPDB__SELECT_ERROR_MESSAGE', 'DB Error: cannot select' );
30
+ }
31
+ if ( !defined( 'BPDB__DB_VERSION_ERROR' ) ) {
32
+ define( 'BPDB__DB_VERSION_ERROR', 'DB Requires MySQL version 4.0 or higher' );
33
+ }
34
+ if ( !defined( 'BPDB__PHP_EXTENSION_MISSING' ) ) {
35
+ define( 'BPDB__PHP_EXTENSION_MISSING', 'DB Requires The MySQL PHP extension' );
36
+ }
37
+
38
+ class BPDB
39
+ {
40
+ /**
41
+ * Whether to show SQL/DB errors
42
+ *
43
+ * @since 1.0
44
+ * @access private
45
+ * @var bool
46
+ */
47
+ var $show_errors = false;
48
+
49
+ /**
50
+ * Whether to suppress errors during the DB bootstrapping.
51
+ *
52
+ * @access private
53
+ * @since 1.0
54
+ * @var bool
55
+ */
56
+ var $suppress_errors = false;
57
+
58
+ /**
59
+ * The last error during query.
60
+ *
61
+ * @since 1.0
62
+ * @var string
63
+ */
64
+ var $last_error = '';
65
+
66
+ /**
67
+ * Amount of queries made
68
+ *
69
+ * @since 1.0
70
+ * @access private
71
+ * @var int
72
+ */
73
+ var $num_queries = 0;
74
+
75
+ /**
76
+ * The last query made
77
+ *
78
+ * @since 1.0
79
+ * @access private
80
+ * @var string
81
+ */
82
+ var $last_query = null;
83
+
84
+ /**
85
+ * Saved info on the table column
86
+ *
87
+ * @since 1.0
88
+ * @access private
89
+ * @var array
90
+ */
91
+ var $col_info = array();
92
+
93
+ /**
94
+ * Saved queries that were executed
95
+ *
96
+ * @since 1.0
97
+ * @access private
98
+ * @var array
99
+ */
100
+ var $queries = array();
101
+
102
+ /**
103
+ * Whether to use the query log
104
+ *
105
+ * @since 1.0
106
+ * @access private
107
+ * @var bool
108
+ */
109
+ var $save_queries = false;
110
+
111
+ /**
112
+ * Table prefix
113
+ *
114
+ * You can set this to have multiple installations
115
+ * in a single database. The second reason is for possible
116
+ * security precautions.
117
+ *
118
+ * @since 1.0
119
+ * @access private
120
+ * @var string
121
+ */
122
+ var $prefix = '';
123
+
124
+ /**
125
+ * Whether the database queries are ready to start executing.
126
+ *
127
+ * @since 1.0
128
+ * @access private
129
+ * @var bool
130
+ */
131
+ var $ready = false;
132
+
133
+ /**
134
+ * The currently connected MySQL connection resource.
135
+ *
136
+ * @since 1.0
137
+ * @access private
138
+ * @var bool|resource
139
+ */
140
+ var $dbh = false;
141
+
142
+ /**
143
+ * List of tables
144
+ *
145
+ * @since 1.0
146
+ * @access private
147
+ * @var array
148
+ */
149
+ var $tables = array();
150
+
151
+ /**
152
+ * Whether to use mysql_real_escape_string
153
+ *
154
+ * @since 1.0
155
+ * @access public
156
+ * @var bool
157
+ */
158
+ var $real_escape = false;
159
+
160
+ /**
161
+ * PHP4 style constructor
162
+ *
163
+ * @since 1.0
164
+ *
165
+ * @return unknown Returns the result of bpdb::__construct()
166
+ */
167
+ function BPDB()
168
+ {
169
+ $args = func_get_args();
170
+ register_shutdown_function( array( &$this, '__destruct' ) );
171
+ return call_user_func_array( array( &$this, '__construct' ), $args );
172
+ }
173
+
174
+ /**
175
+ * PHP5 style constructor
176
+ *
177
+ * Grabs the arguments, calls bpdb::_init() and then connects to the database
178
+ *
179
+ * @since 1.0
180
+ *
181
+ * @return void
182
+ */
183
+ function __construct()
184
+ {
185
+ $args = func_get_args();
186
+ $args = call_user_func_array( array( &$this, '_init' ), $args );
187
+
188
+ $this->db_connect_host( $args );
189
+ }
190
+
191
+ /**
192
+ * Initialises the class variables based on provided arguments
193
+ *
194
+ * @since 1.0
195
+ *
196
+ * @param array $args The provided connection settings
197
+ * @return array The current connection settings after processing by init
198
+ */
199
+ function _init( $args )
200
+ {
201
+ if ( !extension_loaded( 'mysql' ) ) {
202
+ $this->show_errors();
203
+ $this->bail( BPDB__PHP_EXTENSION_MISSING );
204
+ return;
205
+ }
206
+
207
+ if ( 4 == func_num_args() ) {
208
+ $args = array(
209
+ 'user' => $args,
210
+ 'password' => func_get_arg( 1 ),
211
+ 'name' => func_get_arg( 2 ),
212
+ 'host' => func_get_arg( 3 )
213
+ );
214
+ }
215
+
216
+ $defaults = array(
217
+ 'user' => false,
218
+ 'password' => false,
219
+ 'name' => false,
220
+ 'host' => 'localhost',
221
+ 'charset' => false,
222
+ 'collate' => false,
223
+ 'errors' => false
224
+ );
225
+
226
+ $args = wp_parse_args( $args, $defaults );
227
+
228
+ switch ( $args['errors'] ) {
229
+ case 'show' :
230
+ $this->show_errors( true );
231
+ break;
232
+ case 'suppress' :
233
+ $this->suppress_errors( true );
234
+ break;
235
+ }
236
+
237
+ return $args;
238
+ }
239
+
240
+ /**
241
+ * PHP5 style destructor, registered as shutdown function in PHP4
242
+ *
243
+ * @since 1.0
244
+ *
245
+ * @return bool Always returns true
246
+ */
247
+ function __destruct()
248
+ {
249
+ return true;
250
+ }
251
+
252
+ /**
253
+ * Figure out which database server should handle the query, and connect to it.
254
+ *
255
+ * @since 1.0
256
+ *
257
+ * @param string query
258
+ * @return resource mysql database connection
259
+ */
260
+ function &db_connect( $query = '' )
261
+ {
262
+ $false = false;
263
+ if ( empty( $query ) ) {
264
+ return $false;
265
+ }
266
+ return $this->dbh;
267
+ }
268
+
269
+ /**
270
+ * Connects to the database server and selects a database
271
+ *
272
+ * @since 1.0
273
+ *
274
+ * @param array args
275
+ * name => string DB name (required)
276
+ * user => string DB user (optional: false)
277
+ * password => string DB user password (optional: false)
278
+ * host => string DB hostname (optional: 'localhost')
279
+ * charset => string DB default charset. Used in a SET NAMES query. (optional)
280
+ * collate => string DB default collation. If charset supplied, optionally added to the SET NAMES query (optional)
281
+ * @return void|bool void if cannot connect, false if cannot select, true if success
282
+ */
283
+ function db_connect_host( $args )
284
+ {
285
+ extract( $args, EXTR_SKIP );
286
+
287
+ unset( $this->dbh ); // De-reference before re-assigning
288
+ $this->dbh = @mysql_connect( $host, $user, $password, true );
289
+
290
+ if ( !$this->dbh ) {
291
+ if ( !$this->suppress_errors ) {
292
+ $this->show_errors();
293
+ }
294
+ $this->bail( BPDB__CONNECT_ERROR_MESSAGE );
295
+ return;
296
+ }
297
+
298
+ $this->ready = true;
299
+
300
+ if ( $this->has_cap( 'collation' ) ) {
301
+ if ( !empty( $charset ) ) {
302
+ if ( function_exists( 'mysql_set_charset' ) ) {
303
+ mysql_set_charset( $charset, $this->dbh );
304
+ $this->real_escape = true;
305
+ } else {
306
+ $collation_query = "SET NAMES '{$charset}'";
307
+ if ( !empty( $collate ) ) {
308
+ $collation_query .= " COLLATE '{$collate}'";
309
+ }
310
+ $this->query( $collation_query, true );
311
+ }
312
+ }
313
+ }
314
+
315
+ return $this->select( $name, $this->dbh );
316
+ }
317
+
318
+ /**
319
+ * Sets the table prefix for the WordPress tables.
320
+ *
321
+ * @since 1.0
322
+ *
323
+ * @param string prefix
324
+ * @param false|array tables (optional: false)
325
+ * table identifiers are array keys
326
+ * array values
327
+ * empty: set prefix: array( 'posts' => false, 'users' => false, ... )
328
+ * string: set to that array value: array( 'posts' => 'my_posts', 'users' => 'my_users' )
329
+ * OR array values (with numeric keys): array( 'posts', 'users', ... )
330
+ *
331
+ * @return string the previous prefix (mostly only meaningful if all $table parameter was false)
332
+ */
333
+ function set_prefix( $prefix, $tables = false )
334
+ {
335
+ if ( !$prefix ) {
336
+ return false;
337
+ }
338
+ if ( preg_match( '|[^a-z0-9_]|i', $prefix ) ) {
339
+ return new WP_Error( 'invalid_db_prefix', 'Invalid database prefix' ); // No gettext here
340
+ }
341
+
342
+ $old_prefix = $this->prefix;
343
+
344
+ if ( $tables && is_array( $tables ) ) {
345
+ $_tables =& $tables;
346
+ } else {
347
+ $_tables =& $this->tables;
348
+ $this->prefix = $prefix;
349
+ }
350
+
351
+ foreach ( $_tables as $key => $value ) {
352
+ if ( is_numeric( $key ) ) { // array( 'posts', 'users', ... )
353
+ $this->$value = $prefix . $value;
354
+ } elseif ( !$value ) {
355
+ $this->$key = $prefix . $key; // array( 'posts' => false, 'users' => false, ... )
356
+ } elseif ( is_string( $value ) ) { // array( 'posts' => 'my_posts', 'users' => 'my_users' )
357
+ $this->$key = $value;
358
+ }
359
+ }
360
+
361
+ return $old_prefix;
362
+ }
363
+
364
+ /**
365
+ * Selects a database using the current database connection.
366
+ *
367
+ * The database name will be changed based on the current database
368
+ * connection. On failure, the execution will bail and display an DB error.
369
+ *
370
+ * @since 1.0
371
+ *
372
+ * @param string $db MySQL database name
373
+ * @return bool True on success, false on failure.
374
+ */
375
+ function select( $db, &$dbh )
376
+ {
377
+ if ( !@mysql_select_db( $db, $dbh ) ) {
378
+ $this->ready = false;
379
+ $this->show_errors();
380
+ $this->bail( BPDB__SELECT_ERROR_MESSAGE );
381
+ return false;
382
+ }
383
+ return true;
384
+ }
385
+
386
+ function _weak_escape( $string )
387
+ {
388
+ return addslashes( $string );
389
+ }
390
+
391
+ function _real_escape( $string )
392
+ {
393
+ if ( $this->dbh && $this->real_escape ) {
394
+ return mysql_real_escape_string( $string, $this->dbh );
395
+ } else {
396
+ return addslashes( $string );
397
+ }
398
+ }
399
+
400
+ function _escape( $data )
401
+ {
402
+ if ( is_array( $data ) ) {
403
+ foreach ( (array) $data as $k => $v ) {
404
+ if ( is_array( $v ) ) {
405
+ $data[$k] = $this->_escape( $v );
406
+ } else {
407
+ $data[$k] = $this->_real_escape( $v );
408
+ }
409
+ }
410
+ } else {
411
+ $data = $this->_real_escape( $data );
412
+ }
413
+
414
+ return $data;
415
+ }
416
+
417
+ /**
418
+ * Escapes content for insertion into the database using addslashes(), for security
419
+ *
420
+ * @since 1.0
421
+ *
422
+ * @param string|array $data
423
+ * @return string query safe string
424
+ */
425
+ function escape( $data )
426
+ {
427
+ if ( is_array( $data ) ) {
428
+ foreach ( (array) $data as $k => $v ) {
429
+ if ( is_array( $v ) ) {
430
+ $data[$k] = $this->escape( $v );
431
+ } else {
432
+ $data[$k] = $this->_weak_escape( $v );
433
+ }
434
+ }
435
+ } else {
436
+ $data = $this->_weak_escape( $data );
437
+ }
438
+
439
+ return $data;
440
+ }
441
+
442
+ /**
443
+ * Escapes content by reference for insertion into the database, for security
444
+ *
445
+ * @since 1.0
446
+ *
447
+ * @param string $s
448
+ */
449
+ function escape_by_ref( &$string )
450
+ {
451
+ $string = $this->_real_escape( $string );
452
+ }
453
+
454
+ /**
455
+ * Escapes array recursively for insertion into the database, for security
456
+ * @param array $array
457
+ */
458
+ function escape_deep( $array )
459
+ {
460
+ return $this->_escape( $array );
461
+ }
462
+
463
+ /**
464
+ * Prepares a SQL query for safe execution. Uses sprintf()-like syntax.
465
+ *
466
+ * This function only supports a small subset of the sprintf syntax; it only supports %d (decimal number), %s (string).
467
+ * Does not support sign, padding, alignment, width or precision specifiers.
468
+ * Does not support argument numbering/swapping.
469
+ *
470
+ * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}.
471
+ *
472
+ * Both %d and %s should be left unquoted in the query string.
473
+ *
474
+ * <code>
475
+ * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", "foo", 1337 )
476
+ * </code>
477
+ *
478
+ * @link http://php.net/sprintf Description of syntax.
479
+ * @since 1.0
480
+ *
481
+ * @param string $query Query statement with sprintf()-like placeholders
482
+ * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called like {@link http://php.net/vsprintf vsprintf()}, or the first variable to substitute into the query's placeholders if being called like {@link http://php.net/sprintf sprintf()}.
483
+ * @param mixed $args,... further variables to substitute into the query's placeholders if being called like {@link http://php.net/sprintf sprintf()}.
484
+ * @return null|string Sanitized query string
485
+ */
486
+ function prepare( $query = null ) // ( $query, *$args )
487
+ {
488
+ if ( is_null( $query ) ) {
489
+ return;
490
+ }
491
+ $args = func_get_args();
492
+ array_shift( $args );
493
+ // If args were passed as an array (as in vsprintf), move them up
494
+ if ( isset( $args[0] ) && is_array( $args[0] ) ) {
495
+ $args = $args[0];
496
+ }
497
+ $query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it
498
+ $query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting
499
+ $query = str_replace( '%s', "'%s'", $query ); // quote the strings
500
+ array_walk( $args, array( &$this, 'escape_by_ref' ) );
501
+ return @vsprintf( $query, $args );
502
+ }
503
+
504
+ /**
505
+ * Get SQL/DB error
506
+ *
507
+ * @since 1.0
508
+ *
509
+ * @param string $str Error string
510
+ */
511
+ function get_error( $str = '' )
512
+ {
513
+ if ( empty( $str ) ) {
514
+ if ( $this->last_error ) {
515
+ $str = $this->last_error;
516
+ } else {
517
+ return false;
518
+ }
519
+ }
520
+
521
+ $caller = $this->get_caller();
522
+ $error_str = sprintf( BPDB__ERROR_STRING, $str, $this->last_query, $caller );
523
+
524
+ if ( class_exists( 'WP_Error' ) ) {
525
+ return new WP_Error( 'db_query', $error_str, array( 'query' => $this->last_query, 'error' => $str, 'caller' => $caller ) );
526
+ } else {
527
+ return array( 'query' => $this->last_query, 'error' => $str, 'caller' => $caller, 'error_str' => $error_str );
528
+ }
529
+ }
530
+
531
+ /**
532
+ * Print SQL/DB error.
533
+ *
534
+ * @since 1.0
535
+ *
536
+ * @param string $str The error to display
537
+ * @return bool False if the showing of errors is disabled.
538
+ */
539
+ function print_error( $str = '' )
540
+ {
541
+ if ( $this->suppress_errors ) {
542
+ return false;
543
+ }
544
+
545
+ $error = $this->get_error( $str );
546
+ if ( is_object( $error ) && is_a( $error, 'WP_Error' ) ) {
547
+ $err = $error->get_error_data();
548
+ $err['error_str'] = $error->get_error_message();
549
+ } else {
550
+ $err =& $error;
551
+ }
552
+
553
+ $log_file = ini_get( 'error_log' );
554
+ if ( !empty( $log_file ) && ( 'syslog' != $log_file ) && is_writable( $log_file ) && function_exists( 'error_log' ) ) {
555
+ error_log($err['error_str'], 0);
556
+ }
557
+
558
+ // Is error output turned on or not
559
+ if ( !$this->show_errors ) {
560
+ return false;
561
+ }
562
+
563
+ $str = htmlspecialchars( $err['error'], ENT_QUOTES );
564
+ $query = htmlspecialchars( $err['query'], ENT_QUOTES );
565
+ $caller = htmlspecialchars( $err['caller'], ENT_QUOTES );
566
+
567
+ // If there is an error then take note of it
568
+
569
+ printf( BPDB__ERROR_HTML, $str, $query, $caller );
570
+ }
571
+
572
+ /**
573
+ * Enables showing of database errors.
574
+ *
575
+ * This function should be used only to enable showing of errors.
576
+ * bpdb::hide_errors() should be used instead for hiding of errors. However,
577
+ * this function can be used to enable and disable showing of database
578
+ * errors.
579
+ *
580
+ * @since 1.0
581
+ *
582
+ * @param bool $show Whether to show or hide errors
583
+ * @return bool Old value for showing errors.
584
+ */
585
+ function show_errors( $show = true )
586
+ {
587
+ $errors = $this->show_errors;
588
+ $this->show_errors = $show;
589
+ return $errors;
590
+ }
591
+
592
+ /**
593
+ * Disables showing of database errors.
594
+ *
595
+ * @since 1.0
596
+ *
597
+ * @return bool Whether showing of errors was active or not
598
+ */
599
+ function hide_errors()
600
+ {
601
+ return $this->show_errors( false );
602
+ }
603
+
604
+ /**
605
+ * Whether to suppress database errors.
606
+ *
607
+ * @since 1.0
608
+ *
609
+ * @param bool $suppress
610
+ * @return bool previous setting
611
+ */
612
+ function suppress_errors( $suppress = true )
613
+ {
614
+ $errors = $this->suppress_errors;
615
+ $this->suppress_errors = $suppress;
616
+ return $errors;
617
+ }
618
+
619
+ /**
620
+ * Kill cached query results.
621
+ *
622
+ * @since 1.0
623
+ */
624
+ function flush()
625
+ {
626
+ $this->last_result = array();
627
+ $this->col_info = array();
628
+ $this->last_query = null;
629
+ $this->last_error = '';
630
+ $this->num_rows = 0;
631
+ }
632
+
633
+ /**
634
+ * Perform a MySQL database query, using current database connection.
635
+ *
636
+ * More information can be found on the codex page.
637
+ *
638
+ * @since 1.0
639
+ *
640
+ * @param string $query
641
+ * @return int|false Number of rows affected/selected or false on error
642
+ */
643
+ function query( $query, $use_current = false )
644
+ {
645
+ if ( !$this->ready ) {
646
+ return false;
647
+ }
648
+
649
+ // filter the query, if filters are available
650
+ // NOTE: some queries are made before the plugins have been loaded, and thus cannot be filtered with this method
651
+ if ( function_exists( 'apply_filters' ) ) {
652
+ $query = apply_filters( 'query', $query );
653
+ }
654
+
655
+ // initialise return
656
+ $return_val = 0;
657
+ $this->flush();
658
+
659
+ // Log how the function was called
660
+ $this->func_call = "\$db->query(\"$query\")";
661
+
662
+ // Keep track of the last query for debug..
663
+ $this->last_query = $query;
664
+
665
+ // Perform the query via std mysql_query function..
666
+ if ( SAVEQUERIES ) {
667
+ $this->timer_start();
668
+ }
669
+
670
+ if ( $use_current ) {
671
+ $dbh =& $this->dbh;
672
+ } else {
673
+ $dbh = $this->db_connect( $query );
674
+ }
675
+
676
+ $this->result = @mysql_query( $query, $dbh );
677
+ ++$this->num_queries;
678
+
679
+ if ( SAVEQUERIES ) {
680
+ $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() );
681
+ }
682
+
683
+ // If there is an error then take note of it..
684
+ if ( $this->last_error = mysql_error( $dbh ) ) {
685
+ return $this->print_error( $this->last_error );
686
+ }
687
+
688
+ if ( preg_match( "/^\\s*(insert|delete|update|replace|alter) /i", $query ) ) {
689
+ $this->rows_affected = mysql_affected_rows( $dbh );
690
+ // Take note of the insert_id
691
+ if ( preg_match( "/^\\s*(insert|replace) /i", $query ) ) {
692
+ $this->insert_id = mysql_insert_id( $dbh );
693
+ }
694
+ // Return number of rows affected
695
+ $return_val = $this->rows_affected;
696
+ } else {
697
+ $i = 0;
698
+ while ( $i < @mysql_num_fields( $this->result ) ) {
699
+ $this->col_info[$i] = @mysql_fetch_field( $this->result );
700
+ $i++;
701
+ }
702
+ $num_rows = 0;
703
+ while ( $row = @mysql_fetch_object( $this->result ) ) {
704
+ $this->last_result[$num_rows] = $row;
705
+ $num_rows++;
706
+ }
707
+
708
+ @mysql_free_result( $this->result );
709
+
710
+ // Log number of rows the query returned
711
+ $this->num_rows = $num_rows;
712
+
713
+ // Return number of rows selected
714
+ $return_val = $this->num_rows;
715
+ }
716
+
717
+ return $return_val;
718
+ }
719
+
720
+ /**
721
+ * Insert a row into a table.
722
+ *
723
+ * <code>
724
+ * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
725
+ * </code>
726
+ *
727
+ * @since 1.0
728
+ * @see bpdb::prepare()
729
+ *
730
+ * @param string $table table name
731
+ * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
732
+ * @param array|string $format (optional) An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data. A format is one of '%d', '%s' (decimal number, string). If omitted, all values in $data will be treated as strings.
733
+ * @return int|false The number of rows inserted, or false on error.
734
+ */
735
+ function insert( $table, $data, $format = null )
736
+ {
737
+ $formats = $format = (array) $format;
738
+ $fields = array_keys( $data );
739
+ $formatted_fields = array();
740
+ foreach ( $fields as $field ) {
741
+ if ( !empty( $format ) ) {
742
+ $form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
743
+ } elseif ( isset( $this->field_types[$field] ) ) {
744
+ $form = $this->field_types[$field];
745
+ } elseif ( is_null( $data[$field] ) ) {
746
+ $form = 'NULL';
747
+ unset( $data[$field] );
748
+ } else {
749
+ $form = '%s';
750
+ }
751
+ $formatted_fields[] = $form;
752
+ }
753
+ $sql = "INSERT INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES (" . implode( ",", $formatted_fields ) . ")";
754
+ return $this->query( $this->prepare( $sql, $data ) );
755
+ }
756
+
757
+ /**
758
+ * Update a row in the table
759
+ *
760
+ * <code>
761
+ * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( 'ID' => 1 ), array( '%s', '%d' ), array( '%d' ) )
762
+ * </code>
763
+ *
764
+ * @since 1.0
765
+ * @see bpdb::prepare()
766
+ *
767
+ * @param string $table table name
768
+ * @param array $data Data to update (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
769
+ * @param array $where A named array of WHERE clauses (in column => value pairs). Multiple clauses will be joined with ANDs. Both $where columns and $where values should be "raw".
770
+ * @param array|string $format (optional) An array of formats to be mapped to each of the values in $data. If string, that format will be used for all of the values in $data. A format is one of '%d', '%s' (decimal number, string). If omitted, all values in $data will be treated as strings.
771
+ * @param array|string $format_where (optional) An array of formats to be mapped to each of the values in $where. If string, that format will be used for all of the items in $where. A format is one of '%d', '%s' (decimal number, string). If omitted, all values in $where will be treated as strings.
772
+ * @return int|false The number of rows updated, or false on error.
773
+ */
774
+ function update( $table, $data, $where, $format = null, $where_format = null )
775
+ {
776
+ if ( !is_array( $where ) ) {
777
+ return false;
778
+ }
779
+
780
+ $formats = $format = (array) $format;
781
+ $bits = $wheres = array();
782
+ foreach ( (array) array_keys( $data ) as $field ) {
783
+ if ( !empty( $format ) ) {
784
+ $form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
785
+ } elseif ( isset( $this->field_types[$field] ) ) {
786
+ $form = $this->field_types[$field];
787
+ } elseif ( is_null( $data[$field] ) ) {
788
+ $form = 'NULL';
789
+ unset( $data[$field] );
790
+ } else {
791
+ $form = '%s';
792
+ }
793
+ $bits[] = "`$field` = {$form}";
794
+ }
795
+
796
+ $where_formats = $where_format = (array) $where_format;
797
+ foreach ( (array) array_keys( $where ) as $field ) {
798
+ if ( !empty( $where_format ) ) {
799
+ $form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0];
800
+ } elseif ( isset( $this->field_types[$field] ) ) {
801
+ $form = $this->field_types[$field];
802
+ } elseif ( is_null( $where[$field] ) ) {
803
+ unset( $where[$field] );
804
+ $wheres[] = "`$field` IS NULL";
805
+ continue;
806
+ } else {
807
+ $form = '%s';
808
+ }
809
+ $wheres[] = "`$field` = {$form}";
810
+ }
811
+
812
+ $sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres );
813
+ return $this->query( $this->prepare( $sql, array_merge( array_values( $data ), array_values( $where ) ) ) );
814
+ }
815
+
816
+ /**
817
+ * Retrieve one variable from the database.
818
+ *
819
+ * Executes a SQL query and returns the value from the SQL result.
820
+ * If the SQL result contains more than one column and/or more than one row, this function returns the value in the column and row specified.
821
+ * If $query is null, this function returns the value in the specified column and row from the previous SQL result.
822
+ *
823
+ * @since 1.0
824
+ *
825
+ * @param string|null $query SQL query. If null, use the result from the previous query.
826
+ * @param int $x (optional) Column of value to return. Indexed from 0.
827
+ * @param int $y (optional) Row of value to return. Indexed from 0.
828
+ * @return string Database query result
829
+ */
830
+ function get_var( $query=null, $x = 0, $y = 0 )
831
+ {
832
+ $this->func_call = "\$db->get_var(\"$query\",$x,$y)";
833
+ if ( $query ) {
834
+ $this->query( $query );
835
+ }
836
+
837
+ // Extract var out of cached results based x,y vals
838
+ if ( !empty( $this->last_result[$y] ) ) {
839
+ $values = array_values( get_object_vars( $this->last_result[$y] ) );
840
+ }
841
+
842
+ // If there is a value return it else return null
843
+ return ( isset($values[$x]) && $values[$x]!=='' ) ? $values[$x] : null;
844
+ }
845
+
846
+ /**
847
+ * Retrieve one row from the database.
848
+ *
849
+ * Executes a SQL query and returns the row from the SQL result.
850
+ *
851
+ * @since 1.0
852
+ *
853
+ * @param string|null $query SQL query.
854
+ * @param string $output (optional) one of ARRAY_A | ARRAY_N | OBJECT constants. Return an associative array (column => value, ...), a numerically indexed array (0 => value, ...) or an object ( ->column = value ), respectively.
855
+ * @param int $y (optional) Row to return. Indexed from 0.
856
+ * @return mixed Database query result in format specifed by $output
857
+ */
858
+ function get_row( $query = null, $output = OBJECT, $y = 0 )
859
+ {
860
+ $this->func_call = "\$db->get_row(\"$query\",$output,$y)";
861
+ if ( $query ) {
862
+ $this->query( $query );
863
+ } else {
864
+ return null;
865
+ }
866
+
867
+ if ( !isset( $this->last_result[$y] ) ) {
868
+ return null;
869
+ }
870
+
871
+ if ( $output == OBJECT ) {
872
+ return $this->last_result[$y] ? $this->last_result[$y] : null;
873
+ } elseif ( $output == ARRAY_A ) {
874
+ return $this->last_result[$y] ? get_object_vars( $this->last_result[$y] ) : null;
875
+ } elseif ( $output == ARRAY_N ) {
876
+ return $this->last_result[$y] ? array_values( get_object_vars( $this->last_result[$y] ) ) : null;
877
+ } else {
878
+ $this->print_error( " \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N" );
879
+ }
880
+ }
881
+
882
+ /**
883
+ * Retrieve one column from the database.
884
+ *
885
+ * Executes a SQL query and returns the column from the SQL result.
886
+ * If the SQL result contains more than one column, this function returns the column specified.
887
+ * If $query is null, this function returns the specified column from the previous SQL result.
888
+ *
889
+ * @since 1.0
890
+ *
891
+ * @param string|null $query SQL query. If null, use the result from the previous query.
892
+ * @param int $x Column to return. Indexed from 0.
893
+ * @return array Database query result. Array indexed from 0 by SQL result row number.
894
+ */
895
+ function get_col( $query = null , $x = 0 )
896
+ {
897
+ if ( $query ) {
898
+ $this->query( $query );
899
+ }
900
+
901
+ $new_array = array();
902
+ // Extract the column values
903
+ for ( $i=0; $i < count( $this->last_result ); $i++ ) {
904
+ $new_array[$i] = $this->get_var( null, $x, $i );
905
+ }
906
+ return $new_array;
907
+ }
908
+
909
+ /**
910
+ * Retrieve an entire SQL result set from the database (i.e., many rows)
911
+ *
912
+ * Executes a SQL query and returns the entire SQL result.
913
+ *
914
+ * @since 1.0
915
+ *
916
+ * @param string $query SQL query.
917
+ * @param string $output (optional) ane of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K | ARRAY_K constants. With one of the first three, return an array of rows indexed from 0 by SQL result row number. Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively. With OBJECT_K and ARRAY_K, return an associative array of row objects keyed by the value of each row's first column's value. Duplicate keys are discarded.
918
+ * @return mixed Database query results
919
+ */
920
+ function get_results( $query = null, $output = OBJECT )
921
+ {
922
+ $this->func_call = "\$db->get_results(\"$query\", $output)";
923
+
924
+ if ( $query ) {
925
+ $this->query($query);
926
+ } else {
927
+ return null;
928
+ }
929
+
930
+ if ( $output == OBJECT ) {
931
+ // Return an integer-keyed array of row objects
932
+ return $this->last_result;
933
+ } elseif ( $output == OBJECT_K || $output == ARRAY_K ) {
934
+ // Return an array of row objects with keys from column 1
935
+ // (Duplicates are discarded)
936
+ $key = $this->col_info[0]->name;
937
+ foreach ( $this->last_result as $row ) {
938
+ if ( !isset( $new_array[ $row->$key ] ) ) {
939
+ $new_array[ $row->$key ] = $row;
940
+ }
941
+ }
942
+ if ( $output == ARRAY_K ) {
943
+ return array_map( 'get_object_vars', $new_array );
944
+ }
945
+ return $new_array;
946
+ } elseif ( $output == ARRAY_A || $output == ARRAY_N ) {
947
+ // Return an integer-keyed array of...
948
+ if ( $this->last_result ) {
949
+ $i = 0;
950
+ foreach( $this->last_result as $row ) {
951
+ if ( $output == ARRAY_N ) {
952
+ // ...integer-keyed row arrays
953
+ $new_array[$i] = array_values( get_object_vars( $row ) );
954
+ } else {
955
+ // ...column name-keyed row arrays
956
+ $new_array[$i] = get_object_vars( $row );
957
+ }
958
+ ++$i;
959
+ }
960
+ return $new_array;
961
+ }
962
+ }
963
+ }
964
+
965
+ /**
966
+ * Retrieve column metadata from the last query.
967
+ *
968
+ * @since 1.0
969
+ *
970
+ * @param string $info_type one of name, table, def, max_length, not_null, primary_key, multiple_key, unique_key, numeric, blob, type, unsigned, zerofill
971
+ * @param int $col_offset 0: col name. 1: which table the col's in. 2: col's max length. 3: if the col is numeric. 4: col's type
972
+ * @return mixed Column Results
973
+ */
974
+ function get_col_info( $info_type = 'name', $col_offset = -1 )
975
+ {
976
+ if ( $this->col_info ) {
977
+ if ( $col_offset == -1 ) {
978
+ $i = 0;
979
+ foreach( (array) $this->col_info as $col ) {
980
+ $new_array[$i] = $col->{$info_type};
981
+ $i++;
982
+ }
983
+ return $new_array;
984
+ } else {
985
+ return $this->col_info[$col_offset]->{$info_type};
986
+ }
987
+ }
988
+ }
989
+
990
+ /**
991
+ * Starts the timer, for debugging purposes.
992
+ *
993
+ * @since 1.0
994
+ *
995
+ * @return true
996
+ */
997
+ function timer_start()
998
+ {
999
+ $mtime = microtime();
1000
+ $mtime = explode( ' ', $mtime );
1001
+ $this->time_start = $mtime[1] + $mtime[0];
1002
+ return true;
1003
+ }
1004
+
1005
+ /**
1006
+ * Stops the debugging timer.
1007
+ *
1008
+ * @since 1.0
1009
+ *
1010
+ * @return int Total time spent on the query, in milliseconds
1011
+ */
1012
+ function timer_stop()
1013
+ {
1014
+ $mtime = microtime();
1015
+ $mtime = explode( ' ', $mtime );
1016
+ $time_end = $mtime[1] + $mtime[0];
1017
+ $time_total = $time_end - $this->time_start;
1018
+ return $time_total;
1019
+ }
1020
+
1021
+ /**
1022
+ * Wraps errors in a nice header and footer and dies.
1023
+ *
1024
+ * Will not die if bpdb::$show_errors is true
1025
+ *
1026
+ * @since 1.0
1027
+ *
1028
+ * @param string $message
1029
+ * @return false|void
1030
+ */
1031
+ function bail( $message )
1032
+ {
1033
+ if ( !$this->show_errors ) {
1034
+ if ( class_exists( 'WP_Error' ) )
1035
+ $this->error = new WP_Error( '500', $message );
1036
+ else
1037
+ $this->error = $message;
1038
+ return false;
1039
+ }
1040
+ backpress_die( $message );
1041
+ }
1042
+
1043
+ /**
1044
+ * Whether or not MySQL database is at least the required minimum version.
1045
+ *
1046
+ * @since 1.0
1047
+ *
1048
+ * @return WP_Error
1049
+ */
1050
+ function check_database_version( $dbh_or_table = false )
1051
+ {
1052
+ // Make sure the server has MySQL 4.0
1053
+ if ( version_compare( $this->db_version( $dbh_or_table ), '4.0.0', '<' ) ) {
1054
+ return new WP_Error( 'database_version', BPDB__DB_VERSION_ERROR );
1055
+ }
1056
+ }
1057
+
1058
+ /**
1059
+ * Whether of not the database supports collation.
1060
+ *
1061
+ * Called when BackPress is generating the table scheme.
1062
+ *
1063
+ * @since 1.0
1064
+ *
1065
+ * @return bool True if collation is supported, false if version does not
1066
+ */
1067
+ function supports_collation()
1068
+ {
1069
+ return $this->has_cap( 'collation' );
1070
+ }
1071
+
1072
+ /**
1073
+ * Generic function to determine if a database supports a particular feature
1074
+ *
1075
+ * @since 1.0
1076
+ *
1077
+ * @param string $db_cap the feature
1078
+ * @param false|string|resource $dbh_or_table Which database to test. False = the currently selected database, string = the database containing the specified table, resource = the database corresponding to the specified mysql resource.
1079
+ * @return bool
1080
+ */
1081
+ function has_cap( $db_cap, $dbh_or_table = false )
1082
+ {
1083
+ $version = $this->db_version( $dbh_or_table );
1084
+
1085
+ switch ( strtolower( $db_cap ) ) {
1086
+ case 'collation' :
1087
+ case 'group_concat' :
1088
+ case 'subqueries' :
1089
+ return version_compare( $version, '4.1', '>=' );
1090
+ break;
1091
+
1092
+ case 'index_hint_for_join' :
1093
+ return version_compare( $version, '5.0', '>=' );
1094
+ break;
1095
+
1096
+ case 'index_hint_lists' :
1097
+ case 'index_hint_for_any' :
1098
+ return version_compare( $version, '5.1', '>=' );
1099
+ break;
1100
+ }
1101
+
1102
+ return false;
1103
+ }
1104
+
1105
+ /**
1106
+ * The database version number
1107
+ *
1108
+ * @since 1.0
1109
+ *
1110
+ * @param false|string|resource $dbh_or_table Which database to test. False = the currently selected database, string = the database containing the specified table, resource = the database corresponding to the specified mysql resource.
1111
+ * @return false|string false on failure, version number on success
1112
+ */
1113
+ function db_version( $dbh_or_table = false )
1114
+ {
1115
+ if ( !$dbh_or_table ) {
1116
+ $dbh =& $this->dbh;
1117
+ } elseif ( is_resource( $dbh_or_table ) ) {
1118
+ $dbh =& $dbh_or_table;
1119
+ } else {
1120
+ $dbh = $this->db_connect( "DESCRIBE $dbh_or_table" );
1121
+ }
1122
+
1123
+ if ( $dbh ) {
1124
+ return preg_replace( '|[^0-9\.]|', '', mysql_get_server_info( $dbh ) );
1125
+ }
1126
+ return false;
1127
+ }
1128
+
1129
+ /**
1130
+ * Retrieve the name of the function that called bpdb.
1131
+ *
1132
+ * Requires PHP 4.3 and searches up the list of functions until it reaches
1133
+ * the one that would most logically had called this method.
1134
+ *
1135
+ * @since 1.0
1136
+ *
1137
+ * @return string The name of the calling function
1138
+ */
1139
+ function get_caller()
1140
+ {
1141
+ // requires PHP 4.3+
1142
+ if ( !is_callable( 'debug_backtrace' ) ) {
1143
+ return '';
1144
+ }
1145
+
1146
+ $bt = debug_backtrace();
1147
+ $caller = array();
1148
+
1149
+ $bt = array_reverse( $bt );
1150
+ foreach ( (array) $bt as $call ) {
1151
+ if ( @$call['class'] == __CLASS__ ) {
1152
+ continue;
1153
+ }
1154
+ $function = $call['function'];
1155
+ if ( isset( $call['class'] ) ) {
1156
+ $function = $call['class'] . "->$function";
1157
+ }
1158
+ $caller[] = $function;
1159
+ }
1160
+ $caller = join( ', ', $caller );
1161
+
1162
+ return $caller;
1163
+ }
1164
+ }
bp-forums/bbpress/bb-includes/backpress/class.ixr.php ADDED
@@ -0,0 +1,900 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Last sync [WP11537]
3
+
4
+ /**
5
+ * IXR - The Inutio XML-RPC Library
6
+ *
7
+ * @package IXR
8
+ * @since 1.5
9
+ *
10
+ * @copyright Incutio Ltd 2002-2005
11
+ * @version 1.7 (beta) 23rd May 2005
12
+ * @author Simon Willison
13
+ * @link http://scripts.incutio.com/xmlrpc/ Site
14
+ * @link http://scripts.incutio.com/xmlrpc/manual.php Manual
15
+ * @license BSD License http://www.opensource.org/licenses/bsd-license.php
16
+ */
17
+
18
+ /**
19
+ * IXR_Value
20
+ *
21
+ * @package IXR
22
+ * @since 1.5
23
+ */
24
+ class IXR_Value {
25
+ var $data;
26
+ var $type;
27
+
28
+ function IXR_Value ($data, $type = false) {
29
+ $this->data = $data;
30
+ if (!$type) {
31
+ $type = $this->calculateType();
32
+ }
33
+ $this->type = $type;
34
+ if ($type == 'struct') {
35
+ /* Turn all the values in the array in to new IXR_Value objects */
36
+ foreach ($this->data as $key => $value) {
37
+ $this->data[$key] = new IXR_Value($value);
38
+ }
39
+ }
40
+ if ($type == 'array') {
41
+ for ($i = 0, $j = count($this->data); $i < $j; $i++) {
42
+ $this->data[$i] = new IXR_Value($this->data[$i]);
43
+ }
44
+ }
45
+ }
46
+
47
+ function calculateType() {
48
+ if ($this->data === true || $this->data === false) {
49
+ return 'boolean';
50
+ }
51
+ if (is_integer($this->data)) {
52
+ return 'int';
53
+ }
54
+ if (is_double($this->data)) {
55
+ return 'double';
56
+ }
57
+ // Deal with IXR object types base64 and date
58
+ if (is_object($this->data) && is_a($this->data, 'IXR_Date')) {
59
+ return 'date';
60
+ }
61
+ if (is_object($this->data) && is_a($this->data, 'IXR_Base64')) {
62
+ return 'base64';
63
+ }
64
+ // If it is a normal PHP object convert it in to a struct
65
+ if (is_object($this->data)) {
66
+
67
+ $this->data = get_object_vars($this->data);
68
+ return 'struct';
69
+ }
70
+ if (!is_array($this->data)) {
71
+ return 'string';
72
+ }
73
+ /* We have an array - is it an array or a struct ? */
74
+ if ($this->isStruct($this->data)) {
75
+ return 'struct';
76
+ } else {
77
+ return 'array';
78
+ }
79
+ }
80
+
81
+ function getXml() {
82
+ /* Return XML for this value */
83
+ switch ($this->type) {
84
+ case 'boolean':
85
+ return '<boolean>'.(($this->data) ? '1' : '0').'</boolean>';
86
+ break;
87
+ case 'int':
88
+ return '<int>'.$this->data.'</int>';
89
+ break;
90
+ case 'double':
91
+ return '<double>'.$this->data.'</double>';
92
+ break;
93
+ case 'string':
94
+ return '<string>'.htmlspecialchars($this->data).'</string>';
95
+ break;
96
+ case 'array':
97
+ $return = '<array><data>'."\n";
98
+ foreach ($this->data as $item) {
99
+ $return .= ' <value>'.$item->getXml()."</value>\n";
100
+ }
101
+ $return .= '</data></array>';
102
+ return $return;
103
+ break;
104
+ case 'struct':
105
+ $return = '<struct>'."\n";
106
+ foreach ($this->data as $name => $value) {
107
+ $name = htmlspecialchars($name);
108
+ $return .= " <member><name>$name</name><value>";
109
+ $return .= $value->getXml()."</value></member>\n";
110
+ }
111
+ $return .= '</struct>';
112
+ return $return;
113
+ break;
114
+ case 'date':
115
+ case 'base64':
116
+ return $this->data->getXml();
117
+ break;
118
+ }
119
+ return false;
120
+ }
121
+
122
+ function isStruct($array) {
123
+ /* Nasty function to check if an array is a struct or not */
124
+ $expected = 0;
125
+ foreach ($array as $key => $value) {
126
+ if ((string)$key != (string)$expected) {
127
+ return true;
128
+ }
129
+ $expected++;
130
+ }
131
+ return false;
132
+ }
133
+ }
134
+
135
+ /**
136
+ * IXR_Message
137
+ *
138
+ * @package IXR
139
+ * @since 1.5
140
+ */
141
+ class IXR_Message {
142
+ var $message;
143
+ var $messageType; // methodCall / methodResponse / fault
144
+ var $faultCode;
145
+ var $faultString;
146
+ var $methodName;
147
+ var $params;
148
+ // Current variable stacks
149
+ var $_arraystructs = array(); // The stack used to keep track of the current array/struct
150
+ var $_arraystructstypes = array(); // Stack keeping track of if things are structs or array
151
+ var $_currentStructName = array(); // A stack as well
152
+ var $_param;
153
+ var $_value;
154
+ var $_currentTag;
155
+ var $_currentTagContents;
156
+ // The XML parser
157
+ var $_parser;
158
+ function IXR_Message ($message) {
159
+ $this->message = $message;
160
+ }
161
+ function parse() {
162
+ // first remove the XML declaration
163
+ $this->message = preg_replace('/<\?xml.*?\?'.'>/', '', $this->message);
164
+ if (trim($this->message) == '') {
165
+ return false;
166
+ }
167
+ $this->_parser = xml_parser_create();
168
+ // Set XML parser to take the case of tags in to account
169
+ xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
170
+ // Set XML parser callback functions
171
+ xml_set_object($this->_parser, $this);
172
+ xml_set_element_handler($this->_parser, 'tag_open', 'tag_close');
173
+ xml_set_character_data_handler($this->_parser, 'cdata');
174
+ if (!xml_parse($this->_parser, $this->message)) {
175
+ /* die(sprintf('XML error: %s at line %d',
176
+ xml_error_string(xml_get_error_code($this->_parser)),
177
+ xml_get_current_line_number($this->_parser))); */
178
+ return false;
179
+ }
180
+ xml_parser_free($this->_parser);
181
+ // Grab the error messages, if any
182
+ if ($this->messageType == 'fault') {
183
+ $this->faultCode = $this->params[0]['faultCode'];
184
+ $this->faultString = $this->params[0]['faultString'];
185
+ }
186
+ return true;
187
+ }
188
+ function tag_open($parser, $tag, $attr) {
189
+ $this->_currentTagContents = '';
190
+ $this->currentTag = $tag;
191
+ switch($tag) {
192
+ case 'methodCall':
193
+ case 'methodResponse':
194
+ case 'fault':
195
+ $this->messageType = $tag;
196
+ break;
197
+ /* Deal with stacks of arrays and structs */
198
+ case 'data': // data is to all intents and puposes more interesting than array
199
+ $this->_arraystructstypes[] = 'array';
200
+ $this->_arraystructs[] = array();
201
+ break;
202
+ case 'struct':
203
+ $this->_arraystructstypes[] = 'struct';
204
+ $this->_arraystructs[] = array();
205
+ break;
206
+ }
207
+ }
208
+ function cdata($parser, $cdata) {
209
+ $this->_currentTagContents .= $cdata;
210
+ }
211
+ function tag_close($parser, $tag) {
212
+ $valueFlag = false;
213
+ switch($tag) {
214
+ case 'int':
215
+ case 'i4':
216
+ $value = (int) trim($this->_currentTagContents);
217
+ $valueFlag = true;
218
+ break;
219
+ case 'double':
220
+ $value = (double) trim($this->_currentTagContents);
221
+ $valueFlag = true;
222
+ break;
223
+ case 'string':
224
+ $value = $this->_currentTagContents;
225
+ $valueFlag = true;
226
+ break;
227
+ case 'dateTime.iso8601':
228
+ $value = new IXR_Date(trim($this->_currentTagContents));
229
+ // $value = $iso->getTimestamp();
230
+ $valueFlag = true;
231
+ break;
232
+ case 'value':
233
+ // "If no type is indicated, the type is string."
234
+ if (trim($this->_currentTagContents) != '') {
235
+ $value = (string)$this->_currentTagContents;
236
+ $valueFlag = true;
237
+ }
238
+ break;
239
+ case 'boolean':
240
+ $value = (boolean) trim($this->_currentTagContents);
241
+ $valueFlag = true;
242
+ break;
243
+ case 'base64':
244
+ $value = base64_decode( trim( $this->_currentTagContents ) );
245
+ $valueFlag = true;
246
+ break;
247
+ /* Deal with stacks of arrays and structs */
248
+ case 'data':
249
+ case 'struct':
250
+ $value = array_pop($this->_arraystructs);
251
+ array_pop($this->_arraystructstypes);
252
+ $valueFlag = true;
253
+ break;
254
+ case 'member':
255
+ array_pop($this->_currentStructName);
256
+ break;
257
+ case 'name':
258
+ $this->_currentStructName[] = trim($this->_currentTagContents);
259
+ break;
260
+ case 'methodName':
261
+ $this->methodName = trim($this->_currentTagContents);
262
+ break;
263
+ }
264
+ if ($valueFlag) {
265
+ if (count($this->_arraystructs) > 0) {
266
+ // Add value to struct or array
267
+ if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') {
268
+ // Add to struct
269
+ $this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value;
270
+ } else {
271
+ // Add to array
272
+ $this->_arraystructs[count($this->_arraystructs)-1][] = $value;
273
+ }
274
+ } else {
275
+ // Just add as a paramater
276
+ $this->params[] = $value;
277
+ }
278
+ }
279
+ $this->_currentTagContents = '';
280
+ }
281
+ }
282
+
283
+ /**
284
+ * IXR_Server
285
+ *
286
+ * @package IXR
287
+ * @since 1.5
288
+ */
289
+ class IXR_Server {
290
+ var $data;
291
+ var $callbacks = array();
292
+ var $message;
293
+ var $capabilities;
294
+ function IXR_Server($callbacks = false, $data = false) {
295
+ $this->setCapabilities();
296
+ if ($callbacks) {
297
+ $this->callbacks = $callbacks;
298
+ }
299
+ $this->setCallbacks();
300
+ $this->serve($data);
301
+ }
302
+ function serve($data = false) {
303
+ if (!$data) {
304
+ global $HTTP_RAW_POST_DATA;
305
+ if (!$HTTP_RAW_POST_DATA) {
306
+ header( 'Content-Type: text/plain' );
307
+ die('XML-RPC server accepts POST requests only.');
308
+ }
309
+ $data = $HTTP_RAW_POST_DATA;
310
+ }
311
+ $this->message = new IXR_Message($data);
312
+ if (!$this->message->parse()) {
313
+ $this->error(-32700, 'parse error. not well formed');
314
+ }
315
+ if ($this->message->messageType != 'methodCall') {
316
+ $this->error(-32600, 'server error. invalid xml-rpc. not conforming to spec. Request must be a methodCall');
317
+ }
318
+ $result = $this->call($this->message->methodName, $this->message->params);
319
+ // Is the result an error?
320
+ if (is_a($result, 'IXR_Error')) {
321
+ $this->error($result);
322
+ }
323
+ // Encode the result
324
+ $r = new IXR_Value($result);
325
+ $resultxml = $r->getXml();
326
+ // Create the XML
327
+ $xml = <<<EOD
328
+ <methodResponse>
329
+ <params>
330
+ <param>
331
+ <value>
332
+ $resultxml
333
+ </value>
334
+ </param>
335
+ </params>
336
+ </methodResponse>
337
+
338
+ EOD;
339
+ // Send it
340
+ $this->output($xml);
341
+ }
342
+ function call($methodname, $args) {
343
+ if (!$this->hasMethod($methodname)) {
344
+ return new IXR_Error(-32601, 'server error. requested method '.
345
+ $methodname.' does not exist.');
346
+ }
347
+ $method = $this->callbacks[$methodname];
348
+ // Perform the callback and send the response
349
+ if (count($args) == 1) {
350
+ // If only one paramater just send that instead of the whole array
351
+ $args = $args[0];
352
+ }
353
+ // Are we dealing with a function or a method?
354
+ if (substr($method, 0, 5) == 'this:') {
355
+ // It's a class method - check it exists
356
+ $method = substr($method, 5);
357
+ if (!method_exists($this, $method)) {
358
+ return new IXR_Error(-32601, 'server error. requested class method "'.
359
+ $method.'" does not exist.');
360
+ }
361
+ // Call the method
362
+ $result = $this->$method($args);
363
+ } else {
364
+ // It's a function - does it exist?
365
+ if (is_array($method)) {
366
+ if (!method_exists($method[0], $method[1])) {
367
+ return new IXR_Error(-32601, 'server error. requested object method "'.
368
+ $method[1].'" does not exist.');
369
+ }
370
+ } else if (!function_exists($method)) {
371
+ return new IXR_Error(-32601, 'server error. requested function "'.
372
+ $method.'" does not exist.');
373
+ }
374
+ // Call the function
375
+ $result = call_user_func($method, $args);
376
+ }
377
+ return $result;
378
+ }
379
+
380
+ function error($error, $message = false) {
381
+ // Accepts either an error object or an error code and message
382
+ if ($message && !is_object($error)) {
383
+ $error = new IXR_Error($error, $message);
384
+ }
385
+ $this->output($error->getXml());
386
+ }
387
+ function output($xml) {
388
+ $xml = '<?xml version="1.0"?>'."\n".$xml;
389
+ $length = strlen($xml);
390
+ header('Connection: close');
391
+ header('Content-Length: '.$length);
392
+ header('Content-Type: text/xml');
393
+ header('Date: '.date('r'));
394
+ echo $xml;
395
+ exit;
396
+ }
397
+ function hasMethod($method) {
398
+ return in_array($method, array_keys($this->callbacks));
399
+ }
400
+ function setCapabilities() {
401
+ // Initialises capabilities array
402
+ $this->capabilities = array(
403
+ 'xmlrpc' => array(
404
+ 'specUrl' => 'http://www.xmlrpc.com/spec',
405
+ 'specVersion' => 1
406
+ ),
407
+ 'faults_interop' => array(
408
+ 'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php',
409
+ 'specVersion' => 20010516
410
+ ),
411
+ 'system.multicall' => array(
412
+ 'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208',
413
+ 'specVersion' => 1
414
+ ),
415
+ );
416
+ }
417
+ function getCapabilities($args) {
418
+ return $this->capabilities;
419
+ }
420
+ function setCallbacks() {
421
+ $this->callbacks['system.getCapabilities'] = 'this:getCapabilities';
422
+ $this->callbacks['system.listMethods'] = 'this:listMethods';
423
+ $this->callbacks['system.multicall'] = 'this:multiCall';
424
+ }
425
+ function listMethods($args) {
426
+ // Returns a list of methods - uses array_reverse to ensure user defined
427
+ // methods are listed before server defined methods
428
+ return array_reverse(array_keys($this->callbacks));
429
+ }
430
+ function multiCall($methodcalls) {
431
+ // See http://www.xmlrpc.com/discuss/msgReader$1208
432
+ $return = array();
433
+ foreach ($methodcalls as $call) {
434
+ $method = $call['methodName'];
435
+ $params = $call['params'];
436
+ if ($method == 'system.multicall') {
437
+ $result = new IXR_Error(-32600, 'Recursive calls to system.multicall are forbidden');
438
+ } else {
439
+ $result = $this->call($method, $params);
440
+ }
441
+ if (is_a($result, 'IXR_Error')) {
442
+ $return[] = array(
443
+ 'faultCode' => $result->code,
444
+ 'faultString' => $result->message
445
+ );
446
+ } else {
447
+ $return[] = array($result);
448
+ }
449
+ }
450
+ return $return;
451
+ }
452
+ }
453
+
454
+ /**
455
+ * IXR_Request
456
+ *
457
+ * @package IXR
458
+ * @since 1.5
459
+ */
460
+ class IXR_Request {
461
+ var $method;
462
+ var $args;
463
+ var $xml;
464
+ function IXR_Request($method, $args) {
465
+ $this->method = $method;
466
+ $this->args = $args;
467
+ $this->xml = <<<EOD
468
+ <?xml version="1.0"?>
469
+ <methodCall>
470
+ <methodName>{$this->method}</methodName>
471
+ <params>
472
+
473
+ EOD;
474
+ foreach ($this->args as $arg) {
475
+ $this->xml .= '<param><value>';
476
+ $v = new IXR_Value($arg);
477
+ $this->xml .= $v->getXml();
478
+ $this->xml .= "</value></param>\n";
479
+ }
480
+ $this->xml .= '</params></methodCall>';
481
+ }
482
+ function getLength() {
483
+ return strlen($this->xml);
484
+ }
485
+ function getXml() {
486
+ return $this->xml;
487
+ }
488
+ }
489
+
490
+ /**
491
+ * IXR_Client
492
+ *
493
+ * @package IXR
494
+ * @since 1.5
495
+ */
496
+ class IXR_Client {
497
+ var $server;
498
+ var $port;
499
+ var $path;
500
+ var $useragent;
501
+ var $headers;
502
+ var $response;
503
+ var $message = false;
504
+ var $debug = false;
505
+ var $timeout;
506
+ // Storage place for an error message
507
+ var $error = false;
508
+ function IXR_Client($server, $path = false, $port = 80, $timeout = false) {
509
+ if (!$path) {
510
+ // Assume we have been given a URL instead
511
+ $bits = parse_url($server);
512
+ $this->server = $bits['host'];
513
+ $this->port = isset($bits['port']) ? $bits['port'] : 80;
514
+ $this->path = isset($bits['path']) ? $bits['path'] : '/';
515
+ // Make absolutely sure we have a path
516
+ if (!$this->path) {
517
+ $this->path = '/';
518
+ }
519
+ } else {
520
+ $this->server = $server;
521
+ $this->path = $path;
522
+ $this->port = $port;
523
+ }
524
+ $this->useragent = 'The Incutio XML-RPC PHP Library';
525
+ $this->timeout = $timeout;
526
+ }
527
+ function query() {
528
+ $args = func_get_args();
529
+ $method = array_shift($args);
530
+ $request = new IXR_Request($method, $args);
531
+ $length = $request->getLength();
532
+ $xml = $request->getXml();
533
+ $r = "\r\n";
534
+ $request = "POST {$this->path} HTTP/1.0$r";
535
+
536
+ $this->headers['Host'] = $this->server;
537
+ $this->headers['Content-Type'] = 'text/xml';
538
+ $this->headers['User-Agent'] = $this->useragent;
539
+ $this->headers['Content-Length']= $length;
540
+
541
+ foreach( $this->headers as $header => $value ) {
542
+ $request .= "{$header}: {$value}{$r}";
543
+ }
544
+ $request .= $r;
545
+
546
+ $request .= $xml;
547
+ // Now send the request
548
+ if ($this->debug) {
549
+ echo '<pre class="ixr_request">'.htmlspecialchars($request)."\n</pre>\n\n";
550
+ }
551
+ if ($this->timeout) {
552
+ $fp = @fsockopen($this->server, $this->port, $errno, $errstr, $this->timeout);
553
+ } else {
554
+ $fp = @fsockopen($this->server, $this->port, $errno, $errstr);
555
+ }
556
+ if (!$fp) {
557
+ $this->error = new IXR_Error(-32300, "transport error - could not open socket: $errno $errstr");
558
+ return false;
559
+ }
560
+ fputs($fp, $request);
561
+ $contents = '';
562
+ $debug_contents = '';
563
+ $gotFirstLine = false;
564
+ $gettingHeaders = true;
565
+ while (!feof($fp)) {
566
+ $line = fgets($fp, 4096);
567
+ if (!$gotFirstLine) {
568
+ // Check line for '200'
569
+ if (strstr($line, '200') === false) {
570
+ $this->error = new IXR_Error(-32301, 'transport error - HTTP status code was not 200');
571
+ return false;
572
+ }
573
+ $gotFirstLine = true;
574
+ }
575
+ if (trim($line) == '') {
576
+ $gettingHeaders = false;
577
+ }
578
+ if (!$gettingHeaders) {
579
+ $contents .= trim($line);
580
+ }
581
+ if ($this->debug) {
582
+ $debug_contents .= $line;
583
+ }
584
+ }
585
+ if ($this->debug) {
586
+ echo '<pre class="ixr_response">'.htmlspecialchars($debug_contents)."\n</pre>\n\n";
587
+ }
588
+ // Now parse what we've got back
589
+ $this->message = new IXR_Message($contents);
590
+ if (!$this->message->parse()) {
591
+ // XML error
592
+ $this->error = new IXR_Error(-32700, 'parse error. not well formed');
593
+ return false;
594
+ }
595
+ // Is the message a fault?
596
+ if ($this->message->messageType == 'fault') {
597
+ $this->error = new IXR_Error($this->message->faultCode, $this->message->faultString);
598
+ return false;
599
+ }
600
+ // Message must be OK
601
+ return true;
602
+ }
603
+ function getResponse() {
604
+ // methodResponses can only have one param - return that
605
+ return $this->message->params[0];
606
+ }
607
+ function isError() {
608
+ return (is_object($this->error));
609
+ }
610
+ function getErrorCode() {
611
+ return $this->error->code;
612
+ }
613
+ function getErrorMessage() {
614
+ return $this->error->message;
615
+ }
616
+ }
617
+
618
+ /**
619
+ * IXR_Error
620
+ *
621
+ * @package IXR
622
+ * @since 1.5
623
+ */
624
+ class IXR_Error {
625
+ var $code;
626
+ var $message;
627
+ function IXR_Error($code, $message) {
628
+ $this->code = $code;
629
+ // WP adds htmlspecialchars(). See #5666
630
+ $this->message = htmlspecialchars($message);
631
+ }
632
+ function getXml() {
633
+ $xml = <<<EOD
634
+ <methodResponse>
635
+ <fault>
636
+ <value>
637
+ <struct>
638
+ <member>
639
+ <name>faultCode</name>
640
+ <value><int>{$this->code}</int></value>
641
+ </member>
642
+ <member>
643
+ <name>faultString</name>
644
+ <value><string>{$this->message}</string></value>
645
+ </member>
646
+ </struct>
647
+ </value>
648
+ </fault>
649
+ </methodResponse>
650
+
651
+ EOD;
652
+ return $xml;
653
+ }
654
+ }
655
+
656
+ /**
657
+ * IXR_Date
658
+ *
659
+ * @package IXR
660
+ * @since 1.5
661
+ */
662
+ class IXR_Date {
663
+ var $year;
664
+ var $month;
665
+ var $day;
666
+ var $hour;
667
+ var $minute;
668
+ var $second;
669
+ var $timezone;
670
+ function IXR_Date($time) {
671
+ // $time can be a PHP timestamp or an ISO one
672
+ if (is_numeric($time)) {
673
+ $this->parseTimestamp($time);
674
+ } else {
675
+ $this->parseIso($time);
676
+ }
677
+ }
678
+ function parseTimestamp($timestamp) {
679
+ $this->year = date('Y', $timestamp);
680
+ $this->month = date('m', $timestamp);
681
+ $this->day = date('d', $timestamp);
682
+ $this->hour = date('H', $timestamp);
683
+ $this->minute = date('i', $timestamp);
684
+ $this->second = date('s', $timestamp);
685
+ // WP adds timezone. See #2036
686
+ $this->timezone = '';
687
+ }
688
+ function parseIso($iso) {
689
+ $this->year = substr($iso, 0, 4);
690
+ $this->month = substr($iso, 4, 2);
691
+ $this->day = substr($iso, 6, 2);
692
+ $this->hour = substr($iso, 9, 2);
693
+ $this->minute = substr($iso, 12, 2);
694
+ $this->second = substr($iso, 15, 2);
695
+ // WP adds timezone. See #2036
696
+ $this->timezone = substr($iso, 17);
697
+ }
698
+ function getIso() {
699
+ // WP adds timezone. See #2036
700
+ return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second.$this->timezone;
701
+ }
702
+ function getXml() {
703
+ return '<dateTime.iso8601>'.$this->getIso().'</dateTime.iso8601>';
704
+ }
705
+ function getTimestamp() {
706
+ return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);
707
+ }
708
+ }
709
+
710
+ /**
711
+ * IXR_Base64
712
+ *
713
+ * @package IXR
714
+ * @since 1.5
715
+ */
716
+ class IXR_Base64 {
717
+ var $data;
718
+ function IXR_Base64($data) {
719
+ $this->data = $data;
720
+ }
721
+ function getXml() {
722
+ return '<base64>'.base64_encode($this->data).'</base64>';
723
+ }
724
+ }
725
+
726
+ /**
727
+ * IXR_IntrospectionServer
728
+ *
729
+ * @package IXR
730
+ * @since 1.5
731
+ */
732
+ class IXR_IntrospectionServer extends IXR_Server {
733
+ var $signatures;
734
+ var $help;
735
+ function IXR_IntrospectionServer() {
736
+ $this->setCallbacks();
737
+ $this->setCapabilities();
738
+ $this->capabilities['introspection'] = array(
739
+ 'specUrl' => 'http://xmlrpc.usefulinc.com/doc/reserved.html',
740
+ 'specVersion' => 1
741
+ );
742
+ $this->addCallback(
743
+ 'system.methodSignature',
744
+ 'this:methodSignature',
745
+ array('array', 'string'),
746
+ 'Returns an array describing the return type and required parameters of a method'
747
+ );
748
+ $this->addCallback(
749
+ 'system.getCapabilities',
750
+ 'this:getCapabilities',
751
+ array('struct'),
752
+ 'Returns a struct describing the XML-RPC specifications supported by this server'
753
+ );
754
+ $this->addCallback(
755
+ 'system.listMethods',
756
+ 'this:listMethods',
757
+ array('array'),
758
+ 'Returns an array of available methods on this server'
759
+ );
760
+ $this->addCallback(
761
+ 'system.methodHelp',
762
+ 'this:methodHelp',
763
+ array('string', 'string'),
764
+ 'Returns a documentation string for the specified method'
765
+ );
766
+ }
767
+ function addCallback($method, $callback, $args, $help) {
768
+ $this->callbacks[$method] = $callback;
769
+ $this->signatures[$method] = $args;
770
+ $this->help[$method] = $help;
771
+ }
772
+ function call($methodname, $args) {
773
+ // Make sure it's in an array
774
+ if ($args && !is_array($args)) {
775
+ $args = array($args);
776
+ }
777
+ // Over-rides default call method, adds signature check
778
+ if (!$this->hasMethod($methodname)) {
779
+ return new IXR_Error(-32601, 'server error. requested method "'.$this->message->methodName.'" not specified.');
780
+ }
781
+ $method = $this->callbacks[$methodname];
782
+ $signature = $this->signatures[$methodname];
783
+ $returnType = array_shift($signature);
784
+ // Check the number of arguments
785
+ if (count($args) != count($signature)) {
786
+ return new IXR_Error(-32602, 'server error. wrong number of method parameters');
787
+ }
788
+ // Check the argument types
789
+ $ok = true;
790
+ $argsbackup = $args;
791
+ for ($i = 0, $j = count($args); $i < $j; $i++) {
792
+ $arg = array_shift($args);
793
+ $type = array_shift($signature);
794
+ switch ($type) {
795
+ case 'int':
796
+ case 'i4':
797
+ if (is_array($arg) || !is_int($arg)) {
798
+ $ok = false;
799
+ }
800
+ break;
801
+ case 'base64':
802
+ case 'string':
803
+ if (!is_string($arg)) {
804
+ $ok = false;
805
+ }
806
+ break;
807
+ case 'boolean':
808
+ if ($arg !== false && $arg !== true) {
809
+ $ok = false;
810
+ }
811
+ break;
812
+ case 'float':
813
+ case 'double':
814
+ if (!is_float($arg)) {
815
+ $ok = false;
816
+ }
817
+ break;
818
+ case 'date':
819
+ case 'dateTime.iso8601':
820
+ if (!is_a($arg, 'IXR_Date')) {
821
+ $ok = false;
822
+ }
823
+ break;
824
+ }
825
+ if (!$ok) {
826
+ return new IXR_Error(-32602, 'server error. invalid method parameters');
827
+ }
828
+ }
829
+ // It passed the test - run the "real" method call
830
+ return parent::call($methodname, $argsbackup);
831
+ }
832
+ function methodSignature($method) {
833
+ if (!$this->hasMethod($method)) {
834
+ return new IXR_Error(-32601, 'server error. requested method "'.$method.'" not specified.');
835
+ }
836
+ // We should be returning an array of types
837
+ $types = $this->signatures[$method];
838
+ $return = array();
839
+ foreach ($types as $type) {
840
+ switch ($type) {
841
+ case 'string':
842
+ $return[] = 'string';
843
+ break;
844
+ case 'int':
845
+ case 'i4':
846
+ $return[] = 42;
847
+ break;
848
+ case 'double':
849
+ $return[] = 3.1415;
850
+ break;
851
+ case 'dateTime.iso8601':
852
+ $return[] = new IXR_Date(time());
853
+ break;
854
+ case 'boolean':
855
+ $return[] = true;
856
+ break;
857
+ case 'base64':
858
+ $return[] = new IXR_Base64('base64');
859
+ break;
860
+ case 'array':
861
+ $return[] = array('array');
862
+ break;
863
+ case 'struct':
864
+ $return[] = array('struct' => 'struct');
865
+ break;
866
+ }
867
+ }
868
+ return $return;
869
+ }
870
+ function methodHelp($method) {
871
+ return $this->help[$method];
872
+ }
873
+ }
874
+
875
+ /**
876
+ * IXR_ClientMulticall
877
+ *
878
+ * @package IXR
879
+ * @since 1.5
880
+ */
881
+ class IXR_ClientMulticall extends IXR_Client {
882
+ var $calls = array();
883
+ function IXR_ClientMulticall($server, $path = false, $port = 80) {
884
+ parent::IXR_Client($server, $path, $port);
885
+ $this->useragent = 'The Incutio XML-RPC PHP Library (multicall client)';
886
+ }
887
+ function addCall() {
888
+ $args = func_get_args();
889
+ $methodName = array_shift($args);
890
+ $struct = array(
891
+ 'methodName' => $methodName,
892
+ 'params' => $args
893
+ );
894
+ $this->calls[] = $struct;
895
+ }
896
+ function query() {
897
+ // Prepare multicall, then call the parent::query() method
898
+ return parent::query('system.multicall', $this->calls);
899
+ }
900
+ }
bp-forums/bbpress/bb-includes/backpress/class.mailer-smtp.php ADDED
@@ -0,0 +1,1061 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Last sync [WP11537]
3
+
4
+ /*~ class.smtp.php
5
+ .---------------------------------------------------------------------------.
6
+ | Software: PHPMailer - PHP email class |
7
+ | Version: 2.0.4 |
8
+ | Contact: via sourceforge.net support pages (also www.codeworxtech.com) |
9
+ | Info: http://phpmailer.sourceforge.net |
10
+ | Support: http://sourceforge.net/projects/phpmailer/ |
11
+ | ------------------------------------------------------------------------- |
12
+ | Author: Andy Prevost (project admininistrator) |
13
+ | Author: Brent R. Matzelle (original founder) |
14
+ | Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved. |
15
+ | Copyright (c) 2001-2003, Brent R. Matzelle |
16
+ | ------------------------------------------------------------------------- |
17
+ | License: Distributed under the Lesser General Public License (LGPL) |
18
+ | http://www.gnu.org/copyleft/lesser.html |
19
+ | This program is distributed in the hope that it will be useful - WITHOUT |
20
+ | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
21
+ | FITNESS FOR A PARTICULAR PURPOSE. |
22
+ | ------------------------------------------------------------------------- |
23
+ | We offer a number of paid services (www.codeworxtech.com): |
24
+ | - Web Hosting on highly optimized fast and secure servers |
25
+ | - Technology Consulting |
26
+ | - Oursourcing (highly qualified programmers and graphic designers) |
27
+ '---------------------------------------------------------------------------'
28
+ */
29
+ /**
30
+ * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
31
+ * commands except TURN which will always return a not implemented
32
+ * error. SMTP also provides some utility methods for sending mail
33
+ * to an SMTP server.
34
+ * @package PHPMailer
35
+ * @author Chris Ryan
36
+ */
37
+
38
+ class SMTP
39
+ {
40
+ /**
41
+ * SMTP server port
42
+ * @var int
43
+ */
44
+ var $SMTP_PORT = 25;
45
+
46
+ /**
47
+ * SMTP reply line ending
48
+ * @var string
49
+ */
50
+ var $CRLF = "\r\n";
51
+
52
+ /**
53
+ * Sets whether debugging is turned on
54
+ * @var bool
55
+ */
56
+ var $do_debug; # the level of debug to perform
57
+
58
+ /**
59
+ * Sets VERP use on/off (default is off)
60
+ * @var bool
61
+ */
62
+ var $do_verp = false;
63
+
64
+ /**#@+
65
+ * @access private
66
+ */
67
+ var $smtp_conn; # the socket to the server
68
+ var $error; # error if any on the last call
69
+ var $helo_rply; # the reply the server sent to us for HELO
70
+ /**#@-*/
71
+
72
+ /**
73
+ * Initialize the class so that the data is in a known state.
74
+ * @access public
75
+ * @return void
76
+ */
77
+ function SMTP() {
78
+ $this->smtp_conn = 0;
79
+ $this->error = null;
80
+ $this->helo_rply = null;
81
+
82
+ $this->do_debug = 0;
83
+ }
84
+
85
+ /*************************************************************
86
+ * CONNECTION FUNCTIONS *
87
+ ***********************************************************/
88
+
89
+ /**
90
+ * Connect to the server specified on the port specified.
91
+ * If the port is not specified use the default SMTP_PORT.
92
+ * If tval is specified then a connection will try and be
93
+ * established with the server for that number of seconds.
94
+ * If tval is not specified the default is 30 seconds to
95
+ * try on the connection.
96
+ *
97
+ * SMTP CODE SUCCESS: 220
98
+ * SMTP CODE FAILURE: 421
99
+ * @access public
100
+ * @return bool
101
+ */
102
+ function Connect($host,$port=0,$tval=30) {
103
+ # set the error val to null so there is no confusion
104
+ $this->error = null;
105
+
106
+ # make sure we are __not__ connected
107
+ if($this->connected()) {
108
+ # ok we are connected! what should we do?
109
+ # for now we will just give an error saying we
110
+ # are already connected
111
+ $this->error = array("error" => "Already connected to a server");
112
+ return false;
113
+ }
114
+
115
+ if(empty($port)) {
116
+ $port = $this->SMTP_PORT;
117
+ }
118
+
119
+ #connect to the smtp server
120
+ $this->smtp_conn = fsockopen($host, # the host of the server
121
+ $port, # the port to use
122
+ $errno, # error number if any
123
+ $errstr, # error message if any
124
+ $tval); # give up after ? secs
125
+ # verify we connected properly
126
+ if(empty($this->smtp_conn)) {
127
+ $this->error = array("error" => "Failed to connect to server",
128
+ "errno" => $errno,
129
+ "errstr" => $errstr);
130
+ if($this->do_debug >= 1) {
131
+ echo "SMTP -> ERROR: " . $this->error["error"] .
132
+ ": $errstr ($errno)" . $this->CRLF;
133
+ }
134
+ return false;
135
+ }
136
+
137
+ # sometimes the SMTP server takes a little longer to respond
138
+ # so we will give it a longer timeout for the first read
139
+ // Windows still does not have support for this timeout function
140
+ if(substr(PHP_OS, 0, 3) != "WIN")
141
+ socket_set_timeout($this->smtp_conn, $tval, 0);
142
+
143
+ # get any announcement stuff
144
+ $announce = $this->get_lines();
145
+
146
+ # set the timeout of any socket functions at 1/10 of a second
147
+ //if(function_exists("socket_set_timeout"))
148
+ // socket_set_timeout($this->smtp_conn, 0, 100000);
149
+
150
+ if($this->do_debug >= 2) {
151
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce;
152
+ }
153
+
154
+ return true;
155
+ }
156
+
157
+ /**
158
+ * Performs SMTP authentication. Must be run after running the
159
+ * Hello() method. Returns true if successfully authenticated.
160
+ * @access public
161
+ * @return bool
162
+ */
163
+ function Authenticate($username, $password) {
164
+ // Start authentication
165
+ fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
166
+
167
+ $rply = $this->get_lines();
168
+ $code = substr($rply,0,3);
169
+
170
+ if($code != 334) {
171
+ $this->error =
172
+ array("error" => "AUTH not accepted from server",
173
+ "smtp_code" => $code,
174
+ "smtp_msg" => substr($rply,4));
175
+ if($this->do_debug >= 1) {
176
+ echo "SMTP -> ERROR: " . $this->error["error"] .
177
+ ": " . $rply . $this->CRLF;
178
+ }
179
+ return false;
180
+ }
181
+
182
+ // Send encoded username
183
+ fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
184
+
185
+ $rply = $this->get_lines();
186
+ $code = substr($rply,0,3);
187
+
188
+ if($code != 334) {
189
+ $this->error =
190
+ array("error" => "Username not accepted from server",
191
+ "smtp_code" => $code,
192
+ "smtp_msg" => substr($rply,4));
193
+ if($this->do_debug >= 1) {
194
+ echo "SMTP -> ERROR: " . $this->error["error"] .
195
+ ": " . $rply . $this->CRLF;
196
+ }
197
+ return false;
198
+ }
199
+
200
+ // Send encoded password
201
+ fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
202
+
203
+ $rply = $this->get_lines();
204
+ $code = substr($rply,0,3);
205
+
206
+ if($code != 235) {
207
+ $this->error =
208
+ array("error" => "Password not accepted from server",
209
+ "smtp_code" => $code,
210
+ "smtp_msg" => substr($rply,4));
211
+ if($this->do_debug >= 1) {
212
+ echo "SMTP -> ERROR: " . $this->error["error"] .
213
+ ": " . $rply . $this->CRLF;
214
+ }
215
+ return false;
216
+ }
217
+
218
+ return true;
219
+ }
220
+
221
+ /**
222
+ * Returns true if connected to a server otherwise false
223
+ * @access private
224
+ * @return bool
225
+ */
226
+ function Connected() {
227
+ if(!empty($this->smtp_conn)) {
228
+ $sock_status = socket_get_status($this->smtp_conn);
229
+ if($sock_status["eof"]) {
230
+ # hmm this is an odd situation... the socket is
231
+ # valid but we are not connected anymore
232
+ if($this->do_debug >= 1) {
233
+ echo "SMTP -> NOTICE:" . $this->CRLF .
234
+ "EOF caught while checking if connected";
235
+ }
236
+ $this->Close();
237
+ return false;
238
+ }
239
+ return true; # everything looks good
240
+ }
241
+ return false;
242
+ }
243
+
244
+ /**
245
+ * Closes the socket and cleans up the state of the class.
246
+ * It is not considered good to use this function without
247
+ * first trying to use QUIT.
248
+ * @access public
249
+ * @return void
250
+ */
251
+ function Close() {
252
+ $this->error = null; # so there is no confusion
253
+ $this->helo_rply = null;
254
+ if(!empty($this->smtp_conn)) {
255
+ # close the connection and cleanup
256
+ fclose($this->smtp_conn);
257
+ $this->smtp_conn = 0;
258
+ }
259
+ }
260
+
261
+ /***************************************************************
262
+ * SMTP COMMANDS *
263
+ *************************************************************/
264
+
265
+ /**
266
+ * Issues a data command and sends the msg_data to the server
267
+ * finializing the mail transaction. $msg_data is the message
268
+ * that is to be send with the headers. Each header needs to be
269
+ * on a single line followed by a <CRLF> with the message headers
270
+ * and the message body being seperated by and additional <CRLF>.
271
+ *
272
+ * Implements rfc 821: DATA <CRLF>
273
+ *
274
+ * SMTP CODE INTERMEDIATE: 354
275
+ * [data]
276
+ * <CRLF>.<CRLF>
277
+ * SMTP CODE SUCCESS: 250
278
+ * SMTP CODE FAILURE: 552,554,451,452
279
+ * SMTP CODE FAILURE: 451,554
280
+ * SMTP CODE ERROR : 500,501,503,421
281
+ * @access public
282
+ * @return bool
283
+ */
284
+ function Data($msg_data) {
285
+ $this->error = null; # so no confusion is caused
286
+
287
+ if(!$this->connected()) {
288
+ $this->error = array(
289
+ "error" => "Called Data() without being connected");
290
+ return false;
291
+ }
292
+
293
+ fputs($this->smtp_conn,"DATA" . $this->CRLF);
294
+
295
+ $rply = $this->get_lines();
296
+ $code = substr($rply,0,3);
297
+
298
+ if($this->do_debug >= 2) {
299
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
300
+ }
301
+
302
+ if($code != 354) {
303
+ $this->error =
304
+ array("error" => "DATA command not accepted from server",
305
+ "smtp_code" => $code,
306
+ "smtp_msg" => substr($rply,4));
307
+ if($this->do_debug >= 1) {
308
+ echo "SMTP -> ERROR: " . $this->error["error"] .
309
+ ": " . $rply . $this->CRLF;
310
+ }
311
+ return false;
312
+ }
313
+
314
+ # the server is ready to accept data!
315
+ # according to rfc 821 we should not send more than 1000
316
+ # including the CRLF
317
+ # characters on a single line so we will break the data up
318
+ # into lines by \r and/or \n then if needed we will break
319
+ # each of those into smaller lines to fit within the limit.
320
+ # in addition we will be looking for lines that start with
321
+ # a period '.' and append and additional period '.' to that
322
+ # line. NOTE: this does not count towards are limit.
323
+
324
+ # normalize the line breaks so we know the explode works
325
+ $msg_data = str_replace("\r\n","\n",$msg_data);
326
+ $msg_data = str_replace("\r","\n",$msg_data);
327
+ $lines = explode("\n",$msg_data);
328
+
329
+ # we need to find a good way to determine is headers are
330
+ # in the msg_data or if it is a straight msg body
331
+ # currently I am assuming rfc 822 definitions of msg headers
332
+ # and if the first field of the first line (':' sperated)
333
+ # does not contain a space then it _should_ be a header
334
+ # and we can process all lines before a blank "" line as
335
+ # headers.
336
+ $field = substr($lines[0],0,strpos($lines[0],":"));
337
+ $in_headers = false;
338
+ if(!empty($field) && !strstr($field," ")) {
339
+ $in_headers = true;
340
+ }
341
+
342
+ $max_line_length = 998; # used below; set here for ease in change
343
+
344
+ while(list(,$line) = @each($lines)) {
345
+ $lines_out = null;
346
+ if($line == "" && $in_headers) {
347
+ $in_headers = false;
348
+ }
349
+ # ok we need to break this line up into several
350
+ # smaller lines
351
+ while(strlen($line) > $max_line_length) {
352
+ $pos = strrpos(substr($line,0,$max_line_length)," ");
353
+
354
+ # Patch to fix DOS attack
355
+ if(!$pos) {
356
+ $pos = $max_line_length - 1;
357
+ }
358
+
359
+ $lines_out[] = substr($line,0,$pos);
360
+ $line = substr($line,$pos + 1);
361
+ # if we are processing headers we need to
362
+ # add a LWSP-char to the front of the new line
363
+ # rfc 822 on long msg headers
364
+ if($in_headers) {
365
+ $line = "\t" . $line;
366
+ }
367
+ }
368
+ $lines_out[] = $line;
369
+
370
+ # now send the lines to the server
371
+ while(list(,$line_out) = @each($lines_out)) {
372
+ if(strlen($line_out) > 0)
373
+ {
374
+ if(substr($line_out, 0, 1) == ".") {
375
+ $line_out = "." . $line_out;
376
+ }
377
+ }
378
+ fputs($this->smtp_conn,$line_out . $this->CRLF);
379
+ }
380
+ }
381
+
382
+ # ok all the message data has been sent so lets get this
383
+ # over with aleady
384
+ fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
385
+
386
+ $rply = $this->get_lines();
387
+ $code = substr($rply,0,3);
388
+
389
+ if($this->do_debug >= 2) {
390
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
391
+ }
392
+
393
+ if($code != 250) {
394
+ $this->error =
395
+ array("error" => "DATA not accepted from server",
396
+ "smtp_code" => $code,
397
+ "smtp_msg" => substr($rply,4));
398
+ if($this->do_debug >= 1) {
399
+ echo "SMTP -> ERROR: " . $this->error["error"] .
400
+ ": " . $rply . $this->CRLF;
401
+ }
402
+ return false;
403
+ }
404
+ return true;
405
+ }
406
+
407
+ /**
408
+ * Expand takes the name and asks the server to list all the
409
+ * people who are members of the _list_. Expand will return
410
+ * back and array of the result or false if an error occurs.
411
+ * Each value in the array returned has the format of:
412
+ * [ <full-name> <sp> ] <path>
413
+ * The definition of <path> is defined in rfc 821
414
+ *
415
+ * Implements rfc 821: EXPN <SP> <string> <CRLF>
416
+ *
417
+ * SMTP CODE SUCCESS: 250
418
+ * SMTP CODE FAILURE: 550
419
+ * SMTP CODE ERROR : 500,501,502,504,421
420
+ * @access public
421
+ * @return string array
422
+ */
423
+ function Expand($name) {
424
+ $this->error = null; # so no confusion is caused
425
+
426
+ if(!$this->connected()) {
427
+ $this->error = array(
428
+ "error" => "Called Expand() without being connected");
429
+ return false;
430
+ }
431
+
432
+ fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF);
433
+
434
+ $rply = $this->get_lines();
435
+ $code = substr($rply,0,3);
436
+
437
+ if($this->do_debug >= 2) {
438
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
439
+ }
440
+
441
+ if($code != 250) {
442
+ $this->error =
443
+ array("error" => "EXPN not accepted from server",
444
+ "smtp_code" => $code,
445
+ "smtp_msg" => substr($rply,4));
446
+ if($this->do_debug >= 1) {
447
+ echo "SMTP -> ERROR: " . $this->error["error"] .
448
+ ": " . $rply . $this->CRLF;
449
+ }
450
+ return false;
451
+ }
452
+
453
+ # parse the reply and place in our array to return to user
454
+ $entries = explode($this->CRLF,$rply);
455
+ while(list(,$l) = @each($entries)) {
456
+ $list[] = substr($l,4);
457
+ }
458
+
459
+ return $list;
460
+ }
461
+
462
+ /**
463
+ * Sends the HELO command to the smtp server.
464
+ * This makes sure that we and the server are in
465
+ * the same known state.
466
+ *
467
+ * Implements from rfc 821: HELO <SP> <domain> <CRLF>
468
+ *
469
+ * SMTP CODE SUCCESS: 250
470
+ * SMTP CODE ERROR : 500, 501, 504, 421
471
+ * @access public
472
+ * @return bool
473
+ */
474
+ function Hello($host="") {
475
+ $this->error = null; # so no confusion is caused
476
+
477
+ if(!$this->connected()) {
478
+ $this->error = array(
479
+ "error" => "Called Hello() without being connected");
480
+ return false;
481
+ }
482
+
483
+ # if a hostname for the HELO was not specified determine
484
+ # a suitable one to send
485
+ if(empty($host)) {
486
+ # we need to determine some sort of appopiate default
487
+ # to send to the server
488
+ $host = "localhost";
489
+ }
490
+
491
+ // Send extended hello first (RFC 2821)
492
+ if(!$this->SendHello("EHLO", $host))
493
+ {
494
+ if(!$this->SendHello("HELO", $host))
495
+ return false;
496
+ }
497
+
498
+ return true;
499
+ }
500
+
501
+ /**
502
+ * Sends a HELO/EHLO command.
503
+ * @access private
504
+ * @return bool
505
+ */
506
+ function SendHello($hello, $host) {
507
+ fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
508
+
509
+ $rply = $this->get_lines();
510
+ $code = substr($rply,0,3);
511
+
512
+ if($this->do_debug >= 2) {
513
+ echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply;
514
+ }
515
+
516
+ if($code != 250) {
517
+ $this->error =
518
+ array("error" => $hello . " not accepted from server",
519
+ "smtp_code" => $code,
520
+ "smtp_msg" => substr($rply,4));
521
+ if($this->do_debug >= 1) {
522
+ echo "SMTP -> ERROR: " . $this->error["error"] .
523
+ ": " . $rply . $this->CRLF;
524
+ }
525
+ return false;
526
+ }
527
+
528
+ $this->helo_rply = $rply;
529
+
530
+ return true;
531
+ }
532
+
533
+ /**
534
+ * Gets help information on the keyword specified. If the keyword
535
+ * is not specified then returns generic help, ussually contianing
536
+ * A list of keywords that help is available on. This function
537
+ * returns the results back to the user. It is up to the user to
538
+ * handle the returned data. If an error occurs then false is
539
+ * returned with $this->error set appropiately.
540
+ *
541
+ * Implements rfc 821: HELP [ <SP> <string> ] <CRLF>
542
+ *
543
+ * SMTP CODE SUCCESS: 211,214
544
+ * SMTP CODE ERROR : 500,501,502,504,421
545
+ * @access public
546
+ * @return string
547
+ */
548
+ function Help($keyword="") {
549
+ $this->error = null; # to avoid confusion
550
+
551
+ if(!$this->connected()) {
552
+ $this->error = array(
553
+ "error" => "Called Help() without being connected");
554
+ return false;
555
+ }
556
+
557
+ $extra = "";
558
+ if(!empty($keyword)) {
559
+ $extra = " " . $keyword;
560
+ }
561
+
562
+ fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF);
563
+
564
+ $rply = $this->get_lines();
565
+ $code = substr($rply,0,3);
566
+
567
+ if($this->do_debug >= 2) {
568
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
569
+ }
570
+
571
+ if($code != 211 && $code != 214) {
572
+ $this->error =
573
+ array("error" => "HELP not accepted from server",
574
+ "smtp_code" => $code,
575
+ "smtp_msg" => substr($rply,4));
576
+ if($this->do_debug >= 1) {
577
+ echo "SMTP -> ERROR: " . $this->error["error"] .
578
+ ": " . $rply . $this->CRLF;
579
+ }
580
+ return false;
581
+ }
582
+
583
+ return $rply;
584
+ }
585
+
586
+ /**
587
+ * Starts a mail transaction from the email address specified in
588
+ * $from. Returns true if successful or false otherwise. If True
589
+ * the mail transaction is started and then one or more Recipient
590
+ * commands may be called followed by a Data command.
591
+ *
592
+ * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
593
+ *
594
+ * SMTP CODE SUCCESS: 250
595
+ * SMTP CODE SUCCESS: 552,451,452
596
+ * SMTP CODE SUCCESS: 500,501,421
597
+ * @access public
598
+ * @return bool
599
+ */
600
+ function Mail($from) {
601
+ $this->error = null; # so no confusion is caused
602
+
603
+ if(!$this->connected()) {
604
+ $this->error = array(
605
+ "error" => "Called Mail() without being connected");
606
+ return false;
607
+ }
608
+
609
+ $useVerp = ($this->do_verp ? "XVERP" : "");
610
+ fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF);
611
+
612
+ $rply = $this->get_lines();
613
+ $code = substr($rply,0,3);
614
+
615
+ if($this->do_debug >= 2) {
616
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
617
+ }
618
+
619
+ if($code != 250) {
620
+ $this->error =
621
+ array("error" => "MAIL not accepted from server",
622
+ "smtp_code" => $code,
623
+ "smtp_msg" => substr($rply,4));
624
+ if($this->do_debug >= 1) {
625
+ echo "SMTP -> ERROR: " . $this->error["error"] .
626
+ ": " . $rply . $this->CRLF;
627
+ }
628
+ return false;
629
+ }
630
+ return true;
631
+ }
632
+
633
+ /**
634
+ * Sends the command NOOP to the SMTP server.
635
+ *
636
+ * Implements from rfc 821: NOOP <CRLF>
637
+ *
638
+ * SMTP CODE SUCCESS: 250
639
+ * SMTP CODE ERROR : 500, 421
640
+ * @access public
641
+ * @return bool
642
+ */
643
+ function Noop() {
644
+ $this->error = null; # so no confusion is caused
645
+
646
+ if(!$this->connected()) {
647
+ $this->error = array(
648
+ "error" => "Called Noop() without being connected");
649
+ return false;
650
+ }
651
+
652
+ fputs($this->smtp_conn,"NOOP" . $this->CRLF);
653
+
654
+ $rply = $this->get_lines();
655
+ $code = substr($rply,0,3);
656
+
657
+ if($this->do_debug >= 2) {
658
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
659
+ }
660
+
661
+ if($code != 250) {
662
+ $this->error =
663
+ array("error" => "NOOP not accepted from server",
664
+ "smtp_code" => $code,
665
+ "smtp_msg" => substr($rply,4));
666
+ if($this->do_debug >= 1) {
667
+ echo "SMTP -> ERROR: " . $this->error["error"] .
668
+ ": " . $rply . $this->CRLF;
669
+ }
670
+ return false;
671
+ }
672
+ return true;
673
+ }
674
+
675
+ /**
676
+ * Sends the quit command to the server and then closes the socket
677
+ * if there is no error or the $close_on_error argument is true.
678
+ *
679
+ * Implements from rfc 821: QUIT <CRLF>
680
+ *
681
+ * SMTP CODE SUCCESS: 221
682
+ * SMTP CODE ERROR : 500
683
+ * @access public
684
+ * @return bool
685
+ */
686
+ function Quit($close_on_error=true) {
687
+ $this->error = null; # so there is no confusion
688
+
689
+ if(!$this->connected()) {
690
+ $this->error = array(
691
+ "error" => "Called Quit() without being connected");
692
+ return false;
693
+ }
694
+
695
+ # send the quit command to the server
696
+ fputs($this->smtp_conn,"quit" . $this->CRLF);
697
+
698
+ # get any good-bye messages
699
+ $byemsg = $this->get_lines();
700
+
701
+ if($this->do_debug >= 2) {
702
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg;
703
+ }
704
+
705
+ $rval = true;
706
+ $e = null;
707
+
708
+ $code = substr($byemsg,0,3);
709
+ if($code != 221) {
710
+ # use e as a tmp var cause Close will overwrite $this->error
711
+ $e = array("error" => "SMTP server rejected quit command",
712
+ "smtp_code" => $code,
713
+ "smtp_rply" => substr($byemsg,4));
714
+ $rval = false;
715
+ if($this->do_debug >= 1) {
716
+ echo "SMTP -> ERROR: " . $e["error"] . ": " .
717
+ $byemsg . $this->CRLF;
718
+ }
719
+ }
720
+
721
+ if(empty($e) || $close_on_error) {
722
+ $this->Close();
723
+ }
724
+
725
+ return $rval;
726
+ }
727
+
728
+ /**
729
+ * Sends the command RCPT to the SMTP server with the TO: argument of $to.
730
+ * Returns true if the recipient was accepted false if it was rejected.
731
+ *
732
+ * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
733
+ *
734
+ * SMTP CODE SUCCESS: 250,251
735
+ * SMTP CODE FAILURE: 550,551,552,553,450,451,452
736
+ * SMTP CODE ERROR : 500,501,503,421
737
+ * @access public
738
+ * @return bool
739
+ */
740
+ function Recipient($to) {
741
+ $this->error = null; # so no confusion is caused
742
+
743
+ if(!$this->connected()) {
744
+ $this->error = array(
745
+ "error" => "Called Recipient() without being connected");
746
+ return false;
747
+ }
748
+
749
+ fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
750
+
751
+ $rply = $this->get_lines();
752
+ $code = substr($rply,0,3);
753
+
754
+ if($this->do_debug >= 2) {
755
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
756
+ }
757
+
758
+ if($code != 250 && $code != 251) {
759
+ $this->error =
760
+ array("error" => "RCPT not accepted from server",
761
+ "smtp_code" => $code,
762
+ "smtp_msg" => substr($rply,4));
763
+ if($this->do_debug >= 1) {
764
+ echo "SMTP -> ERROR: " . $this->error["error"] .
765
+ ": " . $rply . $this->CRLF;
766
+ }
767
+ return false;
768
+ }
769
+ return true;
770
+ }
771
+
772
+ /**
773
+ * Sends the RSET command to abort and transaction that is
774
+ * currently in progress. Returns true if successful false
775
+ * otherwise.
776
+ *
777
+ * Implements rfc 821: RSET <CRLF>
778
+ *
779
+ * SMTP CODE SUCCESS: 250
780
+ * SMTP CODE ERROR : 500,501,504,421
781
+ * @access public
782
+ * @return bool
783
+ */
784
+ function Reset() {
785
+ $this->error = null; # so no confusion is caused
786
+
787
+ if(!$this->connected()) {
788
+ $this->error = array(
789
+ "error" => "Called Reset() without being connected");
790
+ return false;
791
+ }
792
+
793
+ fputs($this->smtp_conn,"RSET" . $this->CRLF);
794
+
795
+ $rply = $this->get_lines();
796
+ $code = substr($rply,0,3);
797
+
798
+ if($this->do_debug >= 2) {
799
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
800
+ }
801
+
802
+ if($code != 250) {
803
+ $this->error =
804
+ array("error" => "RSET failed",
805
+ "smtp_code" => $code,
806
+ "smtp_msg" => substr($rply,4));
807
+ if($this->do_debug >= 1) {
808
+ echo "SMTP -> ERROR: " . $this->error["error"] .
809
+ ": " . $rply . $this->CRLF;
810
+ }
811
+ return false;
812
+ }
813
+
814
+ return true;
815
+ }
816
+
817
+ /**
818
+ * Starts a mail transaction from the email address specified in
819
+ * $from. Returns true if successful or false otherwise. If True
820
+ * the mail transaction is started and then one or more Recipient
821
+ * commands may be called followed by a Data command. This command
822
+ * will send the message to the users terminal if they are logged
823
+ * in.
824
+ *
825
+ * Implements rfc 821: SEND <SP> FROM:<reverse-path> <CRLF>
826
+ *
827
+ * SMTP CODE SUCCESS: 250
828
+ * SMTP CODE SUCCESS: 552,451,452
829
+ * SMTP CODE SUCCESS: 500,501,502,421
830
+ * @access public
831
+ * @return bool
832
+ */
833
+ function Send($from) {
834
+ $this->error = null; # so no confusion is caused
835
+
836
+ if(!$this->connected()) {
837
+ $this->error = array(
838
+ "error" => "Called Send() without being connected");
839
+ return false;
840
+ }
841
+
842
+ fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF);
843
+
844
+ $rply = $this->get_lines();
845
+ $code = substr($rply,0,3);
846
+
847
+ if($this->do_debug >= 2) {
848
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
849
+ }
850
+
851
+ if($code != 250) {
852
+ $this->error =
853
+ array("error" => "SEND not accepted from server",
854
+ "smtp_code" => $code,
855
+ "smtp_msg" => substr($rply,4));
856
+ if($this->do_debug >= 1) {
857
+ echo "SMTP -> ERROR: " . $this->error["error"] .
858
+ ": " . $rply . $this->CRLF;
859
+ }
860
+ return false;
861
+ }
862
+ return true;
863
+ }
864
+
865
+ /**
866
+ * Starts a mail transaction from the email address specified in
867
+ * $from. Returns true if successful or false otherwise. If True
868
+ * the mail transaction is started and then one or more Recipient
869
+ * commands may be called followed by a Data command. This command
870
+ * will send the message to the users terminal if they are logged
871
+ * in and send them an email.
872
+ *
873
+ * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
874
+ *
875
+ * SMTP CODE SUCCESS: 250
876
+ * SMTP CODE SUCCESS: 552,451,452
877
+ * SMTP CODE SUCCESS: 500,501,502,421
878
+ * @access public
879
+ * @return bool
880
+ */
881
+ function SendAndMail($from) {
882
+ $this->error = null; # so no confusion is caused
883
+
884
+ if(!$this->connected()) {
885
+ $this->error = array(
886
+ "error" => "Called SendAndMail() without being connected");
887
+ return false;
888
+ }
889
+
890
+ fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
891
+
892
+ $rply = $this->get_lines();
893
+ $code = substr($rply,0,3);
894
+
895
+ if($this->do_debug >= 2) {
896
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
897
+ }
898
+
899
+ if($code != 250) {
900
+ $this->error =
901
+ array("error" => "SAML not accepted from server",
902
+ "smtp_code" => $code,
903
+ "smtp_msg" => substr($rply,4));
904
+ if($this->do_debug >= 1) {
905
+ echo "SMTP -> ERROR: " . $this->error["error"] .
906
+ ": " . $rply . $this->CRLF;
907
+ }
908
+ return false;
909
+ }
910
+ return true;
911
+ }
912
+
913
+ /**
914
+ * Starts a mail transaction from the email address specified in
915
+ * $from. Returns true if successful or false otherwise. If True
916
+ * the mail transaction is started and then one or more Recipient
917
+ * commands may be called followed by a Data command. This command
918
+ * will send the message to the users terminal if they are logged
919
+ * in or mail it to them if they are not.
920
+ *
921
+ * Implements rfc 821: SOML <SP> FROM:<reverse-path> <CRLF>
922
+ *
923
+ * SMTP CODE SUCCESS: 250
924
+ * SMTP CODE SUCCESS: 552,451,452
925
+ * SMTP CODE SUCCESS: 500,501,502,421
926
+ * @access public
927
+ * @return bool
928
+ */
929
+ function SendOrMail($from) {
930
+ $this->error = null; # so no confusion is caused
931
+
932
+ if(!$this->connected()) {
933
+ $this->error = array(
934
+ "error" => "Called SendOrMail() without being connected");
935
+ return false;
936
+ }
937
+
938
+ fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF);
939
+
940
+ $rply = $this->get_lines();
941
+ $code = substr($rply,0,3);
942
+
943
+ if($this->do_debug >= 2) {
944
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
945
+ }
946
+
947
+ if($code != 250) {
948
+ $this->error =
949
+ array("error" => "SOML not accepted from server",
950
+ "smtp_code" => $code,
951
+ "smtp_msg" => substr($rply,4));
952
+ if($this->do_debug >= 1) {
953
+ echo "SMTP -> ERROR: " . $this->error["error"] .
954
+ ": " . $rply . $this->CRLF;
955
+ }
956
+ return false;
957
+ }
958
+ return true;
959
+ }
960
+
961
+ /**
962
+ * This is an optional command for SMTP that this class does not
963
+ * support. This method is here to make the RFC821 Definition
964
+ * complete for this class and __may__ be implimented in the future
965
+ *
966
+ * Implements from rfc 821: TURN <CRLF>
967
+ *
968
+ * SMTP CODE SUCCESS: 250
969
+ * SMTP CODE FAILURE: 502
970
+ * SMTP CODE ERROR : 500, 503
971
+ * @access public
972
+ * @return bool
973
+ */
974
+ function Turn() {
975
+ $this->error = array("error" => "This method, TURN, of the SMTP ".
976
+ "is not implemented");
977
+ if($this->do_debug >= 1) {
978
+ echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF;
979
+ }
980
+ return false;
981
+ }
982
+
983
+ /**
984
+ * Verifies that the name is recognized by the server.
985
+ * Returns false if the name could not be verified otherwise
986
+ * the response from the server is returned.
987
+ *
988
+ * Implements rfc 821: VRFY <SP> <string> <CRLF>
989
+ *
990
+ * SMTP CODE SUCCESS: 250,251
991
+ * SMTP CODE FAILURE: 550,551,553
992
+ * SMTP CODE ERROR : 500,501,502,421
993
+ * @access public
994
+ * @return int
995
+ */
996
+ function Verify($name) {
997
+ $this->error = null; # so no confusion is caused
998
+
999
+ if(!$this->connected()) {
1000
+ $this->error = array(
1001
+ "error" => "Called Verify() without being connected");
1002
+ return false;
1003
+ }
1004
+
1005
+ fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF);
1006
+
1007
+ $rply = $this->get_lines();
1008
+ $code = substr($rply,0,3);
1009
+
1010
+ if($this->do_debug >= 2) {
1011
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
1012
+ }
1013
+
1014
+ if($code != 250 && $code != 251) {
1015
+ $this->error =
1016
+ array("error" => "VRFY failed on name '$name'",
1017
+ "smtp_code" => $code,
1018
+ "smtp_msg" => substr($rply,4));
1019
+ if($this->do_debug >= 1) {
1020
+ echo "SMTP -> ERROR: " . $this->error["error"] .
1021
+ ": " . $rply . $this->CRLF;
1022
+ }
1023
+ return false;
1024
+ }
1025
+ return $rply;
1026
+ }
1027
+
1028
+ /*******************************************************************
1029
+ * INTERNAL FUNCTIONS *
1030
+ ******************************************************************/
1031
+
1032
+ /**
1033
+ * Read in as many lines as possible
1034
+ * either before eof or socket timeout occurs on the operation.
1035
+ * With SMTP we can tell if we have more lines to read if the
1036
+ * 4th character is '-' symbol. If it is a space then we don't
1037
+ * need to read anything else.
1038
+ * @access private
1039
+ * @return string
1040
+ */
1041
+ function get_lines() {
1042
+ $data = "";
1043
+ while($str = @fgets($this->smtp_conn,515)) {
1044
+ if($this->do_debug >= 4) {
1045
+ echo "SMTP -> get_lines(): \$data was \"$data\"" .
1046
+ $this->CRLF;
1047
+ echo "SMTP -> get_lines(): \$str is \"$str\"" .
1048
+ $this->CRLF;
1049
+ }
1050
+ $data .= $str;
1051
+ if($this->do_debug >= 4) {
1052
+ echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF;
1053
+ }
1054
+ # if the 4th character is a space then we are done reading
1055
+ # so just break the loop
1056
+ if(substr($str,3,1) == " ") { break; }
1057
+ }
1058
+ return $data;
1059
+ }
1060
+
1061
+ }
bp-forums/bbpress/bb-includes/backpress/class.mailer.php ADDED
@@ -0,0 +1,1921 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Last sync [WP11537]
3
+
4
+ /*~ class.phpmailer.php
5
+ .---------------------------------------------------------------------------.
6
+ | Software: PHPMailer - PHP email class |
7
+ | Version: 2.0.4 |
8
+ | Contact: via sourceforge.net support pages (also www.codeworxtech.com) |
9
+ | Info: http://phpmailer.sourceforge.net |
10
+ | Support: http://sourceforge.net/projects/phpmailer/ |
11
+ | ------------------------------------------------------------------------- |
12
+ | Author: Andy Prevost (project admininistrator) |
13
+ | Author: Brent R. Matzelle (original founder) |
14
+ | Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved. |
15
+ | Copyright (c) 2001-2003, Brent R. Matzelle |
16
+ | ------------------------------------------------------------------------- |
17
+ | License: Distributed under the Lesser General Public License (LGPL) |
18
+ | http://www.gnu.org/copyleft/lesser.html |
19
+ | This program is distributed in the hope that it will be useful - WITHOUT |
20
+ | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
21
+ | FITNESS FOR A PARTICULAR PURPOSE. |
22
+ | ------------------------------------------------------------------------- |
23
+ | We offer a number of paid services (www.codeworxtech.com): |
24
+ | - Web Hosting on highly optimized fast and secure servers |
25
+ | - Technology Consulting |
26
+ | - Oursourcing (highly qualified programmers and graphic designers) |
27
+ '---------------------------------------------------------------------------'
28
+ */
29
+ /**
30
+ * PHPMailer - PHP email transport class
31
+ * @package PHPMailer
32
+ * @author Andy Prevost
33
+ * @copyright 2004 - 2009 Andy Prevost
34
+ */
35
+
36
+ class PHPMailer {
37
+
38
+ /////////////////////////////////////////////////
39
+ // PROPERTIES, PUBLIC
40
+ /////////////////////////////////////////////////
41
+
42
+ /**
43
+ * Email priority (1 = High, 3 = Normal, 5 = low).
44
+ * @var int
45
+ */
46
+ var $Priority = 3;
47
+
48
+ /**
49
+ * Sets the CharSet of the message.
50
+ * @var string
51
+ */
52
+ var $CharSet = 'iso-8859-1';
53
+
54
+ /**
55
+ * Sets the Content-type of the message.
56
+ * @var string
57
+ */
58
+ var $ContentType = 'text/plain';
59
+
60
+ /**
61
+ * Sets the Encoding of the message. Options for this are "8bit",
62
+ * "7bit", "binary", "base64", and "quoted-printable".
63
+ * @var string
64
+ */
65
+ var $Encoding = '8bit';
66
+
67
+ /**
68
+ * Holds the most recent mailer error message.
69
+ * @var string
70
+ */
71
+ var $ErrorInfo = '';
72
+
73
+ /**
74
+ * Sets the From email address for the message.
75
+ * @var string
76
+ */
77
+ var $From = 'root@localhost';
78
+
79
+ /**
80
+ * Sets the From name of the message.
81
+ * @var string
82
+ */
83
+ var $FromName = 'Root User';
84
+
85
+ /**
86
+ * Sets the Sender email (Return-Path) of the message. If not empty,
87
+ * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
88
+ * @var string
89
+ */
90
+ var $Sender = '';
91
+
92
+ /**
93
+ * Sets the Subject of the message.
94
+ * @var string
95
+ */
96
+ var $Subject = '';
97
+
98
+ /**
99
+ * Sets the Body of the message. This can be either an HTML or text body.
100
+ * If HTML then run IsHTML(true).
101
+ * @var string
102
+ */
103
+ var $Body = '';
104
+
105
+ /**
106
+ * Sets the text-only body of the message. This automatically sets the
107
+ * email to multipart/alternative. This body can be read by mail
108
+ * clients that do not have HTML email capability such as mutt. Clients
109
+ * that can read HTML will view the normal Body.
110
+ * @var string
111
+ */
112
+ var $AltBody = '';
113
+
114
+ /**
115
+ * Sets word wrapping on the body of the message to a given number of
116
+ * characters.
117
+ * @var int
118
+ */
119
+ var $WordWrap = 0;
120
+
121
+ /**
122
+ * Method to send mail: ("mail", "sendmail", or "smtp").
123
+ * @var string
124
+ */
125
+ var $Mailer = 'mail';
126
+
127
+ /**
128
+ * Sets the path of the sendmail program.
129
+ * @var string
130
+ */
131
+ var $Sendmail = '/usr/sbin/sendmail';
132
+
133
+ /**
134
+ * Path to PHPMailer plugins. This is now only useful if the SMTP class
135
+ * is in a different directory than the PHP include path.
136
+ * @var string
137
+ */
138
+ var $PluginDir = '';
139
+
140
+ /**
141
+ * Holds PHPMailer version.
142
+ * @var string
143
+ */
144
+ var $Version = "2.0.4";
145
+
146
+ /**
147
+ * Sets the email address that a reading confirmation will be sent.
148
+ * @var string
149
+ */
150
+ var $ConfirmReadingTo = '';
151
+
152
+ /**
153
+ * Sets the hostname to use in Message-Id and Received headers
154
+ * and as default HELO string. If empty, the value returned
155
+ * by SERVER_NAME is used or 'localhost.localdomain'.
156
+ * @var string
157
+ */
158
+ var $Hostname = '';
159
+
160
+ /**
161
+ * Sets the message ID to be used in the Message-Id header.
162
+ * If empty, a unique id will be generated.
163
+ * @var string
164
+ */
165
+ var $MessageID = '';
166
+
167
+ /////////////////////////////////////////////////
168
+ // PROPERTIES FOR SMTP
169
+ /////////////////////////////////////////////////
170
+
171
+ /**
172
+ * Sets the SMTP hosts. All hosts must be separated by a
173
+ * semicolon. You can also specify a different port
174
+ * for each host by using this format: [hostname:port]
175
+ * (e.g. "smtp1.example.com:25;smtp2.example.com").
176
+ * Hosts will be tried in order.
177
+ * @var string
178
+ */
179
+ var $Host = 'localhost';
180
+
181
+ /**
182
+ * Sets the default SMTP server port.
183
+ * @var int
184
+ */
185
+ var $Port = 25;
186
+
187
+ /**
188
+ * Sets the SMTP HELO of the message (Default is $Hostname).
189
+ * @var string
190
+ */
191
+ var $Helo = '';
192
+
193
+ /**
194
+ * Sets connection prefix.
195
+ * Options are "", "ssl" or "tls"
196
+ * @var string
197
+ */
198
+ var $SMTPSecure = "";
199
+
200
+ /**
201
+ * Sets SMTP authentication. Utilizes the Username and Password variables.
202
+ * @var bool
203
+ */
204
+ var $SMTPAuth = false;
205
+
206
+ /**
207
+ * Sets SMTP username.
208
+ * @var string
209
+ */
210
+ var $Username = '';
211
+
212
+ /**
213
+ * Sets SMTP password.
214
+ * @var string
215
+ */
216
+ var $Password = '';
217
+
218
+ /**
219
+ * Sets the SMTP server timeout in seconds. This function will not
220
+ * work with the win32 version.
221
+ * @var int
222
+ */
223
+ var $Timeout = 10;
224
+
225
+ /**
226
+ * Sets SMTP class debugging on or off.
227
+ * @var bool
228
+ */
229
+ var $SMTPDebug = false;
230
+
231
+ /**
232
+ * Prevents the SMTP connection from being closed after each mail
233
+ * sending. If this is set to true then to close the connection
234
+ * requires an explicit call to SmtpClose().
235
+ * @var bool
236
+ */
237
+ var $SMTPKeepAlive = false;
238
+
239
+ /**
240
+ * Provides the ability to have the TO field process individual
241
+ * emails, instead of sending to entire TO addresses
242
+ * @var bool
243
+ */
244
+ var $SingleTo = false;
245
+
246
+ /////////////////////////////////////////////////
247
+ // PROPERTIES, PRIVATE
248
+ /////////////////////////////////////////////////
249
+
250
+ var $smtp = NULL;
251
+ var $to = array();
252
+ var $cc = array();
253
+ var $bcc = array();
254
+ var $ReplyTo = array();
255
+ var $attachment = array();
256
+ var $CustomHeader = array();
257
+ var $message_type = '';
258
+ var $boundary = array();
259
+ var $language = array();
260
+ var $error_count = 0;
261
+ var $LE = "\n";
262
+ var $sign_cert_file = "";
263
+ var $sign_key_file = "";
264
+ var $sign_key_pass = "";
265
+
266
+ /////////////////////////////////////////////////
267
+ // METHODS, VARIABLES
268
+ /////////////////////////////////////////////////
269
+
270
+ /**
271
+ * Sets message type to HTML.
272
+ * @param bool $bool
273
+ * @return void
274
+ */
275
+ function IsHTML($bool) {
276
+ if($bool == true) {
277
+ $this->ContentType = 'text/html';
278
+ } else {
279
+ $this->ContentType = 'text/plain';
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Sets Mailer to send message using SMTP.
285
+ * @return void
286
+ */
287
+ function IsSMTP() {
288
+ $this->Mailer = 'smtp';
289
+ }
290
+
291
+ /**
292
+ * Sets Mailer to send message using PHP mail() function.
293
+ * @return void
294
+ */
295
+ function IsMail() {
296
+ $this->Mailer = 'mail';
297
+ }
298
+
299
+ /**
300
+ * Sets Mailer to send message using the $Sendmail program.
301
+ * @return void
302
+ */
303
+ function IsSendmail() {
304
+ $this->Mailer = 'sendmail';
305
+ }
306
+
307
+ /**
308
+ * Sets Mailer to send message using the qmail MTA.
309
+ * @return void
310
+ */
311
+ function IsQmail() {
312
+ $this->Sendmail = '/var/qmail/bin/sendmail';
313
+ $this->Mailer = 'sendmail';
314
+ }
315
+
316
+ /////////////////////////////////////////////////
317
+ // METHODS, RECIPIENTS
318
+ /////////////////////////////////////////////////
319
+
320
+ /**
321
+ * Adds a "To" address.
322
+ * @param string $address
323
+ * @param string $name
324
+ * @return void
325
+ */
326
+ function AddAddress($address, $name = '') {
327
+ $cur = count($this->to);
328
+ $this->to[$cur][0] = trim($address);
329
+ $this->to[$cur][1] = $name;
330
+ }
331
+
332
+ /**
333
+ * Adds a "Cc" address. Note: this function works
334
+ * with the SMTP mailer on win32, not with the "mail"
335
+ * mailer.
336
+ * @param string $address
337
+ * @param string $name
338
+ * @return void
339
+ */
340
+ function AddCC($address, $name = '') {
341
+ $cur = count($this->cc);
342
+ $this->cc[$cur][0] = trim($address);
343
+ $this->cc[$cur][1] = $name;
344
+ }
345
+
346
+ /**
347
+ * Adds a "Bcc" address. Note: this function works
348
+ * with the SMTP mailer on win32, not with the "mail"
349
+ * mailer.
350
+ * @param string $address
351
+ * @param string $name
352
+ * @return void
353
+ */
354
+ function AddBCC($address, $name = '') {
355
+ $cur = count($this->bcc);
356
+ $this->bcc[$cur][0] = trim($address);
357
+ $this->bcc[$cur][1] = $name;
358
+ }
359
+
360
+ /**
361
+ * Adds a "Reply-To" address.
362
+ * @param string $address
363
+ * @param string $name
364
+ * @return void
365
+ */
366
+ function AddReplyTo($address, $name = '') {
367
+ $cur = count($this->ReplyTo);
368
+ $this->ReplyTo[$cur][0] = trim($address);
369
+ $this->ReplyTo[$cur][1] = $name;
370
+ }
371
+
372
+ /////////////////////////////////////////////////
373
+ // METHODS, MAIL SENDING
374
+ /////////////////////////////////////////////////
375
+
376
+ /**
377
+ * Creates message and assigns Mailer. If the message is
378
+ * not sent successfully then it returns false. Use the ErrorInfo
379
+ * variable to view description of the error.
380
+ * @return bool
381
+ */
382
+ function Send() {
383
+ $header = '';
384
+ $body = '';
385
+ $result = true;
386
+
387
+ if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
388
+ $this->SetError($this->Lang('provide_address'));
389
+ return false;
390
+ }
391
+
392
+ /* Set whether the message is multipart/alternative */
393
+ if(!empty($this->AltBody)) {
394
+ $this->ContentType = 'multipart/alternative';
395
+ }
396
+
397
+ $this->error_count = 0; // reset errors
398
+ $this->SetMessageType();
399
+ $header .= $this->CreateHeader();
400
+ $body = $this->CreateBody();
401
+
402
+ if($body == '') {
403
+ return false;
404
+ }
405
+
406
+ /* Choose the mailer */
407
+ switch($this->Mailer) {
408
+ case 'sendmail':
409
+ $result = $this->SendmailSend($header, $body);
410
+ break;
411
+ case 'smtp':
412
+ $result = $this->SmtpSend($header, $body);
413
+ break;
414
+ case 'mail':
415
+ $result = $this->MailSend($header, $body);
416
+ break;
417
+ default:
418
+ $result = $this->MailSend($header, $body);
419
+ break;
420
+ //$this->SetError($this->Mailer . $this->Lang('mailer_not_supported'));
421
+ //$result = false;
422
+ //break;
423
+ }
424
+
425
+ return $result;
426
+ }
427
+
428
+ /**
429
+ * Sends mail using the $Sendmail program.
430
+ * @access private
431
+ * @return bool
432
+ */
433
+ function SendmailSend($header, $body) {
434
+ if ($this->Sender != '') {
435
+ $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
436
+ } else {
437
+ $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
438
+ }
439
+
440
+ if(!@$mail = popen($sendmail, 'w')) {
441
+ $this->SetError($this->Lang('execute') . $this->Sendmail);
442
+ return false;
443
+ }
444
+
445
+ fputs($mail, $header);
446
+ fputs($mail, $body);
447
+
448
+ $result = pclose($mail);
449
+ if (version_compare(phpversion(), '4.2.3') == -1) {
450
+ $result = $result >> 8 & 0xFF;
451
+ }
452
+ if($result != 0) {
453
+ $this->SetError($this->Lang('execute') . $this->Sendmail);
454
+ return false;
455
+ }
456
+ return true;
457
+ }
458
+
459
+ /**
460
+ * Sends mail using the PHP mail() function.
461
+ * @access private
462
+ * @return bool
463
+ */
464
+ function MailSend($header, $body) {
465
+
466
+ $to = '';
467
+ for($i = 0; $i < count($this->to); $i++) {
468
+ if($i != 0) { $to .= ', '; }
469
+ $to .= $this->AddrFormat($this->to[$i]);
470
+ }
471
+
472
+ $toArr = split(',', $to);
473
+
474
+ $params = sprintf("-oi -f %s", $this->Sender);
475
+ if ($this->Sender != '' && strlen(ini_get('safe_mode')) < 1) {
476
+ $old_from = ini_get('sendmail_from');
477
+ ini_set('sendmail_from', $this->Sender);
478
+ if ($this->SingleTo === true && count($toArr) > 1) {
479
+ foreach ($toArr as $key => $val) {
480
+ $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
481
+ }
482
+ } else {
483
+ $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
484
+ }
485
+ } else {
486
+ if ($this->SingleTo === true && count($toArr) > 1) {
487
+ foreach ($toArr as $key => $val) {
488
+ $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
489
+ }
490
+ } else {
491
+ $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header);
492
+ }
493
+ }
494
+
495
+ if (isset($old_from)) {
496
+ ini_set('sendmail_from', $old_from);
497
+ }
498
+
499
+ if(!$rt) {
500
+ $this->SetError($this->Lang('instantiate'));
501
+ return false;
502
+ }
503
+
504
+ return true;
505
+ }
506
+
507
+ /**
508
+ * Sends mail via SMTP using PhpSMTP (Author:
509
+ * Chris Ryan). Returns bool. Returns false if there is a
510
+ * bad MAIL FROM, RCPT, or DATA input.
511
+ * @access private
512
+ * @return bool
513
+ */
514
+ function SmtpSend($header, $body) {
515
+ include_once('class.mailer-smtp.php');
516
+ $error = '';
517
+ $bad_rcpt = array();
518
+
519
+ if(!$this->SmtpConnect()) {
520
+ return false;
521
+ }
522
+
523
+ $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
524
+ if(!$this->smtp->Mail($smtp_from)) {
525
+ $error = $this->Lang('from_failed') . $smtp_from;
526
+ $this->SetError($error);
527
+ $this->smtp->Reset();
528
+ return false;
529
+ }
530
+
531
+ /* Attempt to send attach all recipients */
532
+ for($i = 0; $i < count($this->to); $i++) {
533
+ if(!$this->smtp->Recipient($this->to[$i][0])) {
534
+ $bad_rcpt[] = $this->to[$i][0];
535
+ }
536
+ }
537
+ for($i = 0; $i < count($this->cc); $i++) {
538
+ if(!$this->smtp->Recipient($this->cc[$i][0])) {
539
+ $bad_rcpt[] = $this->cc[$i][0];
540
+ }
541
+ }
542
+ for($i = 0; $i < count($this->bcc); $i++) {
543
+ if(!$this->smtp->Recipient($this->bcc[$i][0])) {
544
+ $bad_rcpt[] = $this->bcc[$i][0];
545
+ }
546
+ }
547
+
548
+ if(count($bad_rcpt) > 0) { // Create error message
549
+ for($i = 0; $i < count($bad_rcpt); $i++) {
550
+ if($i != 0) {
551
+ $error .= ', ';
552
+ }
553
+ $error .= $bad_rcpt[$i];
554
+ }
555
+ $error = $this->Lang('recipients_failed') . $error;
556
+ $this->SetError($error);
557
+ $this->smtp->Reset();
558
+ return false;
559
+ }
560
+
561
+ if(!$this->smtp->Data($header . $body)) {
562
+ $this->SetError($this->Lang('data_not_accepted'));
563
+ $this->smtp->Reset();
564
+ return false;
565
+ }
566
+ if($this->SMTPKeepAlive == true) {
567
+ $this->smtp->Reset();
568
+ } else {
569
+ $this->SmtpClose();
570
+ }
571
+
572
+ return true;
573
+ }
574
+
575
+ /**
576
+ * Initiates a connection to an SMTP server. Returns false if the
577
+ * operation failed.
578
+ * @access private
579
+ * @return bool
580
+ */
581
+ function SmtpConnect() {
582
+ if($this->smtp == NULL) {
583
+ $this->smtp = new SMTP();
584
+ }
585
+
586
+ $this->smtp->do_debug = $this->SMTPDebug;
587
+ $hosts = explode(';', $this->Host);
588
+ $index = 0;
589
+ $connection = ($this->smtp->Connected());
590
+
591
+ /* Retry while there is no connection */
592
+ while($index < count($hosts) && $connection == false) {
593
+ $hostinfo = array();
594
+ if(eregi('^(.+):([0-9]+)$', $hosts[$index], $hostinfo)) {
595
+ $host = $hostinfo[1];
596
+ $port = $hostinfo[2];
597
+ } else {
598
+ $host = $hosts[$index];
599
+ $port = $this->Port;
600
+ }
601
+
602
+ if($this->smtp->Connect(((!empty($this->SMTPSecure))?$this->SMTPSecure.'://':'').$host, $port, $this->Timeout)) {
603
+ if ($this->Helo != '') {
604
+ $this->smtp->Hello($this->Helo);
605
+ } else {
606
+ $this->smtp->Hello($this->ServerHostname());
607
+ }
608
+
609
+ $connection = true;
610
+ if($this->SMTPAuth) {
611
+ if(!$this->smtp->Authenticate($this->Username, $this->Password)) {
612
+ $this->SetError($this->Lang('authenticate'));
613
+ $this->smtp->Reset();
614
+ $connection = false;
615
+ }
616
+ }
617
+ }
618
+ $index++;
619
+ }
620
+ if(!$connection) {
621
+ $this->SetError($this->Lang('connect_host'));
622
+ }
623
+
624
+ return $connection;
625
+ }
626
+
627
+ /**
628
+ * Closes the active SMTP session if one exists.
629
+ * @return void
630
+ */
631
+ function SmtpClose() {
632
+ if($this->smtp != NULL) {
633
+ if($this->smtp->Connected()) {
634
+ $this->smtp->Quit();
635
+ $this->smtp->Close();
636
+ }
637
+ }
638
+ }
639
+
640
+ /**
641
+ * Sets the language for all class error messages. Returns false
642
+ * if it cannot load the language file. The default language type
643
+ * is English.
644
+ * @param string $lang_type Type of language (e.g. Portuguese: "br")
645
+ * @param string $lang_path Path to the language file directory
646
+ * @access public
647
+ * @return bool
648
+ */
649
+ function SetLanguage($lang_type, $lang_path = 'language/') {
650
+ if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) {
651
+ include($lang_path.'phpmailer.lang-'.$lang_type.'.php');
652
+ } elseif (file_exists($lang_path.'phpmailer.lang-en.php')) {
653
+ include($lang_path.'phpmailer.lang-en.php');
654
+ } else {
655
+ $PHPMAILER_LANG = array();
656
+ $PHPMAILER_LANG["provide_address"] = 'You must provide at least one ' .
657
+ $PHPMAILER_LANG["mailer_not_supported"] = ' mailer is not supported.';
658
+ $PHPMAILER_LANG["execute"] = 'Could not execute: ';
659
+ $PHPMAILER_LANG["instantiate"] = 'Could not instantiate mail function.';
660
+ $PHPMAILER_LANG["authenticate"] = 'SMTP Error: Could not authenticate.';
661
+ $PHPMAILER_LANG["from_failed"] = 'The following From address failed: ';
662
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP Error: The following ' .
663
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP Error: Data not accepted.';
664
+ $PHPMAILER_LANG["connect_host"] = 'SMTP Error: Could not connect to SMTP host.';
665
+ $PHPMAILER_LANG["file_access"] = 'Could not access file: ';
666
+ $PHPMAILER_LANG["file_open"] = 'File Error: Could not open file: ';
667
+ $PHPMAILER_LANG["encoding"] = 'Unknown encoding: ';
668
+ $PHPMAILER_LANG["signing"] = 'Signing Error: ';
669
+ }
670
+ $this->language = $PHPMAILER_LANG;
671
+
672
+ return true;
673
+ }
674
+
675
+ /////////////////////////////////////////////////
676
+ // METHODS, MESSAGE CREATION
677
+ /////////////////////////////////////////////////
678
+
679
+ /**
680
+ * Creates recipient headers.
681
+ * @access private
682
+ * @return string
683
+ */
684
+ function AddrAppend($type, $addr) {
685
+ $addr_str = $type . ': ';
686
+ $addr_str .= $this->AddrFormat($addr[0]);
687
+ if(count($addr) > 1) {
688
+ for($i = 1; $i < count($addr); $i++) {
689
+ $addr_str .= ', ' . $this->AddrFormat($addr[$i]);
690
+ }
691
+ }
692
+ $addr_str .= $this->LE;
693
+
694
+ return $addr_str;
695
+ }
696
+
697
+ /**
698
+ * Formats an address correctly.
699
+ * @access private
700
+ * @return string
701
+ */
702
+ function AddrFormat($addr) {
703
+ if(empty($addr[1])) {
704
+ $formatted = $this->SecureHeader($addr[0]);
705
+ } else {
706
+ $formatted = $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">";
707
+ }
708
+
709
+ return $formatted;
710
+ }
711
+
712
+ /**
713
+ * Wraps message for use with mailers that do not
714
+ * automatically perform wrapping and for quoted-printable.
715
+ * Original written by philippe.
716
+ * @access private
717
+ * @return string
718
+ */
719
+ function WrapText($message, $length, $qp_mode = false) {
720
+ $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
721
+ // If utf-8 encoding is used, we will need to make sure we don't
722
+ // split multibyte characters when we wrap
723
+ $is_utf8 = (strtolower($this->CharSet) == "utf-8");
724
+
725
+ $message = $this->FixEOL($message);
726
+ if (substr($message, -1) == $this->LE) {
727
+ $message = substr($message, 0, -1);
728
+ }
729
+
730
+ $line = explode($this->LE, $message);
731
+ $message = '';
732
+ for ($i=0 ;$i < count($line); $i++) {
733
+ $line_part = explode(' ', $line[$i]);
734
+ $buf = '';
735
+ for ($e = 0; $e<count($line_part); $e++) {
736
+ $word = $line_part[$e];
737
+ if ($qp_mode and (strlen($word) > $length)) {
738
+ $space_left = $length - strlen($buf) - 1;
739
+ if ($e != 0) {
740
+ if ($space_left > 20) {
741
+ $len = $space_left;
742
+ if ($is_utf8) {
743
+ $len = $this->UTF8CharBoundary($word, $len);
744
+ } elseif (substr($word, $len - 1, 1) == "=") {
745
+ $len--;
746
+ } elseif (substr($word, $len - 2, 1) == "=") {
747
+ $len -= 2;
748
+ }
749
+ $part = substr($word, 0, $len);
750
+ $word = substr($word, $len);
751
+ $buf .= ' ' . $part;
752
+ $message .= $buf . sprintf("=%s", $this->LE);
753
+ } else {
754
+ $message .= $buf . $soft_break;
755
+ }
756
+ $buf = '';
757
+ }
758
+ while (strlen($word) > 0) {
759
+ $len = $length;
760
+ if ($is_utf8) {
761
+ $len = $this->UTF8CharBoundary($word, $len);
762
+ } elseif (substr($word, $len - 1, 1) == "=") {
763
+ $len--;
764
+ } elseif (substr($word, $len - 2, 1) == "=") {
765
+ $len -= 2;
766
+ }
767
+ $part = substr($word, 0, $len);
768
+ $word = substr($word, $len);
769
+
770
+ if (strlen($word) > 0) {
771
+ $message .= $part . sprintf("=%s", $this->LE);
772
+ } else {
773
+ $buf = $part;
774
+ }
775
+ }
776
+ } else {
777
+ $buf_o = $buf;
778
+ $buf .= ($e == 0) ? $word : (' ' . $word);
779
+
780
+ if (strlen($buf) > $length and $buf_o != '') {
781
+ $message .= $buf_o . $soft_break;
782
+ $buf = $word;
783
+ }
784
+ }
785
+ }
786
+ $message .= $buf . $this->LE;
787
+ }
788
+
789
+ return $message;
790
+ }
791
+
792
+ /**
793
+ * Finds last character boundary prior to maxLength in a utf-8
794
+ * quoted (printable) encoded string.
795
+ * Original written by Colin Brown.
796
+ * @access private
797
+ * @param string $encodedText utf-8 QP text
798
+ * @param int $maxLength find last character boundary prior to this length
799
+ * @return int
800
+ */
801
+ function UTF8CharBoundary($encodedText, $maxLength) {
802
+ $foundSplitPos = false;
803
+ $lookBack = 3;
804
+ while (!$foundSplitPos) {
805
+ $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
806
+ $encodedCharPos = strpos($lastChunk, "=");
807
+ if ($encodedCharPos !== false) {
808
+ // Found start of encoded character byte within $lookBack block.
809
+ // Check the encoded byte value (the 2 chars after the '=')
810
+ $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
811
+ $dec = hexdec($hex);
812
+ if ($dec < 128) { // Single byte character.
813
+ // If the encoded char was found at pos 0, it will fit
814
+ // otherwise reduce maxLength to start of the encoded char
815
+ $maxLength = ($encodedCharPos == 0) ? $maxLength :
816
+ $maxLength - ($lookBack - $encodedCharPos);
817
+ $foundSplitPos = true;
818
+ } elseif ($dec >= 192) { // First byte of a multi byte character
819
+ // Reduce maxLength to split at start of character
820
+ $maxLength = $maxLength - ($lookBack - $encodedCharPos);
821
+ $foundSplitPos = true;
822
+ } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back
823
+ $lookBack += 3;
824
+ }
825
+ } else {
826
+ // No encoded character found
827
+ $foundSplitPos = true;
828
+ }
829
+ }
830
+ return $maxLength;
831
+ }
832
+
833
+ /**
834
+ * Set the body wrapping.
835
+ * @access private
836
+ * @return void
837
+ */
838
+ function SetWordWrap() {
839
+ if($this->WordWrap < 1) {
840
+ return;
841
+ }
842
+
843
+ switch($this->message_type) {
844
+ case 'alt':
845
+ /* fall through */
846
+ case 'alt_attachments':
847
+ $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
848
+ break;
849
+ default:
850
+ $this->Body = $this->WrapText($this->Body, $this->WordWrap);
851
+ break;
852
+ }
853
+ }
854
+
855
+ /**
856
+ * Assembles message header.
857
+ * @access private
858
+ * @return string
859
+ */
860
+ function CreateHeader() {
861
+ $result = '';
862
+
863
+ /* Set the boundaries */
864
+ $uniq_id = md5(uniqid(time()));
865
+ $this->boundary[1] = 'b1_' . $uniq_id;
866
+ $this->boundary[2] = 'b2_' . $uniq_id;
867
+
868
+ $result .= $this->HeaderLine('Date', $this->RFCDate());
869
+ if($this->Sender == '') {
870
+ $result .= $this->HeaderLine('Return-Path', trim($this->From));
871
+ } else {
872
+ $result .= $this->HeaderLine('Return-Path', trim($this->Sender));
873
+ }
874
+
875
+ /* To be created automatically by mail() */
876
+ if($this->Mailer != 'mail') {
877
+ if(count($this->to) > 0) {
878
+ $result .= $this->AddrAppend('To', $this->to);
879
+ } elseif (count($this->cc) == 0) {
880
+ $result .= $this->HeaderLine('To', 'undisclosed-recipients:;');
881
+ }
882
+ }
883
+
884
+ $from = array();
885
+ $from[0][0] = trim($this->From);
886
+ $from[0][1] = $this->FromName;
887
+ $result .= $this->AddrAppend('From', $from);
888
+
889
+ /* sendmail and mail() extract Cc from the header before sending */
890
+ if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->cc) > 0)) {
891
+ $result .= $this->AddrAppend('Cc', $this->cc);
892
+ }
893
+
894
+ /* sendmail and mail() extract Bcc from the header before sending */
895
+ if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) {
896
+ $result .= $this->AddrAppend('Bcc', $this->bcc);
897
+ }
898
+
899
+ if(count($this->ReplyTo) > 0) {
900
+ $result .= $this->AddrAppend('Reply-To', $this->ReplyTo);
901
+ }
902
+
903
+ /* mail() sets the subject itself */
904
+ if($this->Mailer != 'mail') {
905
+ $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject)));
906
+ }
907
+
908
+ if($this->MessageID != '') {
909
+ $result .= $this->HeaderLine('Message-ID',$this->MessageID);
910
+ } else {
911
+ $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
912
+ }
913
+ $result .= $this->HeaderLine('X-Priority', $this->Priority);
914
+ $result .= $this->HeaderLine('X-Mailer', 'PHPMailer (phpmailer.sourceforge.net) [version ' . $this->Version . ']');
915
+
916
+ if($this->ConfirmReadingTo != '') {
917
+ $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');
918
+ }
919
+
920
+ // Add custom headers
921
+ for($index = 0; $index < count($this->CustomHeader); $index++) {
922
+ $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1])));
923
+ }
924
+ if (!$this->sign_key_file) {
925
+ $result .= $this->HeaderLine('MIME-Version', '1.0');
926
+ $result .= $this->GetMailMIME();
927
+ }
928
+
929
+ return $result;
930
+ }
931
+
932
+ /**
933
+ * Returns the message MIME.
934
+ * @access private
935
+ * @return string
936
+ */
937
+ function GetMailMIME() {
938
+ $result = '';
939
+ switch($this->message_type) {
940
+ case 'plain':
941
+ $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding);
942
+ $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet);
943
+ break;
944
+ case 'attachments':
945
+ /* fall through */
946
+ case 'alt_attachments':
947
+ if($this->InlineImageExists()){
948
+ $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE);
949
+ } else {
950
+ $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;');
951
+ $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
952
+ }
953
+ break;
954
+ case 'alt':
955
+ $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
956
+ $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
957
+ break;
958
+ }
959
+
960
+ if($this->Mailer != 'mail') {
961
+ $result .= $this->LE.$this->LE;
962
+ }
963
+
964
+ return $result;
965
+ }
966
+
967
+ /**
968
+ * Assembles the message body. Returns an empty string on failure.
969
+ * @access private
970
+ * @return string
971
+ */
972
+ function CreateBody() {
973
+ $result = '';
974
+ if ($this->sign_key_file) {
975
+ $result .= $this->GetMailMIME();
976
+ }
977
+
978
+ $this->SetWordWrap();
979
+
980
+ switch($this->message_type) {
981
+ case 'alt':
982
+ $result .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');
983
+ $result .= $this->EncodeString($this->AltBody, $this->Encoding);
984
+ $result .= $this->LE.$this->LE;
985
+ $result .= $this->GetBoundary($this->boundary[1], '', 'text/html', '');
986
+ $result .= $this->EncodeString($this->Body, $this->Encoding);
987
+ $result .= $this->LE.$this->LE;
988
+ $result .= $this->EndBoundary($this->boundary[1]);
989
+ break;
990
+ case 'plain':
991
+ $result .= $this->EncodeString($this->Body, $this->Encoding);
992
+ break;
993
+ case 'attachments':
994
+ $result .= $this->GetBoundary($this->boundary[1], '', '', '');
995
+ $result .= $this->EncodeString($this->Body, $this->Encoding);
996
+ $result .= $this->LE;
997
+ $result .= $this->AttachAll();
998
+ break;
999
+ case 'alt_attachments':
1000
+ $result .= sprintf("--%s%s", $this->boundary[1], $this->LE);
1001
+ $result .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE);
1002
+ $result .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body
1003
+ $result .= $this->EncodeString($this->AltBody, $this->Encoding);
1004
+ $result .= $this->LE.$this->LE;
1005
+ $result .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body
1006
+ $result .= $this->EncodeString($this->Body, $this->Encoding);
1007
+ $result .= $this->LE.$this->LE;
1008
+ $result .= $this->EndBoundary($this->boundary[2]);
1009
+ $result .= $this->AttachAll();
1010
+ break;
1011
+ }
1012
+
1013
+ if($this->IsError()) {
1014
+ $result = '';
1015
+ } else if ($this->sign_key_file) {
1016
+ $file = tempnam("", "mail");
1017
+ $fp = fopen($file, "w");
1018
+ fwrite($fp, $result);
1019
+ fclose($fp);
1020
+ $signed = tempnam("", "signed");
1021
+
1022
+ if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), null)) {
1023
+ $fp = fopen($signed, "r");
1024
+ $result = fread($fp, filesize($this->sign_key_file));
1025
+ $result = '';
1026
+ while(!feof($fp)){
1027
+ $result = $result . fread($fp, 1024);
1028
+ }
1029
+ fclose($fp);
1030
+ } else {
1031
+ $this->SetError($this->Lang("signing").openssl_error_string());
1032
+ $result = '';
1033
+ }
1034
+
1035
+ unlink($file);
1036
+ unlink($signed);
1037
+ }
1038
+
1039
+ return $result;
1040
+ }
1041
+
1042
+ /**
1043
+ * Returns the start of a message boundary.
1044
+ * @access private
1045
+ */
1046
+ function GetBoundary($boundary, $charSet, $contentType, $encoding) {
1047
+ $result = '';
1048
+ if($charSet == '') {
1049
+ $charSet = $this->CharSet;
1050
+ }
1051
+ if($contentType == '') {
1052
+ $contentType = $this->ContentType;
1053
+ }
1054
+ if($encoding == '') {
1055
+ $encoding = $this->Encoding;
1056
+ }
1057
+ $result .= $this->TextLine('--' . $boundary);
1058
+ $result .= sprintf("Content-Type: %s; charset = \"%s\"", $contentType, $charSet);
1059
+ $result .= $this->LE;
1060
+ $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding);
1061
+ $result .= $this->LE;
1062
+
1063
+ return $result;
1064
+ }
1065
+
1066
+ /**
1067
+ * Returns the end of a message boundary.
1068
+ * @access private
1069
+ */
1070
+ function EndBoundary($boundary) {
1071
+ return $this->LE . '--' . $boundary . '--' . $this->LE;
1072
+ }
1073
+
1074
+ /**
1075
+ * Sets the message type.
1076
+ * @access private
1077
+ * @return void
1078
+ */
1079
+ function SetMessageType() {
1080
+ if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) {
1081
+ $this->message_type = 'plain';
1082
+ } else {
1083
+ if(count($this->attachment) > 0) {
1084
+ $this->message_type = 'attachments';
1085
+ }
1086
+ if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) {
1087
+ $this->message_type = 'alt';
1088
+ }
1089
+ if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) {
1090
+ $this->message_type = 'alt_attachments';
1091
+ }
1092
+ }
1093
+ }
1094
+
1095
+ /* Returns a formatted header line.
1096
+ * @access private
1097
+ * @return string
1098
+ */
1099
+ function HeaderLine($name, $value) {
1100
+ return $name . ': ' . $value . $this->LE;
1101
+ }
1102
+
1103
+ /**
1104
+ * Returns a formatted mail line.
1105
+ * @access private
1106
+ * @return string
1107
+ */
1108
+ function TextLine($value) {
1109
+ return $value . $this->LE;
1110
+ }
1111
+
1112
+ /////////////////////////////////////////////////
1113
+ // CLASS METHODS, ATTACHMENTS
1114
+ /////////////////////////////////////////////////
1115
+
1116
+ /**
1117
+ * Adds an attachment from a path on the filesystem.
1118
+ * Returns false if the file could not be found
1119
+ * or accessed.
1120
+ * @param string $path Path to the attachment.
1121
+ * @param string $name Overrides the attachment name.
1122
+ * @param string $encoding File encoding (see $Encoding).
1123
+ * @param string $type File extension (MIME) type.
1124
+ * @return bool
1125
+ */
1126
+ function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
1127
+ if(!@is_file($path)) {
1128
+ $this->SetError($this->Lang('file_access') . $path);
1129
+ return false;
1130
+ }
1131
+
1132
+ $filename = basename($path);
1133
+ if($name == '') {
1134
+ $name = $filename;
1135
+ }
1136
+
1137
+ $cur = count($this->attachment);
1138
+ $this->attachment[$cur][0] = $path;
1139
+ $this->attachment[$cur][1] = $filename;
1140
+ $this->attachment[$cur][2] = $name;
1141
+ $this->attachment[$cur][3] = $encoding;
1142
+ $this->attachment[$cur][4] = $type;
1143
+ $this->attachment[$cur][5] = false; // isStringAttachment
1144
+ $this->attachment[$cur][6] = 'attachment';
1145
+ $this->attachment[$cur][7] = 0;
1146
+
1147
+ return true;
1148
+ }
1149
+
1150
+ /**
1151
+ * Attaches all fs, string, and binary attachments to the message.
1152
+ * Returns an empty string on failure.
1153
+ * @access private
1154
+ * @return string
1155
+ */
1156
+ function AttachAll() {
1157
+ /* Return text of body */
1158
+ $mime = array();
1159
+
1160
+ /* Add all attachments */
1161
+ for($i = 0; $i < count($this->attachment); $i++) {
1162
+ /* Check for string attachment */
1163
+ $bString = $this->attachment[$i][5];
1164
+ if ($bString) {
1165
+ $string = $this->attachment[$i][0];
1166
+ } else {
1167
+ $path = $this->attachment[$i][0];
1168
+ }
1169
+
1170
+ $filename = $this->attachment[$i][1];
1171
+ $name = $this->attachment[$i][2];
1172
+ $encoding = $this->attachment[$i][3];
1173
+ $type = $this->attachment[$i][4];
1174
+ $disposition = $this->attachment[$i][6];
1175
+ $cid = $this->attachment[$i][7];
1176
+
1177
+ $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE);
1178
+ $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE);
1179
+ $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
1180
+
1181
+ if($disposition == 'inline') {
1182
+ $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
1183
+ }
1184
+
1185
+ $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE.$this->LE);
1186
+
1187
+ /* Encode as string attachment */
1188
+ if($bString) {
1189
+ $mime[] = $this->EncodeString($string, $encoding);
1190
+ if($this->IsError()) {
1191
+ return '';
1192
+ }
1193
+ $mime[] = $this->LE.$this->LE;
1194
+ } else {
1195
+ $mime[] = $this->EncodeFile($path, $encoding);
1196
+ if($this->IsError()) {
1197
+ return '';
1198
+ }
1199
+ $mime[] = $this->LE.$this->LE;
1200
+ }
1201
+ }
1202
+
1203
+ $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE);
1204
+
1205
+ return join('', $mime);
1206
+ }
1207
+
1208
+ /**
1209
+ * Encodes attachment in requested format. Returns an
1210
+ * empty string on failure.
1211
+ * @access private
1212
+ * @return string
1213
+ */
1214
+ function EncodeFile ($path, $encoding = 'base64') {
1215
+ if(!@$fd = fopen($path, 'rb')) {
1216
+ $this->SetError($this->Lang('file_open') . $path);
1217
+ return '';
1218
+ }
1219
+ $magic_quotes = get_magic_quotes_runtime();
1220
+ set_magic_quotes_runtime(0);
1221
+ $file_buffer = fread($fd, filesize($path));
1222
+ $file_buffer = $this->EncodeString($file_buffer, $encoding);
1223
+ fclose($fd);
1224
+ set_magic_quotes_runtime($magic_quotes);
1225
+
1226
+ return $file_buffer;
1227
+ }
1228
+
1229
+ /**
1230
+ * Encodes string to requested format. Returns an
1231
+ * empty string on failure.
1232
+ * @access private
1233
+ * @return string
1234
+ */
1235
+ function EncodeString ($str, $encoding = 'base64') {
1236
+ $encoded = '';
1237
+ switch(strtolower($encoding)) {
1238
+ case 'base64':
1239
+ /* chunk_split is found in PHP >= 3.0.6 */
1240
+ $encoded = chunk_split(base64_encode($str), 76, $this->LE);
1241
+ break;
1242
+ case '7bit':
1243
+ case '8bit':
1244
+ $encoded = $this->FixEOL($str);
1245
+ if (substr($encoded, -(strlen($this->LE))) != $this->LE)
1246
+ $encoded .= $this->LE;
1247
+ break;
1248
+ case 'binary':
1249
+ $encoded = $str;
1250
+ break;
1251
+ case 'quoted-printable':
1252
+ $encoded = $this->EncodeQP($str);
1253
+ break;
1254
+ default:
1255
+ $this->SetError($this->Lang('encoding') . $encoding);
1256
+ break;
1257
+ }
1258
+ return $encoded;
1259
+ }
1260
+
1261
+ /**
1262
+ * Encode a header string to best of Q, B, quoted or none.
1263
+ * @access private
1264
+ * @return string
1265
+ */
1266
+ function EncodeHeader ($str, $position = 'text') {
1267
+ $x = 0;
1268
+
1269
+ switch (strtolower($position)) {
1270
+ case 'phrase':
1271
+ if (!preg_match('/[\200-\377]/', $str)) {
1272
+ /* Can't use addslashes as we don't know what value has magic_quotes_sybase. */
1273
+ $encoded = addcslashes($str, "\0..\37\177\\\"");
1274
+ if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
1275
+ return ($encoded);
1276
+ } else {
1277
+ return ("\"$encoded\"");
1278
+ }
1279
+ }
1280
+ $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
1281
+ break;
1282
+ case 'comment':
1283
+ $x = preg_match_all('/[()"]/', $str, $matches);
1284
+ /* Fall-through */
1285
+ case 'text':
1286
+ default:
1287
+ $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
1288
+ break;
1289
+ }
1290
+
1291
+ if ($x == 0) {
1292
+ return ($str);
1293
+ }
1294
+
1295
+ $maxlen = 75 - 7 - strlen($this->CharSet);
1296
+ /* Try to select the encoding which should produce the shortest output */
1297
+ if (strlen($str)/3 < $x) {
1298
+ $encoding = 'B';
1299
+ if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) {
1300
+ // Use a custom function which correctly encodes and wraps long
1301
+ // multibyte strings without breaking lines within a character
1302
+ $encoded = $this->Base64EncodeWrapMB($str);
1303
+ } else {
1304
+ $encoded = base64_encode($str);
1305
+ $maxlen -= $maxlen % 4;
1306
+ $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
1307
+ }
1308
+ } else {
1309
+ $encoding = 'Q';
1310
+ $encoded = $this->EncodeQ($str, $position);
1311
+ $encoded = $this->WrapText($encoded, $maxlen, true);
1312
+ $encoded = str_replace('='.$this->LE, "\n", trim($encoded));
1313
+ }
1314
+
1315
+ $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded);
1316
+ $encoded = trim(str_replace("\n", $this->LE, $encoded));
1317
+
1318
+ return $encoded;
1319
+ }
1320
+
1321
+ /**
1322
+ * Checks if a string contains multibyte characters.
1323
+ * @access private
1324
+ * @param string $str multi-byte text to wrap encode
1325
+ * @return bool
1326
+ */
1327
+ function HasMultiBytes($str) {
1328
+ if (function_exists('mb_strlen')) {
1329
+ return (strlen($str) > mb_strlen($str, $this->CharSet));
1330
+ } else { // Assume no multibytes (we can't handle without mbstring functions anyway)
1331
+ return False;
1332
+ }
1333
+ }
1334
+
1335
+ /**
1336
+ * Correctly encodes and wraps long multibyte strings for mail headers
1337
+ * without breaking lines within a character.
1338
+ * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php
1339
+ * @access private
1340
+ * @param string $str multi-byte text to wrap encode
1341
+ * @return string
1342
+ */
1343
+ function Base64EncodeWrapMB($str) {
1344
+ $start = "=?".$this->CharSet."?B?";
1345
+ $end = "?=";
1346
+ $encoded = "";
1347
+
1348
+ $mb_length = mb_strlen($str, $this->CharSet);
1349
+ // Each line must have length <= 75, including $start and $end
1350
+ $length = 75 - strlen($start) - strlen($end);
1351
+ // Average multi-byte ratio
1352
+ $ratio = $mb_length / strlen($str);
1353
+ // Base64 has a 4:3 ratio
1354
+ $offset = $avgLength = floor($length * $ratio * .75);
1355
+
1356
+ for ($i = 0; $i < $mb_length; $i += $offset) {
1357
+ $lookBack = 0;
1358
+
1359
+ do {
1360
+ $offset = $avgLength - $lookBack;
1361
+ $chunk = mb_substr($str, $i, $offset, $this->CharSet);
1362
+ $chunk = base64_encode($chunk);
1363
+ $lookBack++;
1364
+ }
1365
+ while (strlen($chunk) > $length);
1366
+
1367
+ $encoded .= $chunk . $this->LE;
1368
+ }
1369
+
1370
+ // Chomp the last linefeed
1371
+ $encoded = substr($encoded, 0, -strlen($this->LE));
1372
+ return $encoded;
1373
+ }
1374
+
1375
+ /**
1376
+ * Encode string to quoted-printable.
1377
+ * @access private
1378
+ * @return string
1379
+ */
1380
+ function EncodeQP( $input = '', $line_max = 76, $space_conv = false ) {
1381
+ $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
1382
+ $lines = preg_split('/(?:\r\n|\r|\n)/', $input);
1383
+ $eol = "\r\n";
1384
+ $escape = '=';
1385
+ $output = '';
1386
+ while( list(, $line) = each($lines) ) {
1387
+ $linlen = strlen($line);
1388
+ $newline = '';
1389
+ for($i = 0; $i < $linlen; $i++) {
1390
+ $c = substr( $line, $i, 1 );
1391
+ $dec = ord( $c );
1392
+ if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E
1393
+ $c = '=2E';
1394
+ }
1395
+ if ( $dec == 32 ) {
1396
+ if ( $i == ( $linlen - 1 ) ) { // convert space at eol only
1397
+ $c = '=20';
1398
+ } else if ( $space_conv ) {
1399
+ $c = '=20';
1400
+ }
1401
+ } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required
1402
+ $h2 = floor($dec/16);
1403
+ $h1 = floor($dec%16);
1404
+ $c = $escape.$hex[$h2].$hex[$h1];
1405
+ }
1406
+ if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted
1407
+ $output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay
1408
+ $newline = '';
1409
+ // check if newline first character will be point or not
1410
+ if ( $dec == 46 ) {
1411
+ $c = '=2E';
1412
+ }
1413
+ }
1414
+ $newline .= $c;
1415
+ } // end of for
1416
+ $output .= $newline.$eol;
1417
+ } // end of while
1418
+ return $output;
1419
+ }
1420
+
1421
+ /**
1422
+ * Callback for converting to "=XX".
1423
+ * @access private
1424
+ * @return string
1425
+ */
1426
+ function EncodeQ_callback ($matches) {
1427
+ return sprintf('=%02X', ord($matches[1]));
1428
+ }
1429
+
1430
+ /**
1431
+ * Encode string to q encoding.
1432
+ * @access private
1433
+ * @return string
1434
+ */
1435
+ function EncodeQ ($str, $position = 'text') {
1436
+ /* There should not be any EOL in the string */
1437
+ $encoded = preg_replace("/[\r\n]/", '', $str);
1438
+
1439
+ switch (strtolower($position)) {
1440
+ case 'phrase':
1441
+ $encoded = preg_replace_callback("/([^A-Za-z0-9!*+\/ -])/",
1442
+ array('PHPMailer', 'EncodeQ_callback'), $encoded);
1443
+ break;
1444
+ case 'comment':
1445
+ $encoded = preg_replace_callback("/([\(\)\"])/",
1446
+ array('PHPMailer', 'EncodeQ_callback'), $encoded);
1447
+ break;
1448
+ case 'text':
1449
+ default:
1450
+ /* Replace every high ascii, control =, ? and _ characters */
1451
+ $encoded = preg_replace_callback('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/',
1452
+ array('PHPMailer', 'EncodeQ_callback'), $encoded);
1453
+ break;
1454
+ }
1455
+
1456
+ /* Replace every spaces to _ (more readable than =20) */
1457
+ $encoded = str_replace(' ', '_', $encoded);
1458
+
1459
+ return $encoded;
1460
+ }
1461
+
1462
+ /**
1463
+ * Adds a string or binary attachment (non-filesystem) to the list.
1464
+ * This method can be used to attach ascii or binary data,
1465
+ * such as a BLOB record from a database.
1466
+ * @param string $string String attachment data.
1467
+ * @param string $filename Name of the attachment.
1468
+ * @param string $encoding File encoding (see $Encoding).
1469
+ * @param string $type File extension (MIME) type.
1470
+ * @return void
1471
+ */
1472
+ function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') {
1473
+ /* Append to $attachment array */
1474
+ $cur = count($this->attachment);
1475
+ $this->attachment[$cur][0] = $string;
1476
+ $this->attachment[$cur][1] = $filename;
1477
+ $this->attachment[$cur][2] = $filename;
1478
+ $this->attachment[$cur][3] = $encoding;
1479
+ $this->attachment[$cur][4] = $type;
1480
+ $this->attachment[$cur][5] = true; // isString
1481
+ $this->attachment[$cur][6] = 'attachment';
1482
+ $this->attachment[$cur][7] = 0;
1483
+ }
1484
+
1485
+ /**
1486
+ * Adds an embedded attachment. This can include images, sounds, and
1487
+ * just about any other document. Make sure to set the $type to an
1488
+ * image type. For JPEG images use "image/jpeg" and for GIF images
1489
+ * use "image/gif".
1490
+ * @param string $path Path to the attachment.
1491
+ * @param string $cid Content ID of the attachment. Use this to identify
1492
+ * the Id for accessing the image in an HTML form.
1493
+ * @param string $name Overrides the attachment name.
1494
+ * @param string $encoding File encoding (see $Encoding).
1495
+ * @param string $type File extension (MIME) type.
1496
+ * @return bool
1497
+ */
1498
+ function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
1499
+
1500
+ if(!@is_file($path)) {
1501
+ $this->SetError($this->Lang('file_access') . $path);
1502
+ return false;
1503
+ }
1504
+
1505
+ $filename = basename($path);
1506
+ if($name == '') {
1507
+ $name = $filename;
1508
+ }
1509
+
1510
+ /* Append to $attachment array */
1511
+ $cur = count($this->attachment);
1512
+ $this->attachment[$cur][0] = $path;
1513
+ $this->attachment[$cur][1] = $filename;
1514
+ $this->attachment[$cur][2] = $name;
1515
+ $this->attachment[$cur][3] = $encoding;
1516
+ $this->attachment[$cur][4] = $type;
1517
+ $this->attachment[$cur][5] = false;
1518
+ $this->attachment[$cur][6] = 'inline';
1519
+ $this->attachment[$cur][7] = $cid;
1520
+
1521
+ return true;
1522
+ }
1523
+
1524
+ /**
1525
+ * Returns true if an inline attachment is present.
1526
+ * @access private
1527
+ * @return bool
1528
+ */
1529
+ function InlineImageExists() {
1530
+ $result = false;
1531
+ for($i = 0; $i < count($this->attachment); $i++) {
1532
+ if($this->attachment[$i][6] == 'inline') {
1533
+ $result = true;
1534
+ break;
1535
+ }
1536
+ }
1537
+
1538
+ return $result;
1539
+ }
1540
+
1541
+ /////////////////////////////////////////////////
1542
+ // CLASS METHODS, MESSAGE RESET
1543
+ /////////////////////////////////////////////////
1544
+
1545
+ /**
1546
+ * Clears all recipients assigned in the TO array. Returns void.
1547
+ * @return void
1548
+ */
1549
+ function ClearAddresses() {
1550
+ $this->to = array();
1551
+ }
1552
+
1553
+ /**
1554
+ * Clears all recipients assigned in the CC array. Returns void.
1555
+ * @return void
1556
+ */
1557
+ function ClearCCs() {
1558
+ $this->cc = array();
1559
+ }
1560
+
1561
+ /**
1562
+ * Clears all recipients assigned in the BCC array. Returns void.
1563
+ * @return void
1564
+ */
1565
+ function ClearBCCs() {
1566
+ $this->bcc = array();
1567
+ }
1568
+
1569
+ /**
1570
+ * Clears all recipients assigned in the ReplyTo array. Returns void.
1571
+ * @return void
1572
+ */
1573
+ function ClearReplyTos() {
1574
+ $this->ReplyTo = array();
1575
+ }
1576
+
1577
+ /**
1578
+ * Clears all recipients assigned in the TO, CC and BCC
1579
+ * array. Returns void.
1580
+ * @return void
1581
+ */
1582
+ function ClearAllRecipients() {
1583
+ $this->to = array();
1584
+ $this->cc = array();
1585
+ $this->bcc = array();
1586
+ }
1587
+
1588
+ /**
1589
+ * Clears all previously set filesystem, string, and binary
1590
+ * attachments. Returns void.
1591
+ * @return void
1592
+ */
1593
+ function ClearAttachments() {
1594
+ $this->attachment = array();
1595
+ }
1596
+
1597
+ /**
1598
+ * Clears all custom headers. Returns void.
1599
+ * @return void
1600
+ */
1601
+ function ClearCustomHeaders() {
1602
+ $this->CustomHeader = array();
1603
+ }
1604
+
1605
+ /////////////////////////////////////////////////
1606
+ // CLASS METHODS, MISCELLANEOUS
1607
+ /////////////////////////////////////////////////
1608
+
1609
+ /**
1610
+ * Adds the error message to the error container.
1611
+ * Returns void.
1612
+ * @access private
1613
+ * @return void
1614
+ */
1615
+ function SetError($msg) {
1616
+ $this->error_count++;
1617
+ $this->ErrorInfo = $msg;
1618
+ }
1619
+
1620
+ /**
1621
+ * Returns the proper RFC 822 formatted date.
1622
+ * @access private
1623
+ * @return string
1624
+ */
1625
+ function RFCDate() {
1626
+ $tz = date('Z');
1627
+ $tzs = ($tz < 0) ? '-' : '+';
1628
+ $tz = abs($tz);
1629
+ $tz = (int)($tz/3600)*100 + ($tz%3600)/60;
1630
+ $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz);
1631
+
1632
+ return $result;
1633
+ }
1634
+
1635
+ /**
1636
+ * Returns the appropriate server variable. Should work with both
1637
+ * PHP 4.1.0+ as well as older versions. Returns an empty string
1638
+ * if nothing is found.
1639
+ * @access private
1640
+ * @return mixed
1641
+ */
1642
+ function ServerVar($varName) {
1643
+ global $HTTP_SERVER_VARS;
1644
+ global $HTTP_ENV_VARS;
1645
+
1646
+ if(!isset($_SERVER)) {
1647
+ $_SERVER = $HTTP_SERVER_VARS;
1648
+ if(!isset($_SERVER['REMOTE_ADDR'])) {
1649
+ $_SERVER = $HTTP_ENV_VARS; // must be Apache
1650
+ }
1651
+ }
1652
+
1653
+ if(isset($_SERVER[$varName])) {
1654
+ return $_SERVER[$varName];
1655
+ } else {
1656
+ return '';
1657
+ }
1658
+ }
1659
+
1660
+ /**
1661
+ * Returns the server hostname or 'localhost.localdomain' if unknown.
1662
+ * @access private
1663
+ * @return string
1664
+ */
1665
+ function ServerHostname() {
1666
+ if ($this->Hostname != '') {
1667
+ $result = $this->Hostname;
1668
+ } elseif ($this->ServerVar('SERVER_NAME') != '') {
1669
+ $result = $this->ServerVar('SERVER_NAME');
1670
+ } else {
1671
+ $result = 'localhost.localdomain';
1672
+ }
1673
+
1674
+ return $result;
1675
+ }
1676
+
1677
+ /**
1678
+ * Returns a message in the appropriate language.
1679
+ * @access private
1680
+ * @return string
1681
+ */
1682
+ function Lang($key) {
1683
+ if(count($this->language) < 1) {
1684
+ $this->SetLanguage('en'); // set the default language
1685
+ }
1686
+
1687
+ if(isset($this->language[$key])) {
1688
+ return $this->language[$key];
1689
+ } else {
1690
+ return 'Language string failed to load: ' . $key;
1691
+ }
1692
+ }
1693
+
1694
+ /**
1695
+ * Returns true if an error occurred.
1696
+ * @return bool
1697
+ */
1698
+ function IsError() {
1699
+ return ($this->error_count > 0);
1700
+ }
1701
+
1702
+ /**
1703
+ * Changes every end of line from CR or LF to CRLF.
1704
+ * @access private
1705
+ * @return string
1706
+ */
1707
+ function FixEOL($str) {
1708
+ $str = str_replace("\r\n", "\n", $str);
1709
+ $str = str_replace("\r", "\n", $str);
1710
+ $str = str_replace("\n", $this->LE, $str);
1711
+ return $str;
1712
+ }
1713
+
1714
+ /**
1715
+ * Adds a custom header.
1716
+ * @return void
1717
+ */
1718
+ function AddCustomHeader($custom_header) {
1719
+ $this->CustomHeader[] = explode(':', $custom_header, 2);
1720
+ }
1721
+
1722
+ /**
1723
+ * Evaluates the message and returns modifications for inline images and backgrounds
1724
+ * @access public
1725
+ * @return $message
1726
+ */
1727
+ function MsgHTML($message,$basedir='') {
1728
+ preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images);
1729
+ if(isset($images[2])) {
1730
+ foreach($images[2] as $i => $url) {
1731
+ // do not change urls for absolute images (thanks to corvuscorax)
1732
+ if (!preg_match('/^[A-z][A-z]*:\/\//',$url)) {
1733
+ $filename = basename($url);
1734
+ $directory = dirname($url);
1735
+ ($directory == '.')?$directory='':'';
1736
+ $cid = 'cid:' . md5($filename);
1737
+ $fileParts = split("\.", $filename);
1738
+ $ext = $fileParts[1];
1739
+ $mimeType = $this->_mime_types($ext);
1740
+ if ( strlen($basedir) > 1 && substr($basedir,-1) != '/') { $basedir .= '/'; }
1741
+ if ( strlen($directory) > 1 && substr($directory,-1) != '/') { $directory .= '/'; }
1742
+ if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64',$mimeType) ) {
1743
+ $message = preg_replace("/".$images[1][$i]."=\"".preg_quote($url, '/')."\"/Ui", $images[1][$i]."=\"".$cid."\"", $message);
1744
+ }
1745
+ }
1746
+ }
1747
+ }
1748
+ $this->IsHTML(true);
1749
+ $this->Body = $message;
1750
+ $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s','',$message)));
1751
+ if ( !empty($textMsg) && empty($this->AltBody) ) {
1752
+ $this->AltBody = html_entity_decode($textMsg);
1753
+ }
1754
+ if ( empty($this->AltBody) ) {
1755
+ $this->AltBody = 'To view this email message, open the email in with HTML compatibility!' . "\n\n";
1756
+ }
1757
+ }
1758
+
1759
+ /**
1760
+ * Gets the mime type of the embedded or inline image
1761
+ * @access private
1762
+ * @return mime type of ext
1763
+ */
1764
+ function _mime_types($ext = '') {
1765
+ $mimes = array(
1766
+ 'ai' => 'application/postscript',
1767
+ 'aif' => 'audio/x-aiff',
1768
+ 'aifc' => 'audio/x-aiff',
1769
+ 'aiff' => 'audio/x-aiff',
1770
+ 'avi' => 'video/x-msvideo',
1771
+ 'bin' => 'application/macbinary',
1772
+ 'bmp' => 'image/bmp',
1773
+ 'class' => 'application/octet-stream',
1774
+ 'cpt' => 'application/mac-compactpro',
1775
+ 'css' => 'text/css',
1776
+ 'dcr' => 'application/x-director',
1777
+ 'dir' => 'application/x-director',
1778
+ 'dll' => 'application/octet-stream',
1779
+ 'dms' => 'application/octet-stream',
1780
+ 'doc' => 'application/msword',
1781
+ 'dvi' => 'application/x-dvi',
1782
+ 'dxr' => 'application/x-director',
1783
+ 'eml' => 'message/rfc822',
1784
+ 'eps' => 'application/postscript',
1785
+ 'exe' => 'application/octet-stream',
1786
+ 'gif' => 'image/gif',
1787
+ 'gtar' => 'application/x-gtar',
1788
+ 'htm' => 'text/html',
1789
+ 'html' => 'text/html',
1790
+ 'jpe' => 'image/jpeg',
1791
+ 'jpeg' => 'image/jpeg',
1792
+ 'jpg' => 'image/jpeg',
1793
+ 'hqx' => 'application/mac-binhex40',
1794
+ 'js' => 'application/x-javascript',
1795
+ 'lha' => 'application/octet-stream',
1796
+ 'log' => 'text/plain',
1797
+ 'lzh' => 'application/octet-stream',
1798
+ 'mid' => 'audio/midi',
1799
+ 'midi' => 'audio/midi',
1800
+ 'mif' => 'application/vnd.mif',
1801
+ 'mov' => 'video/quicktime',
1802
+ 'movie' => 'video/x-sgi-movie',
1803
+ 'mp2' => 'audio/mpeg',
1804
+ 'mp3' => 'audio/mpeg',
1805
+ 'mpe' => 'video/mpeg',
1806
+ 'mpeg' => 'video/mpeg',
1807
+ 'mpg' => 'video/mpeg',
1808
+ 'mpga' => 'audio/mpeg',
1809
+ 'oda' => 'application/oda',
1810
+ 'pdf' => 'application/pdf',
1811
+ 'php' => 'application/x-httpd-php',
1812
+ 'php3' => 'application/x-httpd-php',
1813
+ 'php4' => 'application/x-httpd-php',
1814
+ 'phps' => 'application/x-httpd-php-source',
1815
+ 'phtml' => 'application/x-httpd-php',
1816
+ 'png' => 'image/png',
1817
+ 'ppt' => 'application/vnd.ms-powerpoint',
1818
+ 'ps' => 'application/postscript',
1819
+ 'psd' => 'application/octet-stream',
1820
+ 'qt' => 'video/quicktime',
1821
+ 'ra' => 'audio/x-realaudio',
1822
+ 'ram' => 'audio/x-pn-realaudio',
1823
+ 'rm' => 'audio/x-pn-realaudio',
1824
+ 'rpm' => 'audio/x-pn-realaudio-plugin',
1825
+ 'rtf' => 'text/rtf',
1826
+ 'rtx' => 'text/richtext',
1827
+ 'rv' => 'video/vnd.rn-realvideo',
1828
+ 'sea' => 'application/octet-stream',
1829
+ 'shtml' => 'text/html',
1830
+ 'sit' => 'application/x-stuffit',
1831
+ 'so' => 'application/octet-stream',
1832
+ 'smi' => 'application/smil',
1833
+ 'smil' => 'application/smil',
1834
+ 'swf' => 'application/x-shockwave-flash',
1835
+ 'tar' => 'application/x-tar',
1836
+ 'text' => 'text/plain',
1837
+ 'txt' => 'text/plain',
1838
+ 'tgz' => 'application/x-tar',
1839
+ 'tif' => 'image/tiff',
1840
+ 'tiff' => 'image/tiff',
1841
+ 'wav' => 'audio/x-wav',
1842
+ 'wbxml' => 'application/vnd.wap.wbxml',
1843
+ 'wmlc' => 'application/vnd.wap.wmlc',
1844
+ 'word' => 'application/msword',
1845
+ 'xht' => 'application/xhtml+xml',
1846
+ 'xhtml' => 'application/xhtml+xml',
1847
+ 'xl' => 'application/excel',
1848
+ 'xls' => 'application/vnd.ms-excel',
1849
+ 'xml' => 'text/xml',
1850
+ 'xsl' => 'text/xml',
1851
+ 'zip' => 'application/zip'
1852
+ );
1853
+ return ( ! isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)];
1854
+ }
1855
+
1856
+ /**
1857
+ * Set (or reset) Class Objects (variables)
1858
+ *
1859
+ * Usage Example:
1860
+ * $page->set('X-Priority', '3');
1861
+ *
1862
+ * @access public
1863
+ * @param string $name Parameter Name
1864
+ * @param mixed $value Parameter Value
1865
+ * NOTE: will not work with arrays, there are no arrays to set/reset
1866
+ */
1867
+ function set ( $name, $value = '' ) {
1868
+ if ( isset($this->$name) ) {
1869
+ $this->$name = $value;
1870
+ } else {
1871
+ $this->SetError('Cannot set or reset variable ' . $name);
1872
+ return false;
1873
+ }
1874
+ }
1875
+
1876
+ /**
1877
+ * Read a file from a supplied filename and return it.
1878
+ *
1879
+ * @access public
1880
+ * @param string $filename Parameter File Name
1881
+ */
1882
+ function getFile($filename) {
1883
+ $return = '';
1884
+ if ($fp = fopen($filename, 'rb')) {
1885
+ while (!feof($fp)) {
1886
+ $return .= fread($fp, 1024);
1887
+ }
1888
+ fclose($fp);
1889
+ return $return;
1890
+ } else {
1891
+ return false;
1892
+ }
1893
+ }
1894
+
1895
+ /**
1896
+ * Strips newlines to prevent header injection.
1897
+ * @access private
1898
+ * @param string $str String
1899
+ * @return string
1900
+ */
1901
+ function SecureHeader($str) {
1902
+ $str = trim($str);
1903
+ $str = str_replace("\r", "", $str);
1904
+ $str = str_replace("\n", "", $str);
1905
+ return $str;
1906
+ }
1907
+
1908
+ /**
1909
+ * Set the private key file and password to sign the message.
1910
+ *
1911
+ * @access public
1912
+ * @param string $key_filename Parameter File Name
1913
+ * @param string $key_pass Password for private key
1914
+ */
1915
+ function Sign($cert_filename, $key_filename, $key_pass) {
1916
+ $this->sign_cert_file = $cert_filename;
1917
+ $this->sign_key_file = $key_filename;
1918
+ $this->sign_key_pass = $key_pass;
1919
+ }
1920
+
1921
+ }
bp-forums/bbpress/bb-includes/backpress/class.passwordhash.php ADDED
@@ -0,0 +1,258 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Last sync [WP11537]
3
+
4
+ /**
5
+ * Portable PHP password hashing framework.
6
+ * @package phpass
7
+ * @since 2.5
8
+ * @version 0.1
9
+ * @link http://www.openwall.com/phpass/
10
+ */
11
+
12
+ #
13
+ # Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in
14
+ # the public domain.
15
+ #
16
+ # There's absolutely no warranty.
17
+ #
18
+ # Please be sure to update the Version line if you edit this file in any way.
19
+ # It is suggested that you leave the main version number intact, but indicate
20
+ # your project name (after the slash) and add your own revision information.
21
+ #
22
+ # Please do not change the "private" password hashing method implemented in
23
+ # here, thereby making your hashes incompatible. However, if you must, please
24
+ # change the hash type identifier (the "$P$") to something different.
25
+ #
26
+ # Obviously, since this code is in the public domain, the above are not
27
+ # requirements (there can be none), but merely suggestions.
28
+ #
29
+
30
+ /**
31
+ * Portable PHP password hashing framework.
32
+ *
33
+ * @package phpass
34
+ * @version 0.1 / genuine
35
+ * @link http://www.openwall.com/phpass/
36
+ * @since 2.5
37
+ */
38
+ class PasswordHash {
39
+ var $itoa64;
40
+ var $iteration_count_log2;
41
+ var $portable_hashes;
42
+ var $random_state;
43
+
44
+ function PasswordHash($iteration_count_log2, $portable_hashes)
45
+ {
46
+ $this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
47
+
48
+ if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
49
+ $iteration_count_log2 = 8;
50
+ $this->iteration_count_log2 = $iteration_count_log2;
51
+
52
+ $this->portable_hashes = $portable_hashes;
53
+
54
+ $this->random_state = microtime() . (function_exists('getmypid') ? getmypid() : '') . uniqid(rand(), TRUE);
55
+
56
+ }
57
+
58
+ function get_random_bytes($count)
59
+ {
60
+ $output = '';
61
+ if (($fh = @fopen('/dev/urandom', 'rb'))) {
62
+ $output = fread($fh, $count);
63
+ fclose($fh);
64
+ }
65
+
66
+ if (strlen($output) < $count) {
67
+ $output = '';
68
+ for ($i = 0; $i < $count; $i += 16) {
69
+ $this->random_state =
70
+ md5(microtime() . $this->random_state);
71
+ $output .=
72
+ pack('H*', md5($this->random_state));
73
+ }
74
+ $output = substr($output, 0, $count);
75
+ }
76
+
77
+ return $output;
78
+ }
79
+
80
+ function encode64($input, $count)
81
+ {
82
+ $output = '';
83
+ $i = 0;
84
+ do {
85
+ $value = ord($input[$i++]);
86
+ $output .= $this->itoa64[$value & 0x3f];
87
+ if ($i < $count)
88
+ $value |= ord($input[$i]) << 8;
89
+ $output .= $this->itoa64[($value >> 6) & 0x3f];
90
+ if ($i++ >= $count)
91
+ break;
92
+ if ($i < $count)
93
+ $value |= ord($input[$i]) << 16;
94
+ $output .= $this->itoa64[($value >> 12) & 0x3f];
95
+ if ($i++ >= $count)
96
+ break;
97
+ $output .= $this->itoa64[($value >> 18) & 0x3f];
98
+ } while ($i < $count);
99
+
100
+ return $output;
101
+ }
102
+
103
+ function gensalt_private($input)
104
+ {
105
+ $output = '$P$';
106
+ $output .= $this->itoa64[min($this->iteration_count_log2 +
107
+ ((PHP_VERSION >= '5') ? 5 : 3), 30)];
108
+ $output .= $this->encode64($input, 6);
109
+
110
+ return $output;
111
+ }
112
+
113
+ function crypt_private($password, $setting)
114
+ {
115
+ $output = '*0';
116
+ if (substr($setting, 0, 2) == $output)
117
+ $output = '*1';
118
+
119
+ if (substr($setting, 0, 3) != '$P$')
120
+ return $output;
121
+
122
+ $count_log2 = strpos($this->itoa64, $setting[3]);
123
+ if ($count_log2 < 7 || $count_log2 > 30)
124
+ return $output;
125
+
126
+ $count = 1 << $count_log2;
127
+
128
+ $salt = substr($setting, 4, 8);
129
+ if (strlen($salt) != 8)
130
+ return $output;
131
+
132
+ # We're kind of forced to use MD5 here since it's the only
133
+ # cryptographic primitive available in all versions of PHP
134
+ # currently in use. To implement our own low-level crypto
135
+ # in PHP would result in much worse performance and
136
+ # consequently in lower iteration counts and hashes that are
137
+ # quicker to crack (by non-PHP code).
138
+ if (PHP_VERSION >= '5') {
139
+ $hash = md5($salt . $password, TRUE);
140
+ do {
141
+ $hash = md5($hash . $password, TRUE);
142
+ } while (--$count);
143
+ } else {
144
+ $hash = pack('H*', md5($salt . $password));
145
+ do {
146
+ $hash = pack('H*', md5($hash . $password));
147
+ } while (--$count);
148
+ }
149
+
150
+ $output = substr($setting, 0, 12);
151
+ $output .= $this->encode64($hash, 16);
152
+
153
+ return $output;
154
+ }
155
+
156
+ function gensalt_extended($input)
157
+ {
158
+ $count_log2 = min($this->iteration_count_log2 + 8, 24);
159
+ # This should be odd to not reveal weak DES keys, and the
160
+ # maximum valid value is (2**24 - 1) which is odd anyway.
161
+ $count = (1 << $count_log2) - 1;
162
+
163
+ $output = '_';
164
+ $output .= $this->itoa64[$count & 0x3f];
165
+ $output .= $this->itoa64[($count >> 6) & 0x3f];
166
+ $output .= $this->itoa64[($count >> 12) & 0x3f];
167
+ $output .= $this->itoa64[($count >> 18) & 0x3f];
168
+
169
+ $output .= $this->encode64($input, 3);
170
+
171
+ return $output;
172
+ }
173
+
174
+ function gensalt_blowfish($input)
175
+ {
176
+ # This one needs to use a different order of characters and a
177
+ # different encoding scheme from the one in encode64() above.
178
+ # We care because the last character in our encoded string will
179
+ # only represent 2 bits. While two known implementations of
180
+ # bcrypt will happily accept and correct a salt string which
181
+ # has the 4 unused bits set to non-zero, we do not want to take
182
+ # chances and we also do not want to waste an additional byte
183
+ # of entropy.
184
+ $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
185
+
186
+ $output = '$2a$';
187
+ $output .= chr(ord('0') + $this->iteration_count_log2 / 10);
188
+ $output .= chr(ord('0') + $this->iteration_count_log2 % 10);
189
+ $output .= '$';
190
+
191
+ $i = 0;
192
+ do {
193
+ $c1 = ord($input[$i++]);
194
+ $output .= $itoa64[$c1 >> 2];
195
+ $c1 = ($c1 & 0x03) << 4;
196
+ if ($i >= 16) {
197
+ $output .= $itoa64[$c1];
198
+ break;
199
+ }
200
+
201
+ $c2 = ord($input[$i++]);
202
+ $c1 |= $c2 >> 4;
203
+ $output .= $itoa64[$c1];
204
+ $c1 = ($c2 & 0x0f) << 2;
205
+
206
+ $c2 = ord($input[$i++]);
207
+ $c1 |= $c2 >> 6;
208
+ $output .= $itoa64[$c1];
209
+ $output .= $itoa64[$c2 & 0x3f];
210
+ } while (1);
211
+
212
+ return $output;
213
+ }
214
+
215
+ function HashPassword($password)
216
+ {
217
+ $random = '';
218
+
219
+ if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) {
220
+ $random = $this->get_random_bytes(16);
221
+ $hash =
222
+ crypt($password, $this->gensalt_blowfish($random));
223
+ if (strlen($hash) == 60)
224
+ return $hash;
225
+ }
226
+
227
+ if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) {
228
+ if (strlen($random) < 3)
229
+ $random = $this->get_random_bytes(3);
230
+ $hash =
231
+ crypt($password, $this->gensalt_extended($random));
232
+ if (strlen($hash) == 20)
233
+ return $hash;
234
+ }
235
+
236
+ if (strlen($random) < 6)
237
+ $random = $this->get_random_bytes(6);
238
+ $hash =
239
+ $this->crypt_private($password,
240
+ $this->gensalt_private($random));
241
+ if (strlen($hash) == 34)
242
+ return $hash;
243
+
244
+ # Returning '*' on error is safe here, but would _not_ be safe
245
+ # in a crypt(3)-like function used _both_ for generating new
246
+ # hashes and for validating passwords against existing hashes.
247
+ return '*';
248
+ }
249
+
250
+ function CheckPassword($password, $stored_hash)
251
+ {
252
+ $hash = $this->crypt_private($password, $stored_hash);
253
+ if ($hash[0] == '*')
254
+ $hash = crypt($password, $stored_hash);
255
+
256
+ return $hash == $stored_hash;
257
+ }
258
+ }
bp-forums/bbpress/bb-includes/backpress/class.wp-ajax-response.php ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Last sync [WP11537]
3
+
4
+ /**
5
+ * Send XML response back to AJAX request.
6
+ *
7
+ * @package WordPress
8
+ * @since 2.1.0
9
+ */
10
+ class WP_Ajax_Response {
11
+ /**
12
+ * Store XML responses to send.
13
+ *
14
+ * @since 2.1.0
15
+ * @var array
16
+ * @access private
17
+ */
18
+ var $responses = array();
19
+
20
+ /**
21
+ * PHP4 Constructor - Passes args to {@link WP_Ajax_Response::add()}.
22
+ *
23
+ * @since 2.1.0
24
+ * @see WP_Ajax_Response::add()
25
+ *
26
+ * @param string|array $args Optional. Will be passed to add() method.
27
+ * @return WP_Ajax_Response
28
+ */
29
+ function WP_Ajax_Response( $args = '' ) {
30
+ if ( !empty($args) )
31
+ $this->add($args);
32
+ }
33
+
34
+ /**
35
+ * Append to XML response based on given arguments.
36
+ *
37
+ * The arguments that can be passed in the $args parameter are below. It is
38
+ * also possible to pass a WP_Error object in either the 'id' or 'data'
39
+ * argument. The parameter isn't actually optional, content should be given
40
+ * in order to send the correct response.
41
+ *
42
+ * 'what' argument is a string that is the XMLRPC response type.
43
+ * 'action' argument is a boolean or string that acts like a nonce.
44
+ * 'id' argument can be WP_Error or an integer.
45
+ * 'old_id' argument is false by default or an integer of the previous ID.
46
+ * 'position' argument is an integer or a string with -1 = top, 1 = bottom,
47
+ * html ID = after, -html ID = before.
48
+ * 'data' argument is a string with the content or message.
49
+ * 'supplemental' argument is an array of strings that will be children of
50
+ * the supplemental element.
51
+ *
52
+ * @since 2.1.0
53
+ *
54
+ * @param string|array $args Override defaults.
55
+ * @return string XML response.
56
+ */
57
+ function add( $args = '' ) {
58
+ $defaults = array(
59
+ 'what' => 'object', 'action' => false,
60
+ 'id' => '0', 'old_id' => false,
61
+ 'position' => 1,
62
+ 'data' => '', 'supplemental' => array()
63
+ );
64
+
65
+ $r = wp_parse_args( $args, $defaults );
66
+ extract( $r, EXTR_SKIP );
67
+ $position = preg_replace( '/[^a-z0-9:_-]/i', '', $position );
68
+
69
+ if ( is_wp_error($id) ) {
70
+ $data = $id;
71
+ $id = 0;
72
+ }
73
+
74
+ $response = '';
75
+ if ( is_wp_error($data) ) {
76
+ foreach ( (array) $data->get_error_codes() as $code ) {
77
+ $response .= "<wp_error code='$code'><![CDATA[" . $data->get_error_message($code) . "]]></wp_error>";
78
+ if ( !$error_data = $data->get_error_data($code) )
79
+ continue;
80
+ $class = '';
81
+ if ( is_object($error_data) ) {
82
+ $class = ' class="' . get_class($error_data) . '"';
83
+ $error_data = get_object_vars($error_data);
84
+ }
85
+
86
+ $response .= "<wp_error_data code='$code'$class>";
87
+
88
+ if ( is_scalar($error_data) ) {
89
+ $response .= "<![CDATA[$error_data]]>";
90
+ } elseif ( is_array($error_data) ) {
91
+ foreach ( $error_data as $k => $v )
92
+ $response .= "<$k><![CDATA[$v]]></$k>";
93
+ }
94
+
95
+ $response .= "</wp_error_data>";
96
+ }
97
+ } else {
98
+ $response = "<response_data><![CDATA[$data]]></response_data>";
99
+ }
100
+
101
+ $s = '';
102
+ if ( is_array($supplemental) ) {
103
+ foreach ( $supplemental as $k => $v )
104
+ $s .= "<$k><![CDATA[$v]]></$k>";
105
+ $s = "<supplemental>$s</supplemental>";
106
+ }
107
+
108
+ if ( false === $action )
109
+ $action = $_POST['action'];
110
+
111
+ $x = '';
112
+ $x .= "<response action='{$action}_$id'>"; // The action attribute in the xml output is formatted like a nonce action
113
+ $x .= "<$what id='$id' " . ( false === $old_id ? '' : "old_id='$old_id' " ) . "position='$position'>";
114
+ $x .= $response;
115
+ $x .= $s;
116
+ $x .= "</$what>";
117
+ $x .= "</response>";
118
+
119
+ $this->responses[] = $x;
120
+ return $x;
121
+ }
122
+
123
+ /**
124
+ * Display XML formatted responses.
125
+ *
126
+ * Sets the content type header to text/xml.
127
+ *
128
+ * @since 2.1.0
129
+ */
130
+ function send() {
131
+ header('Content-Type: text/xml');
132
+ echo "<?xml version='1.0' standalone='yes'?><wp_ajax>";
133
+ foreach ( (array) $this->responses as $response )
134
+ echo $response;
135
+ echo '</wp_ajax>';
136
+ die();
137
+ }
138
+ }
bp-forums/bbpress/bb-includes/backpress/class.wp-auth.php ADDED
@@ -0,0 +1,298 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class WP_Auth
3
+ {
4
+ var $db; // BBPDB object
5
+ var $users; // WP_Users object
6
+
7
+ var $cookies;
8
+
9
+ var $current = 0;
10
+
11
+ function WP_Auth( &$db, &$users, $cookies )
12
+ {
13
+ $this->__construct( $db, $users, $cookies );
14
+ }
15
+
16
+ /**
17
+ * @param array $cookies Array indexed by internal name of cookie. Values are arrays of array defining cookie parameters.
18
+ * $cookies = array(
19
+ * 'auth' => array(
20
+ * 0 => array(
21
+ * 'domain' => (string) cookie domain
22
+ * 'path' => (string) cookie path
23
+ * 'name' => (string) cookie name
24
+ * 'secure' => (bool) restrict cookie to HTTPS only
25
+ * )
26
+ * )
27
+ * );
28
+ *
29
+ * At least one cookie is required. Give it an internal name of 'auth'.
30
+ *
31
+ * Suggested cookie structure:
32
+ * logged_in: whether or not a user is logged in. Send everywhere.
33
+ * auth: used to authorize user's actions. Send only to domains/paths that need it (e.g. wp-admin/)
34
+ * secure_auth: used to authorize user's actions. Send only to domains/paths that need it and only over HTTPS
35
+ */
36
+ function __construct( &$db, &$users, $cookies )
37
+ {
38
+ $this->db =& $db;
39
+ $this->users =& $users;
40
+
41
+ $cookies = wp_parse_args( $cookies, array( 'auth' => null ) );
42
+ $_cookies = array();
43
+ foreach ( $cookies as $_scheme => $_scheme_cookies ) {
44
+ foreach ( $_scheme_cookies as $_scheme_cookie ) {
45
+ $_cookies[$_scheme][] = wp_parse_args( $_scheme_cookie, array( 'domain' => null, 'path' => null, 'name' => '' ) );
46
+ }
47
+ unset( $_scheme_cookie );
48
+ }
49
+ unset( $_scheme, $_scheme_cookies );
50
+ $this->cookies = $_cookies;
51
+ unset( $_cookies );
52
+ }
53
+
54
+ /**
55
+ * Changes the current user by ID or name
56
+ *
57
+ * Set $id to null and specify a name if you do not know a user's ID
58
+ *
59
+ * Some WordPress functionality is based on the current user and
60
+ * not based on the signed in user. Therefore, it opens the ability
61
+ * to edit and perform actions on users who aren't signed in.
62
+ *
63
+ * @since 2.0.4
64
+ * @uses do_action() Calls 'set_current_user' hook after setting the current user.
65
+ *
66
+ * @param int $id User ID
67
+ * @param string $name User's username
68
+ * @return BP_User Current user User object
69
+ */
70
+ function set_current_user( $user_id )
71
+ {
72
+ $user = $this->users->get_user( $user_id );
73
+ if ( !$user || is_wp_error( $user ) ) {
74
+ $this->current = 0;
75
+ return $this->current;
76
+ }
77
+
78
+ $user_id = $user->ID;
79
+
80
+ if ( isset( $this->current->ID ) && $user_id == $this->current->ID ) {
81
+ return $this->current;
82
+ }
83
+
84
+ if ( class_exists( 'BP_User' ) ) {
85
+ $this->current = new BP_User( $user_id );
86
+ } else {
87
+ $this->current =& $user;
88
+ }
89
+
90
+ // WP add_action( 'set_current_user', 'setup_userdata', 1 );
91
+
92
+ do_action( 'set_current_user', $user_id );
93
+
94
+ return $this->current;
95
+ }
96
+
97
+ /**
98
+ * Populate variables with information about the currently logged in user
99
+ *
100
+ * Will set the current user, if the current user is not set. The current
101
+ * user will be set to the logged in person. If no user is logged in, then
102
+ * it will set the current user to 0, which is invalid and won't have any
103
+ * permissions.
104
+ *
105
+ * @since 0.71
106
+ * @uses $current_user Checks if the current user is set
107
+ * @uses wp_validate_auth_cookie() Retrieves current logged in user.
108
+ *
109
+ * @return bool|null False on XMLRPC Request and invalid auth cookie. Null when current user set
110
+ */
111
+ function get_current_user()
112
+ {
113
+ if ( !empty( $this->current ) ) {
114
+ return $this->current;
115
+ }
116
+
117
+ if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) {
118
+ $this->set_current_user( 0 );
119
+ } elseif ( $user_id = $this->validate_auth_cookie( null, 'logged_in' ) ) {
120
+ $this->set_current_user( $user_id );
121
+ } else {
122
+ $this->set_current_user( 0 );
123
+ }
124
+
125
+ return $this->current;
126
+ }
127
+
128
+ /**
129
+ * Validates authentication cookie
130
+ *
131
+ * The checks include making sure that the authentication cookie
132
+ * is set and pulling in the contents (if $cookie is not used).
133
+ *
134
+ * Makes sure the cookie is not expired. Verifies the hash in
135
+ * cookie is what is should be and compares the two.
136
+ *
137
+ * @since 2.5
138
+ *
139
+ * @param string $cookie Optional. If used, will validate contents instead of cookie's
140
+ * @return bool|int False if invalid cookie, User ID if valid.
141
+ */
142
+ function validate_auth_cookie( $cookie = null, $scheme = 'auth' )
143
+ {
144
+ if ( empty( $cookie ) ) {
145
+ foreach ( $this->cookies[$scheme] as $_scheme_cookie ) {
146
+ // Take the first cookie of type scheme that exists
147
+ if ( !empty( $_COOKIE[$_scheme_cookie['name']] ) ) {
148
+ $cookie = $_COOKIE[$_scheme_cookie['name']];
149
+ break;
150
+ }
151
+ }
152
+ }
153
+
154
+ if ( !$cookie ) {
155
+ return false;
156
+ }
157
+
158
+ $cookie_elements = explode( '|', $cookie );
159
+ if ( count( $cookie_elements ) != 3 ) {
160
+ do_action( 'auth_cookie_malformed', $cookie, $scheme );
161
+ return false;
162
+ }
163
+
164
+ list( $username, $expiration, $hmac ) = $cookie_elements;
165
+
166
+ $expired = $expiration;
167
+
168
+ // Allow a grace period for POST and AJAX requests
169
+ if ( defined( 'DOING_AJAX' ) || 'POST' == $_SERVER['REQUEST_METHOD'] ) {
170
+ $expired += 3600;
171
+ }
172
+
173
+ if ( $expired < time() ) {
174
+ do_action( 'auth_cookie_expired', $cookie_elements );
175
+ return false;
176
+ }
177
+
178
+ $user = $this->users->get_user( $username, array( 'by' => 'login' ) );
179
+ if ( !$user || is_wp_error( $user ) ) {
180
+ do_action( 'auth_cookie_bad_username', $cookie_elements );
181
+ return $user;
182
+ }
183
+
184
+ $pass_frag = '';
185
+ if ( 1 < WP_AUTH_COOKIE_VERSION ) {
186
+ $pass_frag = substr( $user->user_pass, 8, 4 );
187
+ }
188
+
189
+ $key = call_user_func( backpress_get_option( 'hash_function_name' ), $username . $pass_frag . '|' . $expiration, $scheme );
190
+ $hash = hash_hmac( 'md5', $username . '|' . $expiration, $key );
191
+
192
+ if ( $hmac != $hash ) {
193
+ do_action( 'auth_cookie_bad_hash', $cookie_elements );
194
+ return false;
195
+ }
196
+
197
+ do_action( 'auth_cookie_valid', $cookie_elements, $user );
198
+
199
+ return $user->ID;
200
+ }
201
+
202
+ /**
203
+ * Generate authentication cookie contents
204
+ *
205
+ * @since 2.5
206
+ * @uses apply_filters() Calls 'auth_cookie' hook on $cookie contents, User ID
207
+ * and expiration of cookie.
208
+ *
209
+ * @param int $user_id User ID
210
+ * @param int $expiration Cookie expiration in seconds
211
+ * @return string Authentication cookie contents
212
+ */
213
+ function generate_auth_cookie( $user_id, $expiration, $scheme = 'auth' )
214
+ {
215
+ $user = $this->users->get_user( $user_id );
216
+ if ( !$user || is_wp_error( $user ) ) {
217
+ return $user;
218
+ }
219
+
220
+ $pass_frag = '';
221
+ if ( 1 < WP_AUTH_COOKIE_VERSION ) {
222
+ $pass_frag = substr( $user->user_pass, 8, 4 );
223
+ }
224
+
225
+ $key = call_user_func( backpress_get_option( 'hash_function_name' ), $user->user_login . $pass_frag . '|' . $expiration, $scheme );
226
+ $hash = hash_hmac('md5', $user->user_login . '|' . $expiration, $key);
227
+
228
+ $cookie = $user->user_login . '|' . $expiration . '|' . $hash;
229
+
230
+ return apply_filters( 'auth_cookie', $cookie, $user_id, $expiration, $scheme );
231
+ }
232
+
233
+ /**
234
+ * Sets the authentication cookies based User ID
235
+ *
236
+ * The $remember parameter increases the time that the cookie will
237
+ * be kept. The default the cookie is kept without remembering is
238
+ * two days. When $remember is set, the cookies will be kept for
239
+ * 14 days or two weeks.
240
+ *
241
+ * @since 2.5
242
+ *
243
+ * @param int $user_id User ID
244
+ * @param int $expiration the UNIX time after which the cookie's authentication token is no longer valid
245
+ * @param int $expire the UNIX time at which the cookie expires
246
+ * @param int $scheme name of the
247
+ */
248
+ function set_auth_cookie( $user_id, $expiration = 0, $expire = 0, $scheme = 'auth' )
249
+ {
250
+ if ( !isset( $this->cookies[$scheme] ) ) {
251
+ return;
252
+ }
253
+
254
+ if ( !$expiration = absint( $expiration ) ) {
255
+ $expiration = time() + 172800; // 2 days
256
+ }
257
+
258
+ $expire = absint( $expire );
259
+
260
+ foreach ( $this->cookies[$scheme] as $_cookie ) {
261
+ $cookie = $this->generate_auth_cookie( $user_id, $expiration, $scheme );
262
+ if ( is_wp_error( $cookie ) ) {
263
+ return $cookie;
264
+ }
265
+
266
+ do_action( 'set_' . $scheme . '_cookie', $cookie, $expire, $expiration, $user_id, $scheme );
267
+
268
+ $domain = $_cookie['domain'];
269
+ $secure = isset($_cookie['secure']) ? (bool) $_cookie['secure'] : false;
270
+
271
+ // Set httponly if the php version is >= 5.2.0
272
+ if ( version_compare( phpversion(), '5.2.0', 'ge' ) ) {
273
+ setcookie( $_cookie['name'], $cookie, $expire, $_cookie['path'], $domain, $secure, true );
274
+ } else {
275
+ $domain = ( empty( $domain ) ) ? $domain : $domain . '; HttpOnly';
276
+ setcookie( $_cookie['name'], $cookie, $expire, $_cookie['path'], $domain, $secure );
277
+ }
278
+ }
279
+ unset( $_cookie );
280
+ }
281
+
282
+ /**
283
+ * Deletes all of the cookies associated with authentication
284
+ *
285
+ * @since 2.5
286
+ */
287
+ function clear_auth_cookie()
288
+ {
289
+ do_action( 'clear_auth_cookie' );
290
+ foreach ( $this->cookies as $_scheme => $_scheme_cookies ) {
291
+ foreach ( $_scheme_cookies as $_cookie ) {
292
+ setcookie( $_cookie['name'], ' ', time() - 31536000, $_cookie['path'], $_cookie['domain'] );
293
+ }
294
+ unset( $_cookie );
295
+ }
296
+ unset( $_scheme, $_scheme_cookies );
297
+ }
298
+ }
bp-forums/bbpress/bb-includes/backpress/class.wp-dependencies.php ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BackPress Scripts enqueue.
4
+ *
5
+ * These classes were refactored from the WordPress WP_Scripts and WordPress
6
+ * script enqueue API.
7
+ *
8
+ * @package BackPress
9
+ * @since r74
10
+ */
11
+
12
+ /**
13
+ * BackPress enqueued dependiences class.
14
+ *
15
+ * @package BackPress
16
+ * @uses _WP_Dependency
17
+ * @since r74
18
+ */
19
+ class WP_Dependencies {
20
+ var $registered = array();
21
+ var $queue = array();
22
+ var $to_do = array();
23
+ var $done = array();