PageRenderTime 53ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/svntrunk/bp-forums/bbpress/bb-includes/functions.bb-core.php

https://bitbucket.org/simplemediacode/bptrunk
PHP | 1836 lines | 1380 code | 251 blank | 205 comment | 306 complexity | 1e1cbfc0e8c4f0111155aebb09bd897b MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * Core bbPress functions.
  4. *
  5. * @package bbPress
  6. */
  7. /**
  8. * Initialization functions mostly called in bb-settings.php
  9. */
  10. /**
  11. * Marks things as deprecated and informs when they have been used.
  12. *
  13. * @since 0.9
  14. *
  15. * @param string $type The type of thing that was attempted: function, class::function, constant, variable or page.
  16. * @param string $name The thing that was called.
  17. * @param string $replacement Optional. The thing that should have been called.
  18. * @uses $bb_log BP_Log logging object.
  19. */
  20. function bb_log_deprecated( $type, $name, $replacement = 'none' ) {
  21. global $bb_log;
  22. $bb_log->notice( sprintf( __( 'Using deprecated bbPress %1$s - %2$s - replace with - %3$s' ), $type, $name, $replacement ) );
  23. if ( $bb_log->level & BP_LOG_DEBUG && $bb_log->level & BP_LOG_NOTICE ) { // Only compute the location if we're going to log it.
  24. $backtrace = debug_backtrace();
  25. $file = $backtrace[2]['file'];
  26. if ( substr( $file, 0, strlen( BB_PATH ) - 1 ) == rtrim( BB_PATH, '\\/') )
  27. $file = substr( $file, strlen( BB_PATH ) );
  28. $file = str_replace( '\\', '/', $file );
  29. // 0 = this function, 1 = the deprecated function
  30. $bb_log->notice( ' ' . sprintf( __( 'on line %1$d of file %2$s' ), $backtrace[2]['line'], $file ) );
  31. }
  32. }
  33. /**
  34. * Sanitizes user input en-masse.
  35. *
  36. * @param mixed $array The array of values or a single value to sanitize, usually a global variable like $_GET or $_POST.
  37. * @param boolean $trim Optional. Whether to trim the value or not. Default is true.
  38. * @return mixed The sanitized data.
  39. */
  40. function bb_global_sanitize( $array, $trim = true )
  41. {
  42. foreach ( $array as $k => $v ) {
  43. if ( is_array( $v ) ) {
  44. $array[$k] = bb_global_sanitize( $v );
  45. } else {
  46. if ( !get_magic_quotes_gpc() ) {
  47. $array[$k] = addslashes( $v );
  48. }
  49. if ( $trim ) {
  50. $array[$k] = trim( $array[$k] );
  51. }
  52. }
  53. }
  54. return $array;
  55. }
  56. /**
  57. * Reports whether bbPress is installed by getting forums.
  58. *
  59. * @return boolean True if there are forums, otherwise false.
  60. */
  61. function bb_is_installed()
  62. {
  63. // Maybe grab all the forums and cache them
  64. global $bbdb;
  65. $bbdb->suppress_errors();
  66. $forums = (array) @bb_get_forums();
  67. $bbdb->suppress_errors(false);
  68. if ( !$forums ) {
  69. return false;
  70. }
  71. return true;
  72. }
  73. /**
  74. * Sets the required variables to connect to custom user tables.
  75. *
  76. * @return boolean Always returns true.
  77. */
  78. function bb_set_custom_user_tables()
  79. {
  80. global $bb;
  81. // Check for older style custom user table
  82. if ( !isset( $bb->custom_tables['users'] ) ) { // Don't stomp new setting style
  83. if ( $bb->custom_user_table = bb_get_option( 'custom_user_table' ) ) {
  84. if ( !isset( $bb->custom_tables ) ) {
  85. $bb->custom_tables = array();
  86. }
  87. $bb->custom_tables['users'] = $bb->custom_user_table;
  88. }
  89. }
  90. // Check for older style custom user meta table
  91. if ( !isset( $bb->custom_tables['usermeta'] ) ) { // Don't stomp new setting style
  92. if ( $bb->custom_user_meta_table = bb_get_option( 'custom_user_meta_table' ) ) {
  93. if ( !isset( $bb->custom_tables ) ) {
  94. $bb->custom_tables = array();
  95. }
  96. $bb->custom_tables['usermeta'] = $bb->custom_user_meta_table;
  97. }
  98. }
  99. // Check for older style wp_table_prefix
  100. if ( $bb->wp_table_prefix = bb_get_option( 'wp_table_prefix' ) ) { // User has set old constant
  101. if ( !isset( $bb->custom_tables ) ) {
  102. $bb->custom_tables = array(
  103. 'users' => $bb->wp_table_prefix . 'users',
  104. 'usermeta' => $bb->wp_table_prefix . 'usermeta'
  105. );
  106. } else {
  107. if ( !isset( $bb->custom_tables['users'] ) ) { // Don't stomp new setting style
  108. $bb->custom_tables['users'] = $bb->wp_table_prefix . 'users';
  109. }
  110. if ( !isset( $bb->custom_tables['usermeta'] ) ) {
  111. $bb->custom_tables['usermeta'] = $bb->wp_table_prefix . 'usermeta';
  112. }
  113. }
  114. }
  115. if ( bb_get_option( 'wordpress_mu_primary_blog_id' ) ) {
  116. $bb->wordpress_mu_primary_blog_id = bb_get_option( 'wordpress_mu_primary_blog_id' );
  117. }
  118. // Check for older style user database
  119. if ( !isset( $bb->custom_databases ) ) {
  120. $bb->custom_databases = array();
  121. }
  122. if ( !isset( $bb->custom_databases['user'] ) ) {
  123. if ( $bb->user_bbdb_name = bb_get_option( 'user_bbdb_name' ) ) {
  124. $bb->custom_databases['user']['name'] = $bb->user_bbdb_name;
  125. }
  126. if ( $bb->user_bbdb_user = bb_get_option( 'user_bbdb_user' ) ) {
  127. $bb->custom_databases['user']['user'] = $bb->user_bbdb_user;
  128. }
  129. if ( $bb->user_bbdb_password = bb_get_option( 'user_bbdb_password' ) ) {
  130. $bb->custom_databases['user']['password'] = $bb->user_bbdb_password;
  131. }
  132. if ( $bb->user_bbdb_host = bb_get_option( 'user_bbdb_host' ) ) {
  133. $bb->custom_databases['user']['host'] = $bb->user_bbdb_host;
  134. }
  135. if ( $bb->user_bbdb_charset = bb_get_option( 'user_bbdb_charset' ) ) {
  136. $bb->custom_databases['user']['charset'] = $bb->user_bbdb_charset;
  137. }
  138. if ( $bb->user_bbdb_collate = bb_get_option( 'user_bbdb_collate' ) ) {
  139. $bb->custom_databases['user']['collate'] = $bb->user_bbdb_collate;
  140. }
  141. if ( isset( $bb->custom_databases['user'] ) ) {
  142. if ( isset( $bb->custom_tables['users'] ) ) {
  143. $bb->custom_tables['users'] = array( 'user', $bb->custom_tables['users'] );
  144. }
  145. if ( isset( $bb->custom_tables['usermeta'] ) ) {
  146. $bb->custom_tables['usermeta'] = array( 'user', $bb->custom_tables['usermeta'] );
  147. }
  148. }
  149. }
  150. return true;
  151. }
  152. /* Pagination */
  153. /**
  154. * Retrieve paginated links for pages.
  155. *
  156. * Technically, the function can be used to create paginated link list for any
  157. * area. The 'base' argument is used to reference the url, which will be used to
  158. * create the paginated links. The 'format' argument is then used for replacing
  159. * the page number. It is however, most likely and by default, to be used on the
  160. * archive post pages.
  161. *
  162. * The 'type' argument controls format of the returned value. The default is
  163. * 'plain', which is just a string with the links separated by a newline
  164. * character. The other possible values are either 'array' or 'list'. The
  165. * 'array' value will return an array of the paginated link list to offer full
  166. * control of display. The 'list' value will place all of the paginated links in
  167. * an unordered HTML list.
  168. *
  169. * The 'total' argument is the total amount of pages and is an integer. The
  170. * 'current' argument is the current page number and is also an integer.
  171. *
  172. * An example of the 'base' argument is "http://example.com/all_posts.php%_%"
  173. * and the '%_%' is required. The '%_%' will be replaced by the contents of in
  174. * the 'format' argument. An example for the 'format' argument is "?page=%#%"
  175. * and the '%#%' is also required. The '%#%' will be replaced with the page
  176. * number.
  177. *
  178. * You can include the previous and next links in the list by setting the
  179. * 'prev_next' argument to true, which it is by default. You can set the
  180. * previous text, by using the 'prev_text' argument. You can set the next text
  181. * by setting the 'next_text' argument.
  182. *
  183. * If the 'show_all' argument is set to true, then it will show all of the pages
  184. * instead of a short list of the pages near the current page. By default, the
  185. * 'show_all' is set to false and controlled by the 'end_size' and 'mid_size'
  186. * arguments. The 'end_size' argument is how many numbers on either the start
  187. * and the end list edges, by default is 1. The 'mid_size' argument is how many
  188. * numbers to either side of current page, but not including current page.
  189. *
  190. * It is possible to add query vars to the link by using the 'add_args' argument
  191. * and see {@link add_query_arg()} for more information.
  192. *
  193. * @since 1.0
  194. *
  195. * @param string|array $args Optional. Override defaults.
  196. * @return array|string String of page links or array of page links.
  197. */
  198. function bb_paginate_links( $args = '' ) {
  199. $defaults = array(
  200. 'base' => '%_%', // http://example.com/all_posts.php%_% : %_% is replaced by format (below)
  201. 'format' => '?page=%#%', // ?page=%#% : %#% is replaced by the page number
  202. 'total' => 1,
  203. 'current' => 0,
  204. 'show_all' => false,
  205. 'prev_next' => true,
  206. 'prev_text' => __( '&laquo; Previous' ),
  207. 'next_text' => __( 'Next &raquo;' ),
  208. 'end_size' => 1, // How many numbers on either end including the end
  209. 'mid_size' => 2, // How many numbers to either side of current not including current
  210. 'type' => 'plain',
  211. 'add_args' => false, // array of query args to add
  212. 'add_fragment' => '',
  213. 'n_title' => __( 'Page %d' ), // Not from WP version
  214. 'prev_title' => __( 'Previous page' ), // Not from WP version
  215. 'next_title' => __( 'Next page' ) // Not from WP version
  216. );
  217. $args = wp_parse_args( $args, $defaults );
  218. extract( $args, EXTR_SKIP );
  219. // Who knows what else people pass in $args
  220. $total = (int) $total;
  221. if ( $total < 2 )
  222. return;
  223. $current = (int) $current;
  224. $end_size = 0 < (int) $end_size ? (int) $end_size : 1; // Out of bounds? Make it the default.
  225. $mid_size = 0 <= (int) $mid_size ? (int) $mid_size : 2;
  226. $add_args = is_array($add_args) ? $add_args : false;
  227. $r = '';
  228. $page_links = array();
  229. $n = 0;
  230. $dots = false;
  231. $empty_format = '';
  232. if ( strpos( $format, '?' ) === 0 ) {
  233. $empty_format = '?';
  234. }
  235. if ( $prev_next && $current && 1 < $current ) {
  236. $link = str_replace( '%_%', 2 == $current ? $empty_format : $format, $base );
  237. $link = str_replace( '%#%', $current - 1, $link );
  238. $link = str_replace( '?&', '?', $link );
  239. if ( $add_args )
  240. $link = add_query_arg( $add_args, $link );
  241. $link .= $add_fragment;
  242. $page_links[] = '<a class="prev page-numbers" href="' . esc_url( $link ) . '" title="' . esc_attr( $prev_title ) . '">' . $prev_text . '</a>';
  243. }
  244. for ( $n = 1; $n <= $total; $n++ ) {
  245. if ( $n == $current ) {
  246. $n_display = bb_number_format_i18n( $n );
  247. $n_display_title = esc_attr( sprintf( $n_title, $n ) );
  248. $page_links[] = '<span class="page-numbers current" title="' . $n_display_title . '">' . $n_display . '</span>';
  249. $dots = true;
  250. } else {
  251. if ( $show_all || ( $n <= $end_size || ( $current && $n >= $current - $mid_size && $n <= $current + $mid_size ) || $n > $total - $end_size ) ) {
  252. $n_display = bb_number_format_i18n( $n );
  253. $n_display_title = esc_attr( sprintf( $n_title, $n ) );
  254. $link = str_replace( '%_%', 1 == $n ? $empty_format : $format, $base );
  255. $link = str_replace( '%#%', $n, $link );
  256. $link = str_replace( '?&', '?', $link );
  257. if ( $add_args )
  258. $link = add_query_arg( $add_args, $link );
  259. $link .= $add_fragment;
  260. $page_links[] = '<a class="page-numbers" href="' . esc_url( $link ) . '" title="' . $n_display_title . '">' . $n_display . '</a>';
  261. $dots = true;
  262. } elseif ( $dots && !$show_all ) {
  263. $page_links[] = '<span class="page-numbers dots">&hellip;</span>';
  264. $dots = false;
  265. }
  266. }
  267. }
  268. if ( $prev_next && $current && ( $current < $total || -1 == $total ) ) {
  269. $link = str_replace( '%_%', $format, $base );
  270. $link = str_replace( '%#%', $current + 1, $link );
  271. if ( $add_args )
  272. $link = add_query_arg( $add_args, $link );
  273. $link .= $add_fragment;
  274. $page_links[] = '<a class="next page-numbers" href="' . esc_url( $link ) . '" title="' . esc_attr( $next_title ) . '">' . $next_text . '</a>';
  275. }
  276. switch ( $type ) {
  277. case 'array':
  278. return $page_links;
  279. break;
  280. case 'list':
  281. $r .= '<ul class="page-numbers">' . "\n\t" . '<li>';
  282. $r .= join( '</li>' . "\n\t" . '<li>', $page_links );
  283. $r .= '</li>' . "\n" . '</ul>' . "\n";
  284. break;
  285. default:
  286. $r = join( "\n", $page_links );
  287. break;
  288. }
  289. return $r;
  290. }
  291. function bb_get_uri_page() {
  292. if ( isset($_GET['page']) && is_numeric($_GET['page']) && 1 < (int) $_GET['page'] )
  293. return (int) $_GET['page'];
  294. if ( isset($_SERVER['PATH_INFO']) )
  295. $path = $_SERVER['PATH_INFO'];
  296. else
  297. if ( !$path = strtok($_SERVER['REQUEST_URI'], '?') )
  298. return 1;
  299. if ( preg_match( '/^\/([0-9]+)\/?$/', $path, $matches ) ) {
  300. $page = (int) $matches[1];
  301. if ( 1 < $page ) {
  302. return $page;
  303. }
  304. }
  305. if ( $page = strstr($path, '/page/') ) {
  306. $page = (int) substr($page, 6);
  307. if ( 1 < $page )
  308. return $page;
  309. }
  310. return 1;
  311. }
  312. //expects $item = 1 to be the first, not 0
  313. function bb_get_page_number( $item, $per_page = 0 ) {
  314. if ( !$per_page )
  315. $per_page = bb_get_option('page_topics');
  316. return intval( ceil( $item / $per_page ) ); // page 1 is the first page
  317. }
  318. /* Time */
  319. function bb_timer_stop($display = 0, $precision = 3) { //if called like bb_timer_stop(1), will echo $timetotal
  320. global $bb_timestart, $timeend;
  321. $mtime = explode(' ', microtime());
  322. $timeend = $mtime[1] + $mtime[0];
  323. $timetotal = $timeend - $bb_timestart;
  324. if ($display)
  325. echo bb_number_format_i18n($timetotal, $precision);
  326. return bb_number_format_i18n($timetotal, $precision);
  327. }
  328. // GMT -> so many minutes ago
  329. function bb_since( $original, $args = '' )
  330. {
  331. $defaults = array(
  332. 'levels' => 1,
  333. 'separator' => ', '
  334. );
  335. // $args used to be $do_more
  336. // $do_more = 0 is equivalent to $args['levels'] = 1
  337. // $do_more = 1 is equivalent to $args['levels'] = 2
  338. if ( !is_array( $args ) ) {
  339. $args = array(
  340. 'levels' => abs( (integer) $args ) + 1
  341. );
  342. }
  343. $args = wp_parse_args( $args, $defaults );
  344. extract( $args, EXTR_SKIP );
  345. $today = (integer) time();
  346. if ( !is_numeric( $original ) ) {
  347. if ( $today < $_original = bb_gmtstrtotime( str_replace( ',', ' ', $original ) ) ) { // Looks like bb_since was called twice
  348. return $original;
  349. } else {
  350. $original = $_original;
  351. }
  352. }
  353. $seconds = $today - ( (integer) $original );
  354. if ( 0 === $seconds ) {
  355. return sprintf( _n( '%d second', '%d seconds', 0 ), 0 );
  356. }
  357. $levels = abs( (integer) $levels );
  358. if ( 0 === $levels ) {
  359. return '';
  360. }
  361. // array of time period chunks
  362. $chunks = array(
  363. ( 60 * 60 * 24 * 365 ), // years
  364. ( 60 * 60 * 24 * 30 ), // months
  365. ( 60 * 60 * 24 * 7 ), // weeks
  366. ( 60 * 60 * 24 ), // days
  367. ( 60 * 60 ), // hours
  368. ( 60 ), // minutes
  369. ( 1 ) // seconds
  370. );
  371. $caught = 0;
  372. $parts = array();
  373. for ( $i = 0; $i < count( $chunks ); $i++ ) {
  374. if ( ( $count = floor( $seconds / $chunks[$i] ) ) || $caught ) {
  375. if ( $count ) {
  376. $trans = array(
  377. _n( '%d year', '%d years', $count ),
  378. _n( '%d month', '%d months', $count ),
  379. _n( '%d week', '%d weeks', $count ),
  380. _n( '%d day', '%d days', $count ),
  381. _n( '%d hour', '%d hours', $count ),
  382. _n( '%d minute', '%d minutes', $count ),
  383. _n( '%d second', '%d seconds', $count )
  384. );
  385. $parts[] = sprintf( $trans[$i], $count );
  386. }
  387. $caught++;
  388. $seconds = $seconds - ( $count * $chunks[$i] );
  389. }
  390. if ( $caught === $levels ) {
  391. break;
  392. }
  393. }
  394. if ( empty( $parts ) ) {
  395. return sprintf( _n( '%d second', '%d seconds', 0 ), 0 );
  396. }
  397. return join( $separator, $parts );
  398. }
  399. function bb_current_time( $type = 'timestamp' ) {
  400. return current_time( $type, true );
  401. }
  402. // GMT -> Local
  403. // in future versions this could eaily become a user option.
  404. function bb_offset_time( $time, $args = null ) {
  405. if ( isset($args['format']) && 'since' == $args['format'] )
  406. return $time;
  407. if ( !is_numeric($time) ) {
  408. if ( -1 !== $_time = bb_gmtstrtotime( $time ) )
  409. return gmdate('Y-m-d H:i:s', $_time + bb_get_option( 'gmt_offset' ) * 3600);
  410. else
  411. return $time; // Perhaps should return -1 here
  412. } else {
  413. return $time + bb_get_option( 'gmt_offset' ) * 3600;
  414. }
  415. }
  416. /* Permalinking / URLs / Paths */
  417. /**
  418. * BB_URI_CONTEXT_* - Bitwise definitions for bb_uri() and bb_get_uri() contexts
  419. *
  420. * @since 1.0
  421. */
  422. define( 'BB_URI_CONTEXT_NONE', 0 );
  423. define( 'BB_URI_CONTEXT_HEADER', 1 );
  424. define( 'BB_URI_CONTEXT_TEXT', 2 );
  425. define( 'BB_URI_CONTEXT_A_HREF', 4 );
  426. define( 'BB_URI_CONTEXT_FORM_ACTION', 8 );
  427. define( 'BB_URI_CONTEXT_IMG_SRC', 16 );
  428. define( 'BB_URI_CONTEXT_LINK_STYLESHEET_HREF', 32 );
  429. define( 'BB_URI_CONTEXT_LINK_ALTERNATE_HREF', 64 );
  430. define( 'BB_URI_CONTEXT_LINK_OTHER', 128 );
  431. define( 'BB_URI_CONTEXT_SCRIPT_SRC', 256 );
  432. define( 'BB_URI_CONTEXT_IFRAME_SRC', 512 );
  433. define( 'BB_URI_CONTEXT_BB_FEED', 1024 );
  434. define( 'BB_URI_CONTEXT_BB_USER_FORMS', 2048 );
  435. define( 'BB_URI_CONTEXT_BB_ADMIN', 4096 );
  436. define( 'BB_URI_CONTEXT_BB_XMLRPC', 8192 );
  437. define( 'BB_URI_CONTEXT_WP_HTTP_REQUEST', 16384 );
  438. //define( 'BB_URI_CONTEXT_*', 32768 ); // Reserved for future definitions
  439. //define( 'BB_URI_CONTEXT_*', 65536 ); // Reserved for future definitions
  440. //define( 'BB_URI_CONTEXT_*', 131072 ); // Reserved for future definitions
  441. //define( 'BB_URI_CONTEXT_*', 262144 ); // Reserved for future definitions
  442. define( 'BB_URI_CONTEXT_AKISMET', 524288 );
  443. /**
  444. * Echo a URI based on the URI setting
  445. *
  446. * @since 1.0
  447. *
  448. * @param $resource string The directory, may include a querystring
  449. * @param $query mixed The query arguments as a querystring or an associative array
  450. * @param $context integer The context of the URI, use BB_URI_CONTEXT_*
  451. * @return void
  452. */
  453. function bb_uri( $resource = null, $query = null, $context = BB_URI_CONTEXT_A_HREF )
  454. {
  455. echo apply_filters( 'bb_uri', bb_get_uri( $resource, $query, $context ), $resource, $query, $context );
  456. }
  457. /**
  458. * Return a URI based on the URI setting
  459. *
  460. * @since 1.0
  461. *
  462. * @param $resource string The directory, may include a querystring
  463. * @param $query mixed The query arguments as a querystring or an associative array
  464. * @param $context integer The context of the URI, use BB_URI_CONTEXT_*
  465. * @return string The complete URI
  466. */
  467. function bb_get_uri( $resource = null, $query = null, $context = BB_URI_CONTEXT_A_HREF )
  468. {
  469. // If there is a querystring in the resource then extract it
  470. if ( $resource && strpos( $resource, '?' ) !== false ) {
  471. list( $_resource, $_query ) = explode( '?', trim( $resource ), 2 );
  472. $resource = $_resource;
  473. $_query = wp_parse_args( $_query );
  474. } else {
  475. // Make sure $_query is an array for array_merge()
  476. $_query = array();
  477. }
  478. // $query can be an array as well as a string
  479. if ( $query ) {
  480. if ( is_string( $query ) ) {
  481. $query = ltrim( trim( $query ), '?' );
  482. }
  483. $query = wp_parse_args( $query );
  484. }
  485. // Make sure $query is an array for array_merge()
  486. if ( !$query ) {
  487. $query = array();
  488. }
  489. // Merge the queries into a single array
  490. $query = array_merge( $_query, $query );
  491. // Make sure context is an integer
  492. if ( !$context || !is_integer( $context ) ) {
  493. $context = BB_URI_CONTEXT_A_HREF;
  494. }
  495. // Get the base URI
  496. static $_uri;
  497. if( !isset( $_uri ) ) {
  498. $_uri = bb_get_option( 'uri' );
  499. }
  500. $uri = $_uri;
  501. // Use https?
  502. if (
  503. ( ( $context & BB_URI_CONTEXT_BB_USER_FORMS ) && force_ssl_login() ) // Force https when required on user forms
  504. ||
  505. ( ( $context & BB_URI_CONTEXT_BB_ADMIN ) && force_ssl_admin() ) // Force https when required in admin
  506. ) {
  507. static $_uri_ssl;
  508. if( !isset( $_uri_ssl ) ) {
  509. $_uri_ssl = bb_get_option( 'uri_ssl' );
  510. }
  511. $uri = $_uri_ssl;
  512. }
  513. // Add the directory
  514. $uri .= ltrim( $resource, '/' );
  515. // Add the query string to the URI
  516. $uri = add_query_arg( $query, $uri );
  517. return apply_filters( 'bb_get_uri', $uri, $resource, $context );
  518. }
  519. /**
  520. * Forces redirection to an SSL page when required
  521. *
  522. * @since 1.0
  523. *
  524. * @return void
  525. */
  526. function bb_ssl_redirect()
  527. {
  528. $page = bb_get_location();
  529. do_action( 'bb_ssl_redirect' );
  530. if ( BB_IS_ADMIN ) {
  531. if ( !force_ssl_admin() ) {
  532. return;
  533. }
  534. } else {
  535. switch ( $page ) {
  536. case 'login-page':
  537. case 'register-page':
  538. if ( !force_ssl_login() ) {
  539. return;
  540. }
  541. break;
  542. case 'profile-page':
  543. global $self;
  544. if ( $self == 'profile-edit.php' ) {
  545. if ( !force_ssl_login() ) {
  546. return;
  547. }
  548. } else {
  549. return;
  550. }
  551. break;
  552. default:
  553. return;
  554. break;
  555. }
  556. }
  557. if ( is_ssl() ) {
  558. return;
  559. }
  560. $uri_ssl = parse_url( bb_get_option( 'uri_ssl' ) );
  561. $uri = $uri_ssl['scheme'] . '://' . $uri_ssl['host'] . $_SERVER['REQUEST_URI'];
  562. bb_safe_redirect( $uri );
  563. exit;
  564. }
  565. function bb_get_path( $level = 1, $base = false, $request = false ) {
  566. if ( !$request )
  567. $request = $_SERVER['REQUEST_URI'];
  568. if ( is_string($request) )
  569. $request = parse_url($request);
  570. if ( !is_array($request) || !isset($request['path']) )
  571. return '';
  572. $path = rtrim($request['path'], " \t\n\r\0\x0B/");
  573. if ( !$base )
  574. $base = rtrim(bb_get_option('path'), " \t\n\r\0\x0B/");
  575. $path = preg_replace('|' . preg_quote($base, '|') . '/?|','',$path,1);
  576. if ( !$path )
  577. return '';
  578. if ( strpos($path, '/') === false )
  579. return '';
  580. $url = explode('/',$path);
  581. if ( !isset($url[$level]) )
  582. return '';
  583. return urldecode($url[$level]);
  584. }
  585. function bb_find_filename( $text ) {
  586. if ( preg_match('|.*?/([a-z\-]+\.php)/?.*|', $text, $matches) )
  587. return $matches[1];
  588. else {
  589. $path = bb_get_option( 'path' );
  590. $text = preg_replace("#^$path#", '', $text);
  591. $text = preg_replace('#/.+$#', '', $text);
  592. return $text . '.php';
  593. }
  594. return false;
  595. }
  596. function bb_send_headers() {
  597. if ( bb_is_user_logged_in() )
  598. nocache_headers();
  599. @header('Content-Type: ' . bb_get_option( 'html_type' ) . '; charset=' . bb_get_option( 'charset' ));
  600. do_action( 'bb_send_headers' );
  601. }
  602. function bb_pingback_header() {
  603. if (bb_get_option('enable_pingback'))
  604. @header('X-Pingback: '. bb_get_uri('xmlrpc.php', null, BB_URI_CONTEXT_HEADER + BB_URI_CONTEXT_BB_XMLRPC));
  605. }
  606. // Inspired by and adapted from Yung-Lung Scott YANG's http://scott.yang.id.au/2005/05/permalink-redirect/ (GPL)
  607. function bb_repermalink() {
  608. global $page;
  609. $location = bb_get_location();
  610. $uri = $_SERVER['REQUEST_URI'];
  611. if ( isset($_GET['id']) )
  612. $id = $_GET['id'];
  613. else
  614. $id = bb_get_path();
  615. $_original_id = $id;
  616. do_action( 'pre_permalink', $id );
  617. $id = apply_filters( 'bb_repermalink', $id );
  618. switch ($location) {
  619. case 'front-page':
  620. $path = null;
  621. $querystring = null;
  622. if ($page > 1) {
  623. if (bb_get_option( 'mod_rewrite' )) {
  624. $path = 'page/' . $page;
  625. } else {
  626. $querystring = array('page' => $page);
  627. }
  628. }
  629. $permalink = bb_get_uri($path, $querystring, BB_URI_CONTEXT_HEADER);
  630. $issue_404 = true;
  631. break;
  632. case 'forum-page':
  633. if (empty($id)) {
  634. $permalink = bb_get_uri(null, null, BB_URI_CONTEXT_HEADER);
  635. break;
  636. }
  637. global $forum_id, $forum;
  638. $forum = bb_get_forum( $id );
  639. $forum_id = $forum->forum_id;
  640. $permalink = get_forum_link( $forum->forum_id, $page );
  641. break;
  642. case 'topic-edit-page':
  643. case 'topic-page':
  644. if (empty($id)) {
  645. $permalink = bb_get_uri(null, null, BB_URI_CONTEXT_HEADER);
  646. break;
  647. }
  648. global $topic_id, $topic;
  649. $topic = get_topic( $id );
  650. $topic_id = $topic->topic_id;
  651. $permalink = get_topic_link( $topic->topic_id, $page );
  652. break;
  653. case 'profile-page': // This handles the admin side of the profile as well.
  654. global $user_id, $user, $profile_hooks, $self;
  655. if ( isset($_GET['id']) )
  656. $id = $_GET['id'];
  657. elseif ( isset($_GET['username']) )
  658. $id = $_GET['username'];
  659. else
  660. $id = bb_get_path();
  661. $_original_id = $id;
  662. if ( !$id ) {
  663. $user = bb_get_current_user(); // Attempt to go to the current users profile
  664. } else {
  665. if ( bb_get_option( 'mod_rewrite' ) === 'slugs') {
  666. if ( !$user = bb_get_user_by_nicename( $id ) ) {
  667. $user = bb_get_user( $id );
  668. }
  669. } else {
  670. if ( !$user = bb_get_user( $id ) ) {
  671. $user = bb_get_user_by_nicename( $id );
  672. }
  673. }
  674. }
  675. if ( !$user || ( 1 == $user->user_status && !bb_current_user_can( 'moderate' ) ) )
  676. bb_die(__('User not found.'), '', 404);
  677. $user_id = $user->ID;
  678. bb_global_profile_menu_structure();
  679. $valid = false;
  680. if ( $tab = isset($_GET['tab']) ? $_GET['tab'] : bb_get_path(2) ) {
  681. foreach ( $profile_hooks as $valid_tab => $valid_file ) {
  682. if ( $tab == $valid_tab ) {
  683. $valid = true;
  684. $self = $valid_file;
  685. }
  686. }
  687. }
  688. if ( $valid ) {
  689. $permalink = get_profile_tab_link( $user->ID, $tab, $page );
  690. } else {
  691. $permalink = get_user_profile_link( $user->ID, $page );
  692. unset($self, $tab);
  693. }
  694. break;
  695. case 'favorites-page':
  696. $permalink = get_favorites_link();
  697. break;
  698. case 'tag-page': // It's not an integer and tags.php pulls double duty.
  699. $id = ( isset($_GET['tag']) ) ? $_GET['tag'] : false;
  700. if ( ! $id || ! bb_get_tag( (string) $id ) )
  701. $permalink = bb_get_tag_page_link();
  702. else {
  703. global $tag, $tag_name;
  704. $tag_name = $id;
  705. $tag = bb_get_tag( (string) $id );
  706. $permalink = bb_get_tag_link( 0, $page ); // 0 => grabs $tag from global.
  707. }
  708. break;
  709. case 'view-page': // Not an integer
  710. if ( isset($_GET['view']) )
  711. $id = $_GET['view'];
  712. else
  713. $id = bb_get_path();
  714. $_original_id = $id;
  715. global $view;
  716. $view = $id;
  717. $permalink = get_view_link( $view, $page );
  718. break;
  719. default:
  720. return;
  721. break;
  722. }
  723. wp_parse_str($_SERVER['QUERY_STRING'], $args);
  724. $args = urlencode_deep($args);
  725. if ( $args ) {
  726. $permalink = add_query_arg($args, $permalink);
  727. if ( bb_get_option('mod_rewrite') ) {
  728. $pretty_args = array('id', 'page', 'tag', 'tab', 'username'); // these are already specified in the path
  729. if ( $location == 'view-page' )
  730. $pretty_args[] = 'view';
  731. foreach ( $pretty_args as $pretty_arg )
  732. $permalink = remove_query_arg( $pretty_arg, $permalink );
  733. }
  734. }
  735. $permalink = apply_filters( 'bb_repermalink_result', $permalink, $location );
  736. $domain = bb_get_option('domain');
  737. $domain = preg_replace('/^https?/', '', $domain);
  738. $check = preg_replace( '|^.*' . trim($domain, ' /' ) . '|', '', $permalink, 1 );
  739. $uri = rtrim( $uri, " \t\n\r\0\x0B?" );
  740. $uri = str_replace( '/index.php', '/', $uri );
  741. global $bb_log;
  742. $bb_log->debug($uri, 'bb_repermalink() ' . __('REQUEST_URI'));
  743. $bb_log->debug($check, 'bb_repermalink() ' . __('should be'));
  744. $bb_log->debug($permalink, 'bb_repermalink() ' . __('full permalink'));
  745. $bb_log->debug(isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : null, 'bb_repermalink() ' . __('PATH_INFO'));
  746. if ( $check != $uri && $check != str_replace(urlencode($_original_id), $_original_id, $uri) ) {
  747. if ( $issue_404 && rtrim( $check, " \t\n\r\0\x0B/" ) !== rtrim( $uri, " \t\n\r\0\x0B/" ) ) {
  748. status_header( 404 );
  749. bb_load_template( '404.php' );
  750. } else {
  751. wp_redirect( $permalink );
  752. }
  753. exit;
  754. }
  755. do_action( 'post_permalink', $permalink );
  756. }
  757. /* Profile/Admin */
  758. function bb_global_profile_menu_structure() {
  759. global $user_id, $profile_menu, $profile_hooks;
  760. // Menu item name
  761. // The capability required for own user to view the tab ('' to allow non logged in access)
  762. // The capability required for other users to view the tab ('' to allow non logged in access)
  763. // The URL of the item's file
  764. // Item name for URL (nontranslated)
  765. $profile_menu[0] = array(__('Edit'), 'edit_profile', 'edit_users', 'profile-edit.php', 'edit');
  766. $profile_menu[5] = array(__('Favorites'), '', '', 'favorites.php', 'favorites');
  767. // Create list of page plugin hook names the current user can access
  768. $profile_hooks = array();
  769. foreach ($profile_menu as $profile_tab)
  770. if ( bb_can_access_tab( $profile_tab, bb_get_current_user_info( 'id' ), $user_id ) )
  771. $profile_hooks[bb_sanitize_with_dashes($profile_tab[4])] = $profile_tab[3];
  772. do_action('bb_profile_menu');
  773. ksort($profile_menu);
  774. }
  775. function bb_add_profile_tab($tab_title, $users_cap, $others_cap, $file, $arg = false) {
  776. global $profile_menu, $profile_hooks, $user_id;
  777. $arg = $arg ? $arg : $tab_title;
  778. $profile_tab = array($tab_title, $users_cap, $others_cap, $file, $arg);
  779. $profile_menu[] = $profile_tab;
  780. if ( bb_can_access_tab( $profile_tab, bb_get_current_user_info( 'id' ), $user_id ) )
  781. $profile_hooks[bb_sanitize_with_dashes($arg)] = $file;
  782. }
  783. function bb_can_access_tab( $profile_tab, $viewer_id, $owner_id ) {
  784. global $bb_current_user;
  785. $viewer_id = (int) $viewer_id;
  786. $owner_id = (int) $owner_id;
  787. if ( $viewer_id == bb_get_current_user_info( 'id' ) )
  788. $viewer =& $bb_current_user;
  789. else
  790. $viewer = new BP_User( $viewer_id );
  791. if ( !$viewer )
  792. return '' === $profile_tab[2];
  793. if ( $owner_id == $viewer_id ) {
  794. if ( '' === $profile_tab[1] )
  795. return true;
  796. else
  797. return $viewer->has_cap($profile_tab[1]);
  798. } else {
  799. if ( '' === $profile_tab[2] )
  800. return true;
  801. else
  802. return $viewer->has_cap($profile_tab[2]);
  803. }
  804. }
  805. //meta_key => (required?, Label, hCard property). Don't use user_{anything} as the name of your meta_key.
  806. function bb_get_profile_info_keys( $context = null ) {
  807. return apply_filters( 'get_profile_info_keys', array(
  808. 'first_name' => array(0, __('First name')),
  809. 'last_name' => array(0, __('Last name')),
  810. 'display_name' => array(1, __('Display name as')),
  811. 'user_email' => array(1, __('Email'), 'email'),
  812. 'user_url' => array(0, __('Website'), 'url'),
  813. 'from' => array(0, __('Location')),
  814. 'occ' => array(0, __('Occupation'), 'role'),
  815. 'interest' => array(0, __('Interests')),
  816. ), $context );
  817. }
  818. function bb_get_profile_admin_keys( $context = null ) {
  819. global $bbdb;
  820. return apply_filters( 'get_profile_admin_keys', array(
  821. $bbdb->prefix . 'title' => array(0, __('Custom Title'))
  822. ), $context );
  823. }
  824. function bb_get_assignable_caps() {
  825. $caps = array();
  826. if ( $throttle_time = bb_get_option( 'throttle_time' ) )
  827. $caps['throttle'] = sprintf( __('Ignore the %d second post throttling limit'), $throttle_time );
  828. return apply_filters( 'get_assignable_caps', $caps );
  829. }
  830. /* Views */
  831. function bb_get_views() {
  832. global $bb_views;
  833. $views = array();
  834. foreach ( (array) $bb_views as $view => $array )
  835. $views[$view] = $array['title'];
  836. return $views;
  837. }
  838. function bb_register_view( $view, $title, $query_args = '', $feed = TRUE ) {
  839. global $bb_views;
  840. $view = bb_slug_sanitize( $view );
  841. $title = esc_html( $title );
  842. if ( !$view || !$title )
  843. return false;
  844. $query_args = wp_parse_args( $query_args );
  845. if ( !$sticky_set = isset($query_args['sticky']) )
  846. $query_args['sticky'] = 'no';
  847. $bb_views[$view]['title'] = $title;
  848. $bb_views[$view]['query'] = $query_args;
  849. $bb_views[$view]['sticky'] = !$sticky_set; // No sticky set => split into stickies and not
  850. $bb_views[$view]['feed'] = $feed;
  851. return $bb_views[$view];
  852. }
  853. function bb_deregister_view( $view ) {
  854. global $bb_views;
  855. $view = bb_slug_sanitize( $view );
  856. if ( !isset($bb_views[$view]) )
  857. return false;
  858. unset($GLOBALS['bb_views'][$view]);
  859. return true;
  860. }
  861. function bb_view_query( $view, $new_args = '' ) {
  862. global $bb_views;
  863. $view = bb_slug_sanitize( $view );
  864. if ( !isset($bb_views[$view]) )
  865. return false;
  866. if ( $new_args ) {
  867. $new_args = wp_parse_args( $new_args );
  868. $query_args = array_merge( $bb_views[$view]['query'], $new_args );
  869. } else {
  870. $query_args = $bb_views[$view]['query'];
  871. }
  872. return new BB_Query( 'topic', $query_args, "bb_view_$view" );
  873. }
  874. function bb_get_view_query_args( $view ) {
  875. global $bb_views;
  876. $view = bb_slug_sanitize( $view );
  877. if ( !isset($bb_views[$view]) )
  878. return false;
  879. return $bb_views[$view]['query'];
  880. }
  881. function bb_register_default_views() {
  882. // no posts (besides the first one), older than 2 hours
  883. bb_register_view( 'no-replies', __('Topics with no replies'), array( 'post_count' => 1, 'started' => '<' . gmdate( 'YmdH', time() - 7200 ) ) );
  884. bb_register_view( 'untagged' , __('Topics with no tags') , array( 'tag_count' => 0 ) );
  885. }
  886. /* Feeds */
  887. /**
  888. * Send status headers for clients supporting Conditional Get
  889. *
  890. * The function sends the Last-Modified and ETag headers for all clients. It
  891. * then checks both the If-None-Match and If-Modified-Since headers to see if
  892. * the client has used them. If so, and the ETag does matches the client ETag
  893. * or the last modified date sent by the client is newer or the same as the
  894. * generated last modified, the function sends a 304 Not Modified and exits.
  895. *
  896. * @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3
  897. * @param string $bb_last_modified Last modified time. Must be a HTTP-date
  898. */
  899. function bb_send_304( $bb_last_modified ) {
  900. $bb_etag = '"' . md5($bb_last_modified) . '"';
  901. @header("Last-Modified: $bb_last_modified");
  902. @header("ETag: $bb_etag");
  903. // Support for Conditional GET
  904. if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) $client_etag = stripslashes($_SERVER['HTTP_IF_NONE_MATCH']);
  905. else $client_etag = false;
  906. $client_last_modified = trim( $_SERVER['HTTP_IF_MODIFIED_SINCE']);
  907. // If string is empty, return 0. If not, attempt to parse into a timestamp
  908. $client_modified_timestamp = $client_last_modified ? bb_gmtstrtotime($client_last_modified) : 0;
  909. // Make a timestamp for our most recent modification...
  910. $bb_modified_timestamp = bb_gmtstrtotime($bb_last_modified);
  911. if ( ($client_last_modified && $client_etag) ?
  912. (($client_modified_timestamp >= $bb_modified_timestamp) && ($client_etag == $bb_etag)) :
  913. (($client_modified_timestamp >= $bb_modified_timestamp) || ($client_etag == $bb_etag)) ) {
  914. status_header( 304 );
  915. exit;
  916. }
  917. }
  918. /* Nonce */
  919. /**
  920. * Retrieve URL with nonce added to URL query.
  921. *
  922. * @package bbPress
  923. * @subpackage Security
  924. * @since 1.0
  925. *
  926. * @param string $actionurl URL to add nonce action
  927. * @param string $action Optional. Nonce action name
  928. * @return string URL with nonce action added.
  929. */
  930. function bb_nonce_url( $actionurl, $action = -1 ) {
  931. $actionurl = str_replace( '&amp;', '&', $actionurl );
  932. $nonce = bb_create_nonce( $action );
  933. return esc_html( add_query_arg( '_wpnonce', $nonce, $actionurl ) );
  934. }
  935. /**
  936. * Retrieve or display nonce hidden field for forms.
  937. *
  938. * The nonce field is used to validate that the contents of the form came from
  939. * the location on the current site and not somewhere else. The nonce does not
  940. * offer absolute protection, but should protect against most cases. It is very
  941. * important to use nonce field in forms.
  942. *
  943. * If you set $echo to true and set $referer to true, then you will need to
  944. * retrieve the {@link wp_referer_field() wp referer field}. If you have the
  945. * $referer set to true and are echoing the nonce field, it will also echo the
  946. * referer field.
  947. *
  948. * The $action and $name are optional, but if you want to have better security,
  949. * it is strongly suggested to set those two parameters. It is easier to just
  950. * call the function without any parameters, because validation of the nonce
  951. * doesn't require any parameters, but since crackers know what the default is
  952. * it won't be difficult for them to find a way around your nonce and cause
  953. * damage.
  954. *
  955. * The input name will be whatever $name value you gave. The input value will be
  956. * the nonce creation value.
  957. *
  958. * @package bbPress
  959. * @subpackage Security
  960. * @since 1.0
  961. *
  962. * @param string $action Optional. Action name.
  963. * @param string $name Optional. Nonce name.
  964. * @param bool $referer Optional, default true. Whether to set the referer field for validation.
  965. * @param bool $echo Optional, default true. Whether to display or return hidden form field.
  966. * @return string Nonce field.
  967. */
  968. function bb_nonce_field( $action = -1, $name = "_wpnonce", $referer = true , $echo = true ) {
  969. $name = esc_attr( $name );
  970. $nonce = bb_create_nonce( $action );
  971. $nonce_field = '<input type="hidden" id="' . $name . '" name="' . $name . '" value="' . $nonce . '" />';
  972. if ( $echo )
  973. echo $nonce_field;
  974. if ( $referer )
  975. wp_referer_field( $echo, 'previous' );
  976. return $nonce_field;
  977. }
  978. function bb_nonce_ays( $action )
  979. {
  980. $title = __( 'bbPress Failure Notice' );
  981. $html .= "\t<div id='message' class='updated fade'>\n\t<p>" . esc_html( bb_explain_nonce( $action ) ) . "</p>\n\t<p>";
  982. if ( wp_get_referer() )
  983. $html .= "<a href='" . remove_query_arg( 'updated', esc_url( wp_get_referer() ) ) . "'>" . __( 'Please try again.' ) . "</a>";
  984. $html .= "</p>\n\t</div>\n";
  985. $html .= "</body>\n</html>";
  986. bb_die( $html, $title );
  987. }
  988. function bb_install_header( $title = '', $header = false, $logo = false )
  989. {
  990. if ( empty($title) )
  991. if ( function_exists('__') )
  992. $title = __('bbPress');
  993. else
  994. $title = 'bbPress';
  995. $uri = false;
  996. if ( function_exists('bb_get_uri') && !BB_INSTALLING ) {
  997. $uri = bb_get_uri();
  998. $uri_stylesheet = bb_get_uri('bb-admin/install.css', null, BB_URI_CONTEXT_LINK_STYLESHEET_HREF + BB_URI_CONTEXT_BB_INSTALLER);
  999. $uri_stylesheet_rtl = bb_get_uri('bb-admin/install-rtl.css', null, BB_URI_CONTEXT_LINK_STYLESHEET_HREF + BB_URI_CONTEXT_BB_INSTALLER);
  1000. $uri_logo = bb_get_uri('bb-admin/images/bbpress-logo.png', null, BB_URI_CONTEXT_IMG_SRC + BB_URI_CONTEXT_BB_INSTALLER);
  1001. }
  1002. if (!$uri) {
  1003. $uri = preg_replace('|(/bb-admin)?/[^/]+?$|', '/', $_SERVER['PHP_SELF']);
  1004. $uri_stylesheet = $uri . 'bb-admin/install.css';
  1005. $uri_stylesheet_rtl = $uri . 'bb-admin/install-rtl.css';
  1006. $uri_logo = $uri . 'bb-admin/images/bbpress-logo.png';
  1007. }
  1008. header('Content-Type: text/html; charset=utf-8');
  1009. ?>
  1010. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  1011. <html xmlns="http://www.w3.org/1999/xhtml"<?php if ( function_exists( 'bb_language_attributes' ) ) bb_language_attributes(); ?>>
  1012. <head>
  1013. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  1014. <title><?php echo $title; ?></title>
  1015. <meta name="robots" content="noindex, nofollow" />
  1016. <link rel="stylesheet" href="<?php echo $uri_stylesheet; ?>" type="text/css" />
  1017. <?php
  1018. if ( function_exists( 'bb_get_option' ) && 'rtl' == bb_get_option( 'text_direction' ) ) {
  1019. ?>
  1020. <link rel="stylesheet" href="<?php echo $uri_stylesheet_rtl; ?>" type="text/css" />
  1021. <?php
  1022. }
  1023. ?>
  1024. </head>
  1025. <body>
  1026. <div id="container">
  1027. <?php
  1028. if ( $logo ) {
  1029. ?>
  1030. <div class="logo">
  1031. <img src="<?php echo $uri_logo; ?>" alt="bbPress" />
  1032. </div>
  1033. <?php
  1034. }
  1035. if ( !empty($header) ) {
  1036. ?>
  1037. <h1>
  1038. <?php echo $header; ?>
  1039. </h1>
  1040. <?php
  1041. }
  1042. }
  1043. function bb_install_footer() {
  1044. ?>
  1045. </div>
  1046. </body>
  1047. </html>
  1048. <?php
  1049. }
  1050. function bb_die( $message, $title = '', $header = 0 ) {
  1051. global $bb_locale;
  1052. if ( $header && !headers_sent() )
  1053. status_header( $header );
  1054. if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) {
  1055. if ( empty( $title ) ) {
  1056. $error_data = $message->get_error_data();
  1057. if ( is_array( $error_data ) && isset( $error_data['title'] ) )
  1058. $title = $error_data['title'];
  1059. }
  1060. $errors = $message->get_error_messages();
  1061. switch ( count( $errors ) ) :
  1062. case 0 :
  1063. $message = '';
  1064. break;
  1065. case 1 :
  1066. $message = "<p>{$errors[0]}</p>";
  1067. break;
  1068. default :
  1069. $message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $errors ) . "</li>\n\t</ul>";
  1070. break;
  1071. endswitch;
  1072. } elseif ( is_string( $message ) ) {
  1073. $message = bb_autop( $message );
  1074. }
  1075. if ( empty($title) )
  1076. $title = __('bbPress &rsaquo; Error');
  1077. bb_install_header( $title );
  1078. ?>
  1079. <?php echo $message; ?>
  1080. <?php
  1081. if ($uri = bb_get_uri()) {
  1082. ?>
  1083. <p class="last"><?php printf( __('Back to <a href="%s">%s</a>.'), $uri, bb_get_option( 'name' ) ); ?></p>
  1084. <?php
  1085. }
  1086. bb_install_footer();
  1087. die();
  1088. }
  1089. function bb_explain_nonce($action) {
  1090. if ( $action !== -1 && preg_match('/([a-z]+)-([a-z]+)(_(.+))?/', $action, $matches) ) {
  1091. $verb = $matches[1];
  1092. $noun = $matches[2];
  1093. $trans = array();
  1094. $trans['create']['post'] = array(__('Your attempt to submit this post has failed.'), false);
  1095. $trans['edit']['post'] = array(__('Your attempt to edit this post has failed.'), false);
  1096. $trans['delete']['post'] = array(__('Your attempt to delete this post has failed.'), false);
  1097. $trans['create']['topic'] = array(__('Your attempt to create this topic has failed.'), false);
  1098. $trans['resolve']['topic'] = array(__('Your attempt to change the resolution status of this topic has failed.'), false);
  1099. $trans['delete']['topic'] = array(__('Your attempt to delete this topic has failed.'), false);
  1100. $trans['close']['topic'] = array(__('Your attempt to change the status of this topic has failed.'), false);
  1101. $trans['stick']['topic'] = array(__('Your attempt to change the sticky status of this topic has failed.'), false);
  1102. $trans['move']['topic'] = array(__('Your attempt to move this topic has failed.'), false);
  1103. $trans['add']['tag'] = array(__('Your attempt to add this tag to this topic has failed.'), false);
  1104. $trans['rename']['tag'] = array(__('Your attempt to rename this tag has failed.'), false);
  1105. $trans['merge']['tag'] = array(__('Your attempt to submit these tags has failed.'), false);
  1106. $trans['destroy']['tag'] = array(__('Your attempt to destroy this tag has failed.'), false);
  1107. $trans['remove']['tag'] = array(__('Your attempt to remove this tag from this topic has failed.'), false);
  1108. $trans['toggle']['favorite'] = array(__('Your attempt to toggle your favorite status for this topic has failed.'), false);
  1109. $trans['edit']['profile'] = array(__("Your attempt to edit this user's profile has failed."), false);
  1110. $trans['add']['forum'] = array(__("Your attempt to add this forum has failed."), false);
  1111. $trans['update']['forums'] = array(__("Your attempt to update your forums has failed."), false);
  1112. $trans['delete']['forums'] = array(__("Your attempt to delete that forum has failed."), false);
  1113. $trans['do']['counts'] = array(__("Your attempt to recount these items has failed."), false);
  1114. $trans['switch']['theme'] = array(__("Your attempt to switch themes has failed."), false);
  1115. if ( isset($trans[$verb][$noun]) ) {
  1116. if ( !empty($trans[$verb][$noun][1]) ) {
  1117. $lookup = $trans[$verb][$noun][1];
  1118. $object = $matches[4];
  1119. if ( 'use_id' != $lookup )
  1120. $object = call_user_func($lookup, $object);
  1121. return sprintf($trans[$verb][$noun][0], esc_html( $object ));
  1122. } else {
  1123. return $trans[$verb][$noun][0];
  1124. }
  1125. }
  1126. }
  1127. return apply_filters( 'bb_explain_nonce_' . $verb . '-' . $noun, __('Your attempt to do this has failed.'), $matches[4] );
  1128. }
  1129. /* DB Helpers */
  1130. function bb_count_last_query( $query = '' ) {
  1131. global $bbdb, $bb_last_countable_query;
  1132. if ( $query )
  1133. $q = $query;
  1134. elseif ( $bb_last_countable_query )
  1135. $q = $bb_last_countable_query;
  1136. else
  1137. $q = $bbdb->last_query;
  1138. if ( false === strpos($q, 'SELECT') )
  1139. return false;
  1140. if ( false !== strpos($q, 'SQL_CALC_FOUND_ROWS') )
  1141. return (int) $bbdb->get_var( "SELECT FOUND_ROWS()" );
  1142. $q_original = $q;
  1143. $q = preg_replace(
  1144. array('/SELECT.*?\s+FROM/', '/LIMIT [0-9]+(\s*,\s*[0-9]+)?/', '/ORDER BY\s+.*$/', '/DESC/', '/ASC/'),
  1145. array('SELECT COUNT(*) FROM', ''),
  1146. $q
  1147. );
  1148. if ( preg_match( '/GROUP BY\s+(\S+)/', $q, $matches ) )
  1149. $q = str_replace( array( 'COUNT(*)', $matches[0] ), array( "COUNT(DISTINCT $matches[1])", '' ), $q );
  1150. if ( !$query )
  1151. $bb_last_countable_query = '';
  1152. $q = apply_filters( 'bb_count_last_query', $q, $q_original );
  1153. return (int) $bbdb->get_var($q);
  1154. }
  1155. function bb_no_where( $where ) {
  1156. return;
  1157. }
  1158. /* Plugins/Themes utility */
  1159. function bb_basename( $file, $directories )
  1160. {
  1161. if ( strpos( $file, '#' ) !== false ) {
  1162. return $file; // It's already a basename
  1163. }
  1164. foreach ( $directories as $type => $directory ) {
  1165. if ( strpos( $file, $directory ) !== false ) {
  1166. break; // Keep the $file and $directory set and use them below, nifty huh?
  1167. }
  1168. }
  1169. list( $file, $directory ) = str_replace( '\\','/', array( $file, $directory ) );
  1170. list( $file, $directory ) = preg_replace( '|/+|','/', array( $file,$directory ) );
  1171. $file = preg_replace( '|^.*' . preg_quote( $directory, '|' ) . '|', $type . '#', $file );
  1172. return $file;
  1173. }
  1174. /* Plugins */
  1175. function bb_plugin_basename( $file )
  1176. {
  1177. global $bb;
  1178. $directories = array();
  1179. foreach ( $bb->plugin_locations as $_name => $_data ) {
  1180. $directories[$_name] = $_data['dir'];
  1181. }
  1182. return bb_basename( $file, $directories );
  1183. }
  1184. function bb_register_plugin_activation_hook( $file, $function )
  1185. {
  1186. $file = bb_plugin_basename( $file );
  1187. add_action( 'bb_activate_plugin_' . $file, $function );
  1188. }
  1189. function bb_register_plugin_deactivation_hook( $file, $function )
  1190. {
  1191. $file = bb_plugin_basename( $file );
  1192. add_action( 'bb_deactivate_plugin_' . $file, $function );
  1193. }
  1194. function bb_get_plugin_uri( $plugin = false )
  1195. {
  1196. global $bb;
  1197. if ( preg_match( '/^([a-z0-9_-]+)#((?:[a-z0-9\/\\_-]+.)+)(php)$/i', $plugin, $_matches ) ) {
  1198. $plugin_uri = $bb->plugin_locations[$_matches[1]]['url'] . $_matches[2] . $_matches[3];
  1199. $plugin_uri = dirname( $plugin_uri ) . '/';
  1200. } else {
  1201. $plugin_uri = $bb->plugin_locations['core']['url'];
  1202. }
  1203. return apply_filters( 'bb_get_plugin_uri', $plugin_uri, $plugin );
  1204. }
  1205. function bb_get_plugin_directory( $plugin = false, $path = false )
  1206. {
  1207. global $bb;
  1208. if ( preg_match( '/^([a-z0-9_-]+)#((?:[a-z0-9\/\\_-]+.)+)(php)$/i', $plugin, $_matches ) ) {
  1209. $plugin_directory = $bb->plugin_locations[$_matches[1]]['dir'] . $_matches[2] . $_matches[3];
  1210. if ( !$path ) {
  1211. $plugin_directory = dirname( $plugin_directory ) . '/';
  1212. }
  1213. } else {
  1214. $plugin_directory = $bb->plugin_locations['core']['dir'];
  1215. }
  1216. return apply_filters( 'bb_get_plugin_directory', $plugin_directory, $plugin, $path );
  1217. }
  1218. function bb_get_plugin_path( $plugin = false )
  1219. {
  1220. $plugin_path = bb_get_plugin_directory( $plugin, true );
  1221. return apply_filters( 'bb_get_plugin_path', $plugin_path, $plugin );
  1222. }
  1223. /* Themes / Templates */
  1224. function bb_get_active_theme_directory()
  1225. {
  1226. return apply_filters( 'bb_get_active_theme_directory', bb_get_theme_directory() );
  1227. }
  1228. function bb_get_theme_directory( $theme = false )
  1229. {
  1230. global $bb;
  1231. if ( !$theme ) {
  1232. $theme = bb_get_option( 'bb_active_theme' );
  1233. }
  1234. if ( preg_match( '/^([a-z0-9_-]+)#([\.a-z0-9_-]+)$/i', $theme, $_matches ) ) {
  1235. $theme_directory = $bb->theme_locations[$_matches[1]]['dir'] . $_matches[2] . '/';
  1236. } else {
  1237. $theme_directory = BB_DEFAULT_THEME_DIR;
  1238. }
  1239. return $theme_directory;
  1240. }
  1241. function bb_get_themes()
  1242. {
  1243. $r = array();
  1244. global $bb;
  1245. foreach ( $bb->theme_locations as $_name => $_data ) {
  1246. if ( $themes_dir = @dir( $_data['dir'] ) ) {
  1247. while( ( $theme_dir = $themes_dir->read() ) !== false ) {
  1248. if ( is_file( $_data['dir'] . $theme_dir . '/style.css' ) && is_readable( $_data['dir'] . $theme_dir . '/style.css' ) && '.' != $theme_dir{0} ) {
  1249. $r[$_name . '#' . $theme_dir] = $_name . '#' . $theme_dir;
  1250. }
  1251. }
  1252. }
  1253. }
  1254. ksort( $r );
  1255. return $r;
  1256. }
  1257. function bb_theme_basename( $file )
  1258. {
  1259. global $bb;
  1260. $directories = array();
  1261. foreach ( $bb->theme_locations as $_name => $_data ) {
  1262. $directories[$_name] = $_data['dir'];
  1263. }
  1264. $file = bb_basename( $file, $directories );
  1265. $file = preg_replace( '|/+.*|', '', $file );
  1266. return $file;
  1267. }
  1268. function bb_register_theme_activation_hook( $file, $function )
  1269. {
  1270. $file = bb_theme_basename( $file );
  1271. add_action( 'bb_activate_theme_' . $file, $function );
  1272. }
  1273. function bb_register_theme_deactivation_hook( $file, $function )
  1274. {
  1275. $file = bb_theme_basename( $file );
  1276. add_action( 'bb_deactivate_theme_' . $file, $function );
  1277. }
  1278. /* Search Functions */
  1279. // NOT bbdb::prepared
  1280. function bb_user_search( $args = '' ) {
  1281. global $bbdb, $bb_last_countable_query;
  1282. if ( $args && is_string( $args ) && false === strpos( $args, '=' ) ) {
  1283. $args = array( 'query' => $args );
  1284. }
  1285. $defaults = array(
  1286. 'query' => '',
  1287. 'append_meta' => true,
  1288. 'user_login' => true,
  1289. 'display_name' => true,
  1290. 'user_nicename' => false,
  1291. 'user_url' => true,
  1292. 'user_email' => false,
  1293. 'user_meta' => false,
  1294. 'users_per_page' => false,
  1295. 'page' => false,
  1296. 'roles' => false
  1297. );
  1298. $args = wp_parse_args( $args, $defaults );
  1299. extract( $args, EXTR_SKIP );
  1300. $query = trim( $query );
  1301. if ( $query && strlen( preg_replace( '/[^a-z0-9]/i', '', $query ) ) < 3 ) {
  1302. return new WP_Error( 'invalid-query', __('Your search term was too short') );
  1303. }
  1304. $query = $bbdb->escape( $query );
  1305. if ( !$page ) {
  1306. $page = $GLOBALS['page'];
  1307. }
  1308. $page = (int) $page;
  1309. $limit = 0 < (int) $users_per_page ? (int) $users_per_page : bb_get_option( 'page_topics' );
  1310. if ( 1 < $page ) {
  1311. $limit = ($limit * ($page - 1)) . ", $limit";
  1312. }
  1313. $likeit = preg_replace( '/\s+/', '%', like_escape( $query ) );
  1314. $fields = array();
  1315. foreach ( array( 'user_login', 'display_name', 'user_nicename', 'user_url', 'user_email' ) as $field ) {
  1316. if ( $$field ) {
  1317. $fields[] = $field;
  1318. }
  1319. }
  1320. if ( $roles ) {
  1321. $roles = (array) $roles;
  1322. }
  1323. if ( $roles && !empty( $roles ) && false === $role_user_ids = apply_filters( 'bb_user_search_role_user_ids', false, $roles, $args ) ) {
  1324. $role_meta_key = $bbdb->escape( $bbdb->prefix . 'capabilities' );
  1325. $role_sql_terms = array();
  1326. foreach ( $roles as $role ) {
  1327. $role_sql_terms[] = "`meta_value` LIKE '%" . $bbdb->escape( like_escape( $role ) ) . "%'";
  1328. }
  1329. $role_sql_terms = join( ' OR ', $role_sql_terms );
  1330. $role_sql = "SELECT `user_id` FROM `$bbdb->usermeta` WHERE `meta_key` = '$role_meta_key' AND ($role_sql_terms);";
  1331. $role_user_ids = $bbdb->get_col( $role_sql, 0 );
  1332. if ( is_wp_error( $role_user_ids ) ) {
  1333. return false;
  1334. }
  1335. }
  1336. if ( is_array( $role_user_ids ) && empty( $role_user_ids ) ) {
  1337. return false;
  1338. }
  1339. if ( $query && $user_meta && false === $meta_user_ids = apply_filters( 'bb_user_search_meta_user_ids', false, $args ) ) {
  1340. $meta_sql = "SELECT `user_id` FROM `$bbdb->usermeta` WHERE `meta_value` LIKE ('%$likeit%')";
  1341. if ( empty( $fields ) ) {
  1342. $meta_sql .= " LIMIT $limit";
  1343. }
  1344. $meta_user_ids = $bbdb->get_col( $meta_sql, 0 );
  1345. if ( is_wp_error( $meta_user_ids ) ) {
  1346. $meta_user_ids = false;
  1347. }
  1348. }
  1349. $user_ids = array();
  1350. if ( $role_user_ids && $meta_user_ids ) {
  1351. $user_ids = array_intersect( (array) $role_user_ids, (array) $meta_user_ids );
  1352. } elseif ( $role_user_ids ) {
  1353. $user_ids = (array) $role_user_ids;
  1354. } elseif ( $meta_user_ids ) {
  1355. $user_ids = (array) $meta_user_ids;
  1356. }
  1357. $sql = "SELECT * FROM $bbdb->users";
  1358. $sql_terms = array();
  1359. if ( $query && count( $fields ) ) {
  1360. foreach ( $fields as $field ) {
  1361. $sql_terms[] = "$field LIKE ('%$likeit%')";
  1362. }
  1363. }
  1364. $user_ids_sql = '';
  1365. if ( $user_ids ) {
  1366. $user_ids_sql = "AND ID IN (". join(',', $user_ids) . ")";
  1367. }
  1368. if ( $query && empty( $sql_terms ) ) {
  1369. return new WP_Error( 'invalid-query', __( 'Your query parameters are invalid' ) );
  1370. }
  1371. if ( count( $sql_terms ) || count( $user_ids ) ) {
  1372. $sql .= ' WHERE ';
  1373. }
  1374. if ( count( $sql_terms ) ) {
  1375. $sql .= '(' . implode( ' OR ', $sql_terms ) . ')';
  1376. }
  1377. if ( count( $sql_terms ) && count( $user_ids ) ) {
  1378. $sql .= ' AND ';
  1379. }
  1380. if ( count( $user_ids ) ) {
  1381. $sql .= '`ID` IN (' . join( ',', $user_ids ) . ')';
  1382. }
  1383. $sql .= " ORDER BY user_login LIMIT $limit";
  1384. $bb_last_countable_query = $sql;
  1385. do_action( 'bb_user_search', $sql, $args );
  1386. if ( ( $users = $bbdb->get_results( $sql ) ) && $append_meta ) {

Large files files are truncated, but you can click here to view the full file