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

  1. <?php 
  2.  
  3. function bb_autop($pee, $br = 1) { // Reduced to be faster 
  4. $pee = $pee . "\n"; // just to make things a little easier, pad the end 
  5. $pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee); 
  6. // Space things out a little 
  7. $pee = preg_replace('!(<(?:ul|ol|li|blockquote|pre|p)[^>]*>)!', "\n$1", $pee);  
  8. $pee = preg_replace('!(</(?:ul|ol|li|blockquote|pre|p)>)!', "$1\n", $pee); 
  9. $pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines  
  10. $pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates 
  11. $pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n", $pee); // make paragraphs, including one at the end  
  12. $pee = preg_replace('|<p>\s*?</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace  
  13. $pee = preg_replace('!<p>\s*(</?(?:ul|ol|li|blockquote|p)[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag 
  14. $pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists 
  15. $pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee); 
  16. $pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee); 
  17. $pee = preg_replace('!<p>\s*(</?(?:ul|ol|li|blockquote|p)[^>]*>)!', "$1", $pee); 
  18. $pee = preg_replace('!(</?(?:ul|ol|li|blockquote|p)[^>]*>)\s*</p>!', "$1", $pee);  
  19. if ($br) $pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks 
  20. $pee = preg_replace('!(</?(?:ul|ol|li|blockquote|p)[^>]*>)\s*<br />!', "$1", $pee); 
  21. $pee = preg_replace('!<br />(\s*</?(?:p|li|ul|ol)>)!', '$1', $pee); 
  22. if ( false !== strpos( $pee, '<pre' ) ) 
  23. $pee = preg_replace_callback('!(<pre.*?>)(.*?)</pre>!is', 'clean_pre', $pee ); 
  24. return $pee;  
  25.  
  26. function bb_encodeit( $matches ) { 
  27. $text = trim($matches[2]); 
  28. $text = htmlspecialchars($text, ENT_QUOTES); 
  29. $text = str_replace(array("\r\n", "\r"), "\n", $text); 
  30. $text = preg_replace("|\n\n\n+|", "\n\n", $text); 
  31. $text = str_replace('&amp;', '&', $text); 
  32. $text = str_replace('&lt;', '<', $text); 
  33. $text = str_replace('&gt;', '>', $text); 
  34. $text = "<code>$text</code>"; 
  35. if ( "`" != $matches[1] ) 
  36. $text = "<pre>$text</pre>"; 
  37. return $text; 
  38.  
  39. function bb_decodeit( $matches ) { 
  40. $text = $matches[2]; 
  41. $trans_table = array_flip(get_html_translation_table(HTML_ENTITIES)); 
  42. $text = strtr($text, $trans_table); 
  43. $text = str_replace('<br />', '<coded_br />', $text); 
  44. $text = str_replace('<p>', '<coded_p>', $text); 
  45. $text = str_replace('</p>', '</coded_p>', $text); 
  46. $text = str_replace(array('&', '&'), '&', $text); 
  47. $text = str_replace(''', "'", $text); 
  48. if ( '<pre><code>' == $matches[1] ) 
  49. $text = "\n$text\n"; 
  50. return "`$text`"; 
  51.  
  52. function bb_code_trick( $text ) { 
  53. $text = str_replace(array("\r\n", "\r"), "\n", $text); 
  54. $text = preg_replace_callback("|(`)(.*?)`|", 'bb_encodeit', $text); 
  55. $text = preg_replace_callback("!(^|\n)`(.*?)`!s", 'bb_encodeit', $text); 
  56. return $text; 
  57.  
  58. function bb_code_trick_reverse( $text ) { 
  59. $text = preg_replace_callback("!(<pre><code>|<code>)(.*?)(</code></pre>|</code>)!s", 'bb_decodeit', $text); 
  60. $text = str_replace(array('<p>', '<br />'), '', $text); 
  61. $text = str_replace('</p>', "\n", $text); 
  62. $text = str_replace('<coded_br />', '<br />', $text); 
  63. $text = str_replace('<coded_p>', '<p>', $text); 
  64. $text = str_replace('</coded_p>', '</p>', $text); 
  65. return $text; 
  66.  
  67. function _bb_encode_bad_empty(&$text, $key, $preg) { 
  68. if (strpos($text, '`') !== 0) 
  69. $text = preg_replace("|<($preg)\s*?/*?>|i", '<$1 />', $text); 
  70. } 
  71.   
  72. function _bb_encode_bad_normal(&$text, $key, $preg) { 
  73. if (strpos($text, '`') !== 0) 
  74. $text = preg_replace("|<(/?$preg)>|i", '<$1>', $text); 
  75. } 
  76.   
  77. function bb_encode_bad( $text ) { 
  78. $text = wp_specialchars( $text, ENT_NOQUOTES ); 
  79.   
  80. $text = preg_split('@(`[^`]*`)@m', $text, -1, PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE); 
  81.   
  82. $allowed = bb_allowed_tags(); 
  83. $empty = array( 'br' => true, 'hr' => true, 'img' => true, 'input' => true, 'param' => true, 'area' => true, 'col' => true, 'embed' => true ); 
  84.   
  85. foreach ( $allowed as $tag => $args ) { 
  86. $preg = $args ? "$tag(?:\s.*?)?" : $tag; 
  87.   
  88. if ( isset( $empty[$tag] ) ) 
  89. array_walk($text, '_bb_encode_bad_empty', $preg); 
  90. else 
  91. array_walk($text, '_bb_encode_bad_normal', $preg); 
  92. } 
  93.   
  94. return join('', $text); 
  95. } 
  96.   
  97. function bb_filter_kses($data) { 
  98. $allowedtags = bb_allowed_tags(); 
  99. return wp_kses($data, $allowedtags); 
  100. } 
  101.   
  102. function bb_allowed_tags() { 
  103. $tags = array( 
  104. 'a' => array( 
  105. 'href' => array(),  
  106. 'title' => array(),  
  107. 'rel' => array()),  
  108. 'blockquote' => array('cite' => array()),  
  109. 'br' => array(),  
  110. 'code' => array(),  
  111. 'pre' => array(),  
  112. 'em' => array(),  
  113. 'strong' => array(),  
  114. 'ul' => array(),  
  115. 'ol' => array(),  
  116. 'li' => array() 
  117. ); 
  118. return apply_filters( 'bb_allowed_tags', $tags ); 
  119. } 
  120.   
  121. function bb_rel_nofollow( $text ) { 
  122. return preg_replace_callback('|<a (.+?)>|i', 'bb_rel_nofollow_callback', $text); 
  123. } 
  124.   
  125. function bb_rel_nofollow_callback( $matches ) { 
  126. $text = $matches[1]; 
  127. $text = str_replace(array(' rel="nofollow"', " rel='nofollow'"), '', $text); 
  128. return "<a $text rel=\"nofollow\">"; 
  129. } 
  130.   
  131. // Should be able to take both escaped and unescaped data 
  132. function bb_trim_for_db( $string, $length ) { 
  133. $_string = $string; 
  134. if ( seems_utf8( $string ) ) { 
  135. $string = bb_utf8_cut( $string, $length ); 
  136. // if we have slashes at the end, make sure we have a reasonable number of them 
  137. if ( preg_match( '#[^\\\\](\\\\+)$#', $string, $matches ) ) { 
  138. $end = stripslashes($matches[1]); 
  139. $end = addslashes($end); 
  140. $string = trim( $string, '\\' ) . $end; 
  141. } 
  142. } 
  143. return apply_filters( 'bb_trim_for_db', $string, $_string, $length ); 
  144. } 
  145.   
  146. // Reduce utf8 string to $length in single byte character equivalents without breaking multibyte characters 
  147. function bb_utf8_cut( $utf8_string, $length = 0 ) { 
  148. if ( $length < 1 ) 
  149. return $utf8_string; 
  150.   
  151. $unicode = ''; 
  152. $chars = array(); 
  153. $num_octets = 1; 
  154.   
  155. for ($i = 0; $i < strlen( $utf8_string ); $i++ ) { 
  156.   
  157. $value = ord( $utf8_string[ $i ] ); 
  158.   
  159. if ( 128 > $value ) { 
  160. if ( strlen($unicode) + 1 > $length ) 
  161. break;  
  162. $unicode .= $utf8_string[ $i ]; 
  163. } else { 
  164. if ( count( $chars ) == 0 ) 
  165. $num_octets = ( 224 > $value ) ? 2 : 3; 
  166.   
  167. $chars[] = $utf8_string[ $i ]; 
  168. if ( strlen($unicode) + $num_octets > $length ) 
  169. break; 
  170. if ( count( $chars ) == $num_octets ) { 
  171. $unicode .= join('', $chars); 
  172. $chars = array(); 
  173. $num_octets = 1; 
  174. } 
  175. } 
  176. } 
  177.   
  178. return $unicode; 
  179. } 
  180.   
  181. function bb_encoded_utf8_cut( $encoded, $length = 0 ) { 
  182. if ( $length < 1 ) 
  183. return $encoded; 
  184.   
  185. $r = ''; 
  186. $values = preg_split( '/(%[0-9a-f]{2})/i', $encoded, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );; 
  187.   
  188. for ($i = 0; $i < count( $values ); $i += $num_octets ) { 
  189. $num_octets = 1; 
  190. if ( '%' != $values[$i][0] ) { 
  191. $r .= $values[$i]; 
  192. if ( $length && strlen($r) > $length ) 
  193. return substr($r, 0, $length); 
  194. } else { 
  195. $value = hexdec(substr($values[$i], 1)); 
  196.   
  197. if ( 1 == $num_octets ) 
  198. $num_octets = ( 224 > $value ) ? 2 : 3; 
  199.   
  200. if ( $length && ( strlen($r) + $num_octets * 3 ) > $length ) 
  201. return $r; 
  202.   
  203. $r .= $values[$i] . $values[$i + 1]; 
  204. if ( 3 == $num_octets ) 
  205. $r .= $values[$i + 2]; 
  206. } 
  207. } 
  208.   
  209. return $r; 
  210. } 
  211.   
  212. function bb_pre_term_slug( $slug, $taxonomy = '', $term_id = 0 ) { 
  213. return bb_sanitize_with_dashes( $slug, 200 ); 
  214. } 
  215.   
  216. function bb_trim_for_db_55( $string ) { 
  217. return bb_trim_for_db( $string, 55 ); 
  218. } 
  219.   
  220. function bb_trim_for_db_150( $string ) { 
  221. return bb_trim_for_db( $string, 150 ); 
  222. } 
  223.   
  224. function bb_slug_sanitize( $slug, $length = 255 ) { 
  225. $_slug = $slug; 
  226. return apply_filters( 'bb_slug_sanitize', bb_sanitize_with_dashes( $slug, $length ), $_slug, $length ); 
  227. } 
  228.   
  229. function bb_user_nicename_sanitize( $user_nicename, $length = 50 ) { 
  230. $_user_nicename = $user_nicename; 
  231. return apply_filters( 'bb_user_nicename_sanitize', bb_sanitize_with_dashes( $user_nicename, $length ), $_user_nicename, $length ); 
  232. } 
  233.   
  234. function bb_sanitize_with_dashes( $text, $length = 0 ) { // Multibyte aware 
  235. $_text = $text; 
  236. $text = trim($text); 
  237. $text = strip_tags($text); 
  238. // Preserve escaped octets. 
  239. $text = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $text); 
  240. // Remove percent signs that are not part of an octet. 
  241. $text = str_replace('%', '', $text); 
  242. // Restore octets. 
  243. $text = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $text); 
  244.   
  245. $text = apply_filters( 'pre_sanitize_with_dashes', $text, $_text, $length ); 
  246.   
  247. $text = strtolower($text); 
  248. $text = preg_replace('/&(^\x80-\xff)+?;/', '', $text); // kill entities 
  249. $text = preg_replace('/[^%a-z0-9\x80-\xff _-]/', '', $text); 
  250. $text = trim($text); 
  251. $text = preg_replace('/\s+/', '-', $text); 
  252. $text = preg_replace(array('|-+|', '|_+|'), array('-', '_'), $text); // Kill the repeats 
  253.  
  254. return $text; 
  255. } 
  256.   
  257. function bb_pre_sanitize_with_dashes_utf8( $text, $_text = '', $length = 0 ) { 
  258. $text = remove_accents($text); 
  259.   
  260. if ( seems_utf8( $text ) ) { 
  261. if ( function_exists('mb_strtolower') ) 
  262. $text = mb_strtolower($text, 'UTF-8'); 
  263. $text = utf8_uri_encode( $text, $length ); 
  264. } 
  265.   
  266. return $text; 
  267. } 
  268.   
  269. function bb_show_topic_context( $term, $text ) { 
  270. $text = strip_tags( $text ); 
  271. $term = preg_quote( $term ); 
  272. $text = preg_replace( "|.*?(.{0, 80})$term(.{0, 80}).*|is", "$1<strong>$term</strong>$2", $text, 1 ); 
  273. $text = substr( $text, 0, 210 ); 
  274. return $text; 
  275. } 
  276.   
  277. function bb_post_text_context( $post_text ) { 
  278. return bb_show_context( $GLOBALS['q'], $post_text ); 
  279. } 
  280.   
  281. function bb_show_context( $term, $text ) { 
  282. $text = strip_shortcodes( $text ); 
  283. $text = strip_tags( $text ); 
  284. $term = preg_quote( $term ); 
  285. $text = preg_replace( "|.*?(.{0, 80})$term(.{0, 80}).*|is", "... $1<strong>$term</strong>$2 ...", $text, 1 ); 
  286. $text = substr( $text, 0, 210 ); 
  287. return $text; 
  288. } 
  289.   
  290. function bb_fix_link( $link ) { 
  291. if ( false === strpos($link, '.') ) // these are usually random words 
  292. return ''; 
  293. $link = wp_kses_no_null( $link ); 
  294. return esc_url( $link ); 
  295. } 
  296.   
  297. function bb_sticky_label( $label ) { 
  298. global $topic; 
  299. if (bb_is_front()) { 
  300. if ( '2' === $topic->topic_sticky ) { 
  301. return sprintf(__('[sticky] %s'), $label); 
  302. } 
  303. } else { 
  304. if ( '1' === $topic->topic_sticky || '2' === $topic->topic_sticky ) { 
  305. return sprintf(__('[sticky] %s'), $label); 
  306. } 
  307. } 
  308. return $label; 
  309. } 
  310.   
  311. function bb_closed_label( $label ) { 
  312. global $topic; 
  313. if ( '0' === $topic->topic_open ) 
  314. return sprintf(__('[closed] %s'), $label); 
  315. return $label; 
  316. } 
  317.   
  318. function bb_make_link_view_all( $link ) { 
  319. return esc_html( add_query_arg( 'view', 'all', $link ) ); 
  320. } 
  321.   
  322. function bb_gmtstrtotime( $string ) { 
  323. if ( is_numeric($string) ) 
  324. return $string; 
  325. if ( !is_string($string) ) 
  326. return -1; 
  327.   
  328. if ( stristr($string, 'utc') || stristr($string, 'gmt') || stristr($string, '+0000') ) 
  329. return strtotime($string); 
  330.   
  331. if ( -1 == $time = strtotime($string . ' +0000') ) 
  332. return strtotime($string); 
  333.   
  334. return $time; 
  335. } 
  336.   
  337. /** 
  338. * Converts a number of characters from a string. 
  339. * 
  340. * Metadata tags <<title>> and <<category>> are removed, <<br>> and <<hr>> are 
  341. * converted into correct XHTML and Unicode characters are converted to the 
  342. * valid range. 
  343. * 
  344. * @param string $content String of characters to be converted. 
  345. *  
  346. * @return string Converted string. 
  347. */ 
  348. function bb_convert_chars( $content ) { 
  349. // Translation of invalid Unicode references range to valid range 
  350. $wp_htmltranswinuni = array( 
  351. '€' => '€', // the Euro sign 
  352. '' => '',  
  353. '‚' => '‚', // these are Windows CP1252 specific characters 
  354. 'ƒ' => 'ƒ', // they would look weird on non-Windows browsers 
  355. '„' => '„',  
  356. '…' => '…',  
  357. '†' => '†',  
  358. '‡' => '‡',  
  359. 'ˆ' => 'ˆ',  
  360. '‰' => '‰',  
  361. 'Š' => 'Š',  
  362. '‹' => '‹',  
  363. 'Œ' => 'Œ',  
  364. '' => '',  
  365. 'Ž' => 'ž',  
  366. '' => '',  
  367. '' => '',  
  368. '‘' => '‘',  
  369. '’' => '’',  
  370. '“' => '“',  
  371. '”' => '”',  
  372. '•' => '•',  
  373. '–' => '–',  
  374. '—' => '—',  
  375. '˜' => '˜',  
  376. '™' => '™',  
  377. 'š' => 'š',  
  378. '›' => '›',  
  379. 'œ' => 'œ',  
  380. '' => '',  
  381. 'ž' => '',  
  382. 'Ÿ' => 'Ÿ' 
  383. ); 
  384.  
  385. // Remove metadata tags 
  386. $content = preg_replace( '/<title>(.+?)<\/title>/', '', $content ); 
  387. $content = preg_replace( '/<category>(.+?)<\/category>/', '', $content ); 
  388.  
  389. // Converts lone & characters into & (a.k.a. &) 
  390. $content = preg_replace( '/&([^#])(?![a-z1-4]{1, 8};)/i', '&$1', $content ); 
  391.  
  392. // Fix Word pasting 
  393. $content = strtr( $content, $wp_htmltranswinuni ); 
  394.  
  395. // Just a little XHTML help 
  396. $content = str_replace( '<br>', '<br />', $content ); 
  397. $content = str_replace( '<hr>', '<hr />', $content ); 
  398.  
  399. return $content; 
.