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

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