PageRenderTime 55ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/simple-forum/library/sf-filters.php

https://bitbucket.org/crypticrod/sr_wp_code
PHP | 1897 lines | 1054 code | 271 blank | 572 comment | 197 complexity | df17d6713524cc0e4524f06efd1b980d MD5 | raw file
Possible License(s): AGPL-1.0, GPL-2.0, LGPL-2.1, GPL-3.0, LGPL-2.0, AGPL-3.0

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

  1. <?php
  2. /*
  3. Simple:Press
  4. Filters
  5. $LastChangedDate: 2011-06-02 05:56:53 -0700 (Thu, 02 Jun 2011) $
  6. $Rev: 6226 $
  7. */
  8. if(preg_match('#' . basename(__FILE__) . '#', $_SERVER['PHP_SELF'])) {
  9. die('Access Denied');
  10. }
  11. # ===FILTERS - USEAGE ==============================================
  12. #
  13. # sf_filter_content_save($content, $action)
  14. # sf_filter_content_display($content)
  15. # sf_filter_content_edit($content)
  16. # Used for main post/message content so includes html, images,
  17. # profanity etc.
  18. #
  19. # sf_filter_text_save($content)
  20. # sf_filter_text_display($content)
  21. # sf_filter_text_edit($content)
  22. # Used for larger areas of text where html is allowed like
  23. # admin defined message areas etc.
  24. #
  25. # sf_filter_title_save($content)
  26. # sf_filter_title_display($content)
  27. # Used for title text where no html allowed such as forum
  28. # titles, custom labels and links etc.
  29. #
  30. # sf_filter_name_save($content)
  31. # sf_filter_name_display($content)
  32. # Used for user names such as guest name and display name etc.
  33. #
  34. # sf_filter_email_save($email)
  35. # sf_filter_email_display($email)
  36. # Used for email addresses
  37. #
  38. # sf_filter_url_save($url)
  39. # sf_filter_url_display($url)
  40. # Used for URLs
  41. #
  42. # sf_filter_filename_save($filename)
  43. # used for all filenames - i.e., custom icons etc
  44. #
  45. # sf_filter_signature_display($content)
  46. # special for siganture display
  47. #
  48. # sf_filter_tooltip_display($content)
  49. # special for post tooltips
  50. #
  51. # sf_filter_syntax_display($content)
  52. # special for synrax highlighting
  53. #
  54. # sf_filter_rss_display($content)
  55. # Used for post content in rss feed
  56. #
  57. # sf_filter_table_prefix($content)
  58. # removes prefix from tablename in seaches
  59. #
  60. # ==================================================================
  61. # ===START OF SAVE FILTERS==========================================
  62. #
  63. # CONTENT - SAVE FILTERS UMBRELLA
  64. #
  65. # Used: Forum Post (including Quick Reply)
  66. # Private Messages
  67. # Blog Linking Posts and Comments
  68. # ?
  69. # $action will be 'new' or 'edit'
  70. function sf_filter_content_save($content, $action)
  71. {
  72. global $sfglobals, $current_user;
  73. $sffilters = sf_get_option('sffilters');
  74. # 1: Swap smileys for img tags. Do it early before kses
  75. # NOTE Was a display filter - still needs to be a
  76. # display filter for backward compatibility.
  77. $content = sf_filter_display_smileys($content);
  78. # 2: prepare edits if using tinymce
  79. if ($action == 'edit' && $sfglobals['editor']['sfeditor'] == RICHTEXT)
  80. {
  81. $content = addslashes($content);
  82. }
  83. # 3: convert code tags to our own code display tags
  84. $content = sf_filter_save_codetags1($content, $sfglobals['editor']['sfeditor'], $action);
  85. # 4: run it through kses
  86. $content = sf_filter_save_kses($content);
  87. # 5: parse it for the wp oEmbed class
  88. $content = sf_filter_save_oEmbed($content);
  89. # 6: remove nbsp and p/br tags
  90. $content = sf_filter_save_linebreaks($content);
  91. # 7: revist code tags in case post edit save
  92. $content = sf_filter_save_codetags2($content, $sfglobals['editor']['sfeditor'], $action);
  93. # 8: remove 'pre' tags (optional)
  94. if ($sffilters['sffilterpre']) {
  95. $content = sf_filter_save_pre($content);
  96. }
  97. # 9: deal with single quotes (tinymce encodes them)
  98. $content = sf_filter_save_quotes($content);
  99. # 10: balance html tags
  100. $content = sf_filter_save_balancetags($content);
  101. # 11: format links (optional)
  102. if($sffilters['sfurlchars']) {
  103. $content = sf_filter_save_links($content, $sffilters['sfurlchars']);
  104. }
  105. # 12: add nofollow to links (optional)
  106. if ($sffilters['sfnofollow']) {
  107. $content = sf_filter_save_nofollow($content);
  108. }
  109. # 13: add target blank (optional)
  110. if ($sffilters['sftarget']) {
  111. $content = sf_filter_save_target($content);
  112. }
  113. # 14: profanity filter
  114. $content = sf_filter_save_profanity($content);
  115. # 15: escape it All
  116. $content = sf_filter_save_escape($content);
  117. # 16: strip spoiler shortcode if not allowed
  118. if (!$current_user->sfspoilers)
  119. {
  120. $content = sf_filter_save_spoiler($content);
  121. }
  122. # 17: Try and determine images widths if not set
  123. $content = sf_filter_save_images($content);
  124. # 18: apply any users custom filters
  125. $content = apply_filters('sf_save_post_content', $content);
  126. return $content;
  127. }
  128. # ==================================================================
  129. #
  130. # TEXT - SAVE FILTERS UMBRELLA
  131. #
  132. # Used: Profile Description
  133. # Blog Linking Link Text
  134. # Group Message
  135. # Forum Message
  136. # Email Messages
  137. # Signature Text
  138. # Announce Tag Heading/Text
  139. # Sneak Peak Message
  140. # Admin View Message
  141. # Custom Editor Messages
  142. # Registration/Privacy Messages
  143. # Custom Profile Message
  144. # Admins Off-Line Message
  145. # ?
  146. function sf_filter_text_save($content, $links=true)
  147. {
  148. global $sfglobals;
  149. $sffilters = sf_get_option('sffilters');
  150. # Decode the entities first that were applied for display
  151. $content = html_entity_decode($content, ENT_COMPAT, SFCHARSET);
  152. # 1: run it through kses
  153. $content = sf_filter_save_kses($content);
  154. # 2: remove nbsp and p/br tags
  155. $content = sf_filter_save_linebreaks($content);
  156. # 3: deal with single quotes (tinymce encodes them)
  157. $content = sf_filter_save_quotes($content);
  158. # 4: balance html tags
  159. $content = sf_filter_save_balancetags($content);
  160. # are we altering links?
  161. if ($links)
  162. {
  163. # 5: format links (optional)
  164. if($sffilters['sfurlchars']) {
  165. $content = sf_filter_save_links($content, $sffilters['sfurlchars']);
  166. }
  167. # 6: add nofollow to links (optional)
  168. if ($sffilters['sfnofollow']) {
  169. $content = sf_filter_save_nofollow($content);
  170. }
  171. # 7: add target blank (optional)
  172. if ($sffilters['sftarget']) {
  173. $content = sf_filter_save_target($content);
  174. }
  175. }
  176. # 8: escape it All
  177. $content = sf_filter_save_escape($content);
  178. return $content;
  179. }
  180. # ==================================================================
  181. #
  182. # TITLE - SAVE FILTERS UMBRELLA
  183. #
  184. # Used: Group Title/Description
  185. # Forum Title/Description
  186. # Topic Title
  187. # Message Title
  188. # Blog Linking Titles
  189. # Email Subject
  190. # Custom Meta Description/Keywords
  191. # Topic Status Name/List
  192. # Custom Icon Title
  193. # UserGroup Name/Description
  194. # Permission Name/Description
  195. # Profile Form Labels
  196. # ?
  197. function sf_filter_title_save($content)
  198. {
  199. # 1: remove all html
  200. $content = sf_filter_save_nohtml($content);
  201. # 2: encode brackets
  202. $content = sf_filter_save_brackets($content);
  203. # 3: profanity filter
  204. $content = sf_filter_save_profanity($content);
  205. # 4: escape it All
  206. $content = sf_filter_save_escape($content);
  207. return $content;
  208. }
  209. # ==================================================================
  210. #
  211. # USER NAMES - SAVE FILTERS UMBRELLA
  212. #
  213. # Used: Display Name
  214. # Guest Name
  215. # ?
  216. function sf_filter_name_save($content)
  217. {
  218. # 1: Remove any html
  219. $content = sf_filter_save_nohtml($content);
  220. # 2: Encode
  221. $content = sf_filter_save_encode($content);
  222. # 3: escape it
  223. $content = sf_filter_save_escape($content);
  224. return $content;
  225. }
  226. # ==================================================================
  227. #
  228. # EMAIL ADDRESS - SAVE FILTERS UMBRELLA
  229. #
  230. # Used: Guest posts
  231. # User profile
  232. # ?
  233. function sf_filter_email_save($email)
  234. {
  235. # 1: Remove any html
  236. $email = sf_filter_save_nohtml($email);
  237. # 2: Validate and Sanitise Email
  238. $email = sf_filter_save_cleanemail($email);
  239. # 3: escape it
  240. $email = sf_filter_save_escape($email);
  241. return $email;
  242. }
  243. # ==================================================================
  244. #
  245. # URL - SAVE FILTERS UMBRELLA
  246. #
  247. # Used: All URLs
  248. # ?
  249. function sf_filter_url_save($url)
  250. {
  251. # 1: clean up url for database
  252. $url = sf_filter_save_cleanurl($url);
  253. return $url;
  254. }
  255. # ==================================================================
  256. #
  257. # FILENAME - SAVE FILTERS UMBRELLA
  258. #
  259. # Used: Avatar Upload
  260. # Avatar Pool
  261. # Signature Image
  262. # Custom Icons
  263. # Smileys
  264. # Editor Stylesheets
  265. # Registration/Privacy Documents
  266. # ?
  267. function sf_filter_filename_save($filename)
  268. {
  269. # 1: clean up filename
  270. $filename = sf_filter_save_filename($filename);
  271. return $filename;
  272. }
  273. # ===START OF SAVE FILTERS==========================================
  274. # ------------------------------------------------------------------
  275. # sf_filter_save_codetags1()
  276. #
  277. # Try and change code tags to our code divs
  278. # $content: Unfiltered post content
  279. # ------------------------------------------------------------------
  280. function sf_filter_save_codetags1($content, $editor, $action)
  281. {
  282. global $sfglobals;
  283. switch($editor)
  284. {
  285. case RICHTEXT:
  286. # TinyMCE
  287. include_once (SF_PLUGIN_DIR.'/forum/parsers/sf-rtetohtml.php');
  288. $content = sf_RTE2Html(" ".$content);
  289. break;
  290. case BBCODE:
  291. # Send everything through bbCode below as some users use it in all editors
  292. break;
  293. default:
  294. # HTML and Plain Textaera
  295. include_once (SF_PLUGIN_DIR.'/forum/parsers/sf-rawtohtml.php');
  296. $content = sf_Raw2Html(" ".$content);
  297. break;
  298. }
  299. # strip excess slashes if editing for code segments
  300. if ($action == 'edit' && $sfglobals['editor']['sfeditor'] == RICHTEXT)
  301. {
  302. $content = stripslashes($content);
  303. }
  304. # Now perform the bbCode which will preserve above changes
  305. include_once (SF_PLUGIN_DIR.'/forum/parsers/sf-bbtohtml.php');
  306. $content = addslashes(sf_BBCode2Html(" ".stripslashes($content), false));
  307. # Shouldn't need any of these but there just in case...
  308. $content = str_replace('<code>', '<div class="sfcode">', $content);
  309. $content = str_replace('</code>', '</div>', $content);
  310. $content = str_replace('&lt;code&gt;', '<div class="sfcode">', $content);
  311. $content = str_replace('&lt;/code&gt;', '</div>', $content);
  312. return $content;
  313. }
  314. # ------------------------------------------------------------------
  315. # sf_filter_save_codetags2()
  316. #
  317. # May be post edit save - so remove br's
  318. # $content: Unfiltered post content
  319. # $editor: Which editor
  320. # $action: 'new' or 'edit'
  321. # ------------------------------------------------------------------
  322. function sf_filter_save_codetags2($content, $editor, $action)
  323. {
  324. # check if syntax highlighted - if so not needed
  325. $sfsyntax = sf_get_option('sfsyntax');
  326. if ($sfsyntax['sfsyntaxforum'] == true && strpos($content, 'brush-'))
  327. {
  328. return $content;
  329. }
  330. # ONLY used for a TintMCE RichText Save 'Edit'
  331. if($editor == RICHTEXT && $action == 'edit')
  332. {
  333. # recheck extra line breaks and p tags - might have come from an edit
  334. $content = preg_replace_callback('/\<div class=\"sfcode\"\>(.*?)\<\/div\>/ms', "sf_codetag_callback", stripslashes($content));
  335. }
  336. return $content;
  337. }
  338. function sf_codetag_callback($s)
  339. {
  340. $content = str_replace("<br />", "", $s[1]);
  341. $content = str_replace("\n", "", $content);
  342. $content = '<div class="sfcode">'.$content.'</div>';
  343. return $content;
  344. }
  345. # ------------------------------------------------------------------
  346. # sf_filter_save_kses()
  347. #
  348. # Run it through kses - needs to be unescaped first
  349. # $content: Unfiltered post content
  350. # ------------------------------------------------------------------
  351. function sf_filter_save_kses($content)
  352. {
  353. global $allowedforumtags, $allowedforumprotocols;
  354. if(!isset($allowedforumtags))
  355. {
  356. sf_kses_array();
  357. $allowedforumtags = apply_filters('sf_custom_kses', $allowedforumtags);
  358. }
  359. $content = wp_kses(stripslashes($content), $allowedforumtags, $allowedforumprotocols);
  360. return $content;
  361. }
  362. # ------------------------------------------------------------------
  363. # sf_filter_save_linebreaks()
  364. #
  365. # Swap tinymce constructs with br's
  366. # $content: Unfiltered post content
  367. # ------------------------------------------------------------------
  368. function sf_filter_save_linebreaks($content)
  369. {
  370. $gap ='<p>'.chr(194).chr(160).'</p>'.chr(13).chr(10);
  371. $end ='<p>'.chr(194).chr(160).'</p>';
  372. # trim unwanted empty space
  373. $content = trim($content);
  374. while(substr($content, 0, 11) == $gap)
  375. {
  376. $content = substr_replace($content, '', 0, 11);
  377. }
  378. while(substr($content, (strlen($content)-9), 9) == $end)
  379. {
  380. $content = substr_replace($content, '', (strlen($content)-9), 9);
  381. }
  382. while(substr($content, (strlen($content)-11), 11) == $gap)
  383. {
  384. $content = substr_replace($content, '', (strlen($content)-11), 11);
  385. }
  386. # On savibng edit a 'br' may have a trailng line break which
  387. # will display like a paragraph break
  388. $content = str_replace("<br />".chr(13).chr(10), "\n", $content);
  389. # change br's to linebreaks
  390. $content = str_replace("<br />", "\n", $content);
  391. # change tiny blank line to a newline
  392. $content = str_replace($gap.$gap, $gap, $content);
  393. # same for blank line with p tags
  394. $content = str_replace("<p></p>", "\n\n", $content);
  395. $content = str_replace("<p> </p>", "\n\n", $content);
  396. $content = str_replace("<p>", "", $content);
  397. $content = str_replace("</p>", chr(13).chr(10), $content);
  398. return $content;
  399. }
  400. # ------------------------------------------------------------------
  401. # sf_filter_save_pre()
  402. #
  403. # Remove html 'pre' and '/pre' tags
  404. # $content: Unfiltered post content
  405. # ------------------------------------------------------------------
  406. function sf_filter_save_pre($content)
  407. {
  408. # remove pre tags
  409. $content = str_replace("<pre>", "", $content);
  410. $content = str_replace("</pre>", "", $content);
  411. $content = str_replace('&lt;pre&gt;', '', $content);
  412. $content = str_replace('&lt;/pre&gt;', '', $content);
  413. return $content;
  414. }
  415. # ------------------------------------------------------------------
  416. # sf_filter_save_quotes()
  417. #
  418. # Turn encoded single quote back
  419. # $content: Unfiltered post content
  420. # ------------------------------------------------------------------
  421. function sf_filter_save_quotes($content)
  422. {
  423. $content = str_replace("&#39;", "'", $content);
  424. # Replace those odd 0003 chars we have seen here and there
  425. $content = str_replace(chr(003), "'", $content);
  426. return $content;
  427. }
  428. # ------------------------------------------------------------------
  429. # sf_filter_save_balancetags()
  430. #
  431. # Tried to balance html tags
  432. # $content: Unfiltered post content
  433. # ------------------------------------------------------------------
  434. function sf_filter_save_balancetags($content)
  435. {
  436. $content = balanceTags($content, true);
  437. return $content;
  438. }
  439. # ------------------------------------------------------------------
  440. # sf_filter_save_nofollow()
  441. #
  442. # Adds nofollow to links at save post time
  443. # $content: Unfiltered post content
  444. # ------------------------------------------------------------------
  445. function sf_filter_save_nofollow($content)
  446. {
  447. $content = preg_replace_callback('|<a (.+?)>|i', 'sf_nofollow_callback', $content);
  448. return $content;
  449. }
  450. function sf_nofollow_callback($matches)
  451. {
  452. $text = $matches[1];
  453. $text = str_replace(array(' rel="nofollow"', " rel='nofollow'", 'rel="nofollow"', "rel='nofollow'"), '', $text);
  454. return '<a '.$text.' rel="nofollow">';
  455. }
  456. # ------------------------------------------------------------------
  457. # sf_filter_save_target()
  458. #
  459. # Forces target _blank to links at save post time
  460. # $content: Unfiltered post content
  461. # ------------------------------------------------------------------
  462. function sf_filter_save_target($content)
  463. {
  464. $content = preg_replace_callback('|<a (.+?)>|i', 'sf_target_callback', $content);
  465. return $content;
  466. }
  467. function sf_target_callback($matches)
  468. {
  469. $text = $matches[1];
  470. if(strpos($text, 'javascript:void(0)')) return "<a ".$text.">";
  471. $text = str_replace(array(' target="_blank"', " target='_blank'", 'target="_blank"', "target='_blank'"), '', $text);
  472. return '<a '.$text.' target="_blank">';
  473. }
  474. # ------------------------------------------------------------------
  475. # sf_filter_save_links()
  476. #
  477. # Turns urtls in posts to clickable links with shortened text
  478. # $content: Unfiltered post content
  479. # Thanks to Peter at http://www.theblog.ca/shorten-urls for this
  480. # ------------------------------------------------------------------
  481. function sf_filter_save_links($content, $charcount)
  482. {
  483. # make links clickable
  484. $content = sf_make_clickable($content);
  485. # pad it with a space
  486. $content = ' ' . $content;
  487. # chunk those long urls
  488. sf_format_links($content, $charcount);
  489. $content = preg_replace("#(\s)([a-z0-9\-_.]+)@([^,< \n\r]+)#i", "$1<a href=\"mailto:$2@$3\">$2@$3</a>", $content);
  490. # Remove our padding..
  491. $content = substr($content, 1);
  492. return($content);
  493. }
  494. function sf_format_links(&$content, $charcount)
  495. {
  496. $links = explode('<a', $content);
  497. $countlinks = count($links);
  498. for ($i = 0; $i < $countlinks; $i++)
  499. {
  500. $link = $links[$i];
  501. $link = (preg_match('#(.*)(href=")#is', $link)) ? '<a' . $link : $link;
  502. $begin = strpos($link, '>') + 1;
  503. $end = strpos($link, '<', $begin);
  504. $length = $end - $begin;
  505. $urlname = substr($link, $begin, $length);
  506. # We chunk urls that are longer than 50 characters. Just change
  507. # '50' to a value that suits your taste. We are not chunking the link
  508. # text unless if begins with 'http://', 'ftp://', or 'www.'
  509. $chunked = (strlen($urlname) > $charcount && preg_match('#^(http://|ftp://|www\.)#is', $urlname)) ? substr_replace($urlname, '.....', ($charcount - 10), -10) : $urlname;
  510. $content = str_replace('>' . $urlname . '<', '>' . $chunked . '<', $content);
  511. }
  512. }
  513. # ------------------------------------------------------------------
  514. # sf_filter_save_profanity()
  515. #
  516. # Swaps any unwanted words for alternatives in post content
  517. # $content: Unfiltered post content
  518. # ------------------------------------------------------------------
  519. function sf_filter_save_profanity($content)
  520. {
  521. $badwords = explode("\n", stripslashes(sf_get_option('sfbadwords')));
  522. $replacementwords = explode("\n", stripslashes(sf_get_option('sfreplacementwords')));
  523. # need to add in delimiter for preg replace
  524. foreach ($badwords as $index => $badword)
  525. {
  526. if (!empty($badword))
  527. {
  528. $badwords[$index] = '/\b'.trim($badword).'\b/i';
  529. $replacementwords[$index] = trim($replacementwords[$index]);
  530. } else {
  531. unset($badwords[$index]);
  532. }
  533. }
  534. # filter the bad words
  535. $content = preg_replace($badwords, $replacementwords, $content);
  536. return $content;
  537. }
  538. # ------------------------------------------------------------------
  539. # sf_filter_save_nohtml()
  540. #
  541. # Remove unwanted html
  542. # $title: Unfiltered title content
  543. # ------------------------------------------------------------------
  544. function sf_filter_save_nohtml($content)
  545. {
  546. $content = wp_kses(stripslashes($content), array());
  547. return $content;
  548. }
  549. # ------------------------------------------------------------------
  550. # sf_filter_save_brackets()
  551. #
  552. # Remove square brackets from titles
  553. # $content: Unfiltered post content
  554. # ------------------------------------------------------------------
  555. function sf_filter_save_brackets($content)
  556. {
  557. $content = str_replace('[', '&#091;', $content);
  558. $content = str_replace(']', '&#093;', $content);
  559. return $content;
  560. }
  561. # ------------------------------------------------------------------
  562. # sf_filter_save_escape()
  563. #
  564. # escape content before saving
  565. # $content: Unfiltered post content
  566. # ------------------------------------------------------------------
  567. function sf_filter_save_escape($content)
  568. {
  569. $content = esc_sql($content);
  570. return $content;
  571. }
  572. # ------------------------------------------------------------------
  573. # sf_filter_save_filename()
  574. #
  575. # Sanitises a filename and makes it safe
  576. # $filename: Unfiltered file name
  577. # ------------------------------------------------------------------
  578. function sf_filter_save_filename($filename)
  579. {
  580. $filename_raw = $filename;
  581. $special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", chr(0));
  582. $filename = str_replace($special_chars, '', $filename);
  583. $filename = preg_replace('/[\s-]+/', '-', $filename);
  584. $filename = trim($filename, '.-_');
  585. # Split the filename into a base and extension[s]
  586. $parts = explode('.', $filename);
  587. # Return if only one extension
  588. if ( count($parts) <= 2 )
  589. return $filename;
  590. # Process multiple extensions
  591. $filename = array_shift($parts);
  592. $extension = array_pop($parts);
  593. $mimes = get_allowed_mime_types();
  594. # Loop over any intermediate extensions. Munge them with a trailing underscore if they are a 2 - 5 character
  595. # long alpha string not in the extension whitelist.
  596. foreach ( (array) $parts as $part) {
  597. $filename .= '.' . $part;
  598. if ( preg_match("/^[a-zA-Z]{2,5}\d?$/", $part) ) {
  599. $allowed = false;
  600. foreach ( $mimes as $ext_preg => $mime_match ) {
  601. $ext_preg = '!(^' . $ext_preg . ')$!i';
  602. if ( preg_match( $ext_preg, $part ) ) {
  603. $allowed = true;
  604. break;
  605. }
  606. }
  607. if ( !$allowed )
  608. $filename .= '_';
  609. }
  610. }
  611. $filename = str_replace(' ', '_', $filename);
  612. $filename .= '.' . $extension;
  613. return $filename;
  614. }
  615. # ------------------------------------------------------------------
  616. # sf_filter_save_encode()
  617. #
  618. # Encode atributes
  619. # $content: usually a display name
  620. # ------------------------------------------------------------------
  621. function sf_filter_save_encode($content)
  622. {
  623. $content = esc_attr($content);
  624. return $content;
  625. }
  626. # ------------------------------------------------------------------
  627. # sf_filter_save_cleanemail()
  628. #
  629. # Sanitises am email address and makes it safe
  630. # $filename: Unfiltered file name
  631. # ------------------------------------------------------------------
  632. function sf_filter_save_cleanemail($email)
  633. {
  634. $email = sanitize_email($email);
  635. return $email;
  636. }
  637. # ------------------------------------------------------------------
  638. # sf_filter_save_cleanurl()
  639. #
  640. # Sanitises an url for db and makes it safe
  641. # $url: Unfiltered url
  642. # ------------------------------------------------------------------
  643. function sf_filter_save_cleanurl($url)
  644. {
  645. $url = esc_url_raw($url);
  646. return $url;
  647. }
  648. # ------------------------------------------------------------------
  649. # sf_filter_save_spoiler() and support functions
  650. #
  651. # Remove spoilers from content if not allowed
  652. # $content: Unfiltered post content
  653. # ------------------------------------------------------------------
  654. function sf_filter_save_spoiler($content)
  655. {
  656. $content = preg_replace('/\[spoiler\][^>]*\[\/spoiler\]/', '' , $content);
  657. return $content;
  658. }
  659. # ------------------------------------------------------------------
  660. # sf_filter_save_oEmbed() and support function
  661. #
  662. # Checks urls against the WP oEmbed class and pulls in the embed
  663. # code if a match is found. Performed before other url checks
  664. # $content: Unfiltered post content
  665. # ------------------------------------------------------------------
  666. function sf_filter_save_oEmbed($content)
  667. {
  668. $content = preg_replace_callback('#(?<!=\')(?<!=")(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+\#]*[\w\-\@?^=%&amp;/~\+\#])?#i', 'sf_check_save_oEmbed', $content);
  669. return $content;
  670. }
  671. function sf_check_save_oEmbed($match)
  672. {
  673. $url = wp_oembed_get($match[0]);
  674. if(empty($url)) $url=$match[0];
  675. return $url;
  676. }
  677. # ------------------------------------------------------------------
  678. # sf_filter_save_images() and support functions
  679. #
  680. # Set the width of images if possible at save time
  681. # $content: Unfiltered post content
  682. # ------------------------------------------------------------------
  683. function sf_filter_save_images($content)
  684. {
  685. return sf_check_save_image_width($content);
  686. }
  687. function sf_check_save_image_width($content)
  688. {
  689. $content = preg_replace_callback('/<img[^>]*>/', 'sf_check_save_width' , $content);
  690. return $content;
  691. }
  692. function sf_check_save_width($match)
  693. {
  694. global $SFPATHS;
  695. $out = '';
  696. $match[0] = stripslashes($match[0]);
  697. preg_match('/title\s*=\s*"([^"]*)"|title\s*=\s*\'([^\']*)\'/i', $match[0], $title);
  698. preg_match('/alt\s*=\s*"([^"]*)"|alt\s*=\s*\'([^\']*)\'/i', $match[0], $alt);
  699. preg_match('/width\s*=\s*"([^"]*)"|width\s*=\s*\'([^\']*)\'/i', $match[0], $width);
  700. preg_match('/src\s*=\s*"([^"]*)"|src\s*=\s*\'([^\']*)\'/i', $match[0], $src);
  701. preg_match('/style\s*=\s*"([^"]*)"|style\s*=\s*\'([^\']*)\'/i', $match[0], $style);
  702. preg_match('/class\s*=\s*"([^"]*)"|class\s*=\s*\'([^\']*)\'/i', $match[0], $class);
  703. if(isset($width[1])) return $match[0];
  704. if (isset($class[1])) return $match[0];
  705. if ((strpos($src[1], 'plugins/emotions')) || (strpos($src[1], 'images/smilies')) || (strpos($src[1], $SFPATHS['smileys'])))
  706. {
  707. $out = str_replace('img src', 'img class="sfsmiley" src', $match[0]);
  708. return $out;
  709. }
  710. # figure out whether its relative path (same server) or a url
  711. $parsed = parse_url($src[1]);
  712. if (array_key_exists('scheme', $parsed))
  713. {
  714. $srcfile = $src[1]; # url, so leave it alone
  715. } else {
  716. $srcfile = $_SERVER['DOCUMENT_ROOT'].$src[1]; # relative path, so add DOCUMENT_ROOT to path
  717. }
  718. if (empty($width[1]))
  719. {
  720. global $gis_error;
  721. $gis_error = '';
  722. set_error_handler('sf_gis_error');
  723. $size = getimagesize($srcfile);
  724. restore_error_handler();
  725. if ($gis_error == '')
  726. {
  727. if ($size[0])
  728. {
  729. $width[1] = $size[0];
  730. } else {
  731. return '['.__('Image Can Not Be Found', 'sp').']';
  732. }
  733. }
  734. }
  735. if (isset($src[1])) $thissrc = 'src="'.$src[1].'" '; else $thissrc = '';
  736. if (isset($title[1])) $thistitle = 'title="'.$title[1].'" '; else $thistitle = '';
  737. if (isset($alt[1])) $thisalt = 'alt="'.$alt[1].'" '; else $thisalt = '';
  738. if (isset($width[1])) $thiswidth = 'width="'.$width[1].'" '; else $thiswidth = '';
  739. if (isset($style[1])) $thisstyle = 'style="'.$style[1].'" '; else $thisstyle = '';
  740. if (isset($class[1])) $thisclass = 'class="'.$class[1].'" '; else $thisclass = '';
  741. $out.= esc_sql('<img '.$thissrc.$thiswidth.$thisstyle.$thisclass.$thistitle.$thisalt.'/>');
  742. return $out;
  743. }
  744. # ===END OF SAVE FILTERS============================================
  745. # ===START OF EDIT FILTERS==========================================
  746. #
  747. # CONTENT - EDIT FILTERS UMBRELLA
  748. #
  749. # Used: Forum Post
  750. # ?
  751. function sf_filter_content_edit($content)
  752. {
  753. global $sfglobals;
  754. # 1: Convert smiley codes to images
  755. $content = sf_filter_display_smileys($content);
  756. # 2: Convert Chars
  757. $content = sf_filter_display_chars($content);
  758. # 3: Format the paragraphs (p and br onlt Richtext)
  759. if($sfglobals['editor']['sfeditor'] != RICHTEXT) {
  760. $content = sf_filter_save_linebreaks($content);
  761. } else {
  762. $content = sf_filter_display_paragraphs($content);
  763. }
  764. # 4: Parse post into appropriate editor format
  765. $content = sf_filter_edit_parser($content, $sfglobals['editor']['sfeditor']);
  766. # 5: Turn off shortcode processing to keep from messing up their display
  767. remove_all_shortcodes();
  768. return $content;
  769. }
  770. # ==================================================================
  771. #
  772. # TEXT - EDIT FILTERS UMBRELLA
  773. #
  774. # Used: Text Areas
  775. # ?
  776. function sf_filter_text_edit($content)
  777. {
  778. global $sfglobals;
  779. # 1: Convert Chars
  780. $content = sf_filter_display_chars($content);
  781. # 2: Format the paragraphs (p and br)
  782. $content = sf_filter_display_paragraphs($content);
  783. $content = sf_filter_save_linebreaks($content);
  784. # 3: Parse post into appropriate editor format
  785. $content = sf_filter_edit_parser($content, PLAIN);
  786. # 4: remove escape slashes
  787. $content = sf_filter_display_stripslashes($content);
  788. # finally htnl encode it for edit display
  789. $content = htmlentities($content, ENT_COMPAT, SFCHARSET);
  790. return $content;
  791. }
  792. function sf_filter_edit_parser($content, $editor)
  793. {
  794. if($editor == BBCODE) {
  795. # load the bbcode to html parser
  796. include_once (SF_PLUGIN_DIR.'/forum/parsers/sf-htmltobb.php');
  797. $content = sf_Html2BBCode($content);
  798. } elseif($editor == HTML || $editor == PLAIN) {
  799. # load the raw to html parser
  800. include_once (SF_PLUGIN_DIR.'/forum/parsers/sf-htmltoraw.php');
  801. $content = sf_Html2Raw($content);
  802. }
  803. return $content;
  804. }
  805. # ===END OF EDIT FILTERS============================================
  806. # ===START OF DISPLAY FILTERS=======================================
  807. #
  808. # CONTENT - DISPLAY FILTERS UMBRELLA
  809. #
  810. # Used: Forum Post
  811. # Private Messages
  812. # Post Report
  813. # Template Tag
  814. # ?
  815. function sf_filter_content_display($content)
  816. {
  817. global $current_user;
  818. # 1: Backwards compatible make links clickable
  819. $content = sf_filter_display_links($content);
  820. # 2: Convert smiley codes to images
  821. $content = sf_filter_display_smileys($content);
  822. # 3: Convert Chars
  823. $content = sf_filter_display_chars($content);
  824. # 4: Format the paragraphs
  825. $content = sf_filter_display_paragraphs($content);
  826. # 5: Format the code select Divs.
  827. $content = sf_filter_display_codeselect($content);
  828. # 6: Format image tags
  829. $content = sf_filter_display_images($content);
  830. # 7: strip shortcodes
  831. if (sf_get_option('sffiltershortcodes'))
  832. {
  833. $content = sf_filter_display_shortcodes($content);
  834. }
  835. # 8: hide links
  836. if (!$current_user->sfviewlinks)
  837. {
  838. $content = sf_filter_display_hidelinks($content);
  839. }
  840. # 9: apply any users custom filters
  841. $content = apply_filters('sf_show_post_content', $content);
  842. return $content;
  843. }
  844. # ==================================================================
  845. #
  846. # TEXT - DISPLAY FILTERS UMBRELLA
  847. #
  848. # Used: Profile Description
  849. # Blog Linking Link Text
  850. # Group Message
  851. # Forum Message
  852. # Email Messages
  853. # Signature Text
  854. # Announce Tag Heading/Text
  855. # Sneak Peak Message
  856. # Admin View Message
  857. # Custom Editor Messages
  858. # Registration/Privacy Messages
  859. # Custom Profile Message
  860. # Admins Off-Line Message
  861. # ?
  862. function sf_filter_text_display($content)
  863. {
  864. # 1: Convert Chars
  865. $content = sf_filter_display_chars($content);
  866. # 2: Format the paragraphs
  867. $content = sf_filter_display_paragraphs($content);
  868. # 3: remove escape slashes
  869. $content = sf_filter_display_stripslashes($content);
  870. return $content;
  871. }
  872. # ==================================================================
  873. #
  874. # TITLE - DISPLAY FILTERS UMBRELLA
  875. #
  876. # Used: Group Title/Description *
  877. # Forum Title/Description *
  878. # Topic Title *
  879. # Message Title *
  880. # Blog Linking Titles *
  881. # Email Subject *
  882. # Custom Meta Description/Keywords *
  883. # Topic Status Name/List *
  884. # Custom Icon Title *
  885. # UserGroup Name/Description *
  886. # Permission Name/Description *
  887. # Profile Form Labels *
  888. # ?
  889. function sf_filter_title_display($content)
  890. {
  891. # 1: Convert Chars
  892. $content = sf_filter_display_chars($content);
  893. # 2: remove escape slashes
  894. $content = sf_filter_display_stripslashes($content);
  895. return $content;
  896. }
  897. # ==================================================================
  898. #
  899. # USER NAMES - DISPLAY FILTERS UMBRELLA
  900. #
  901. # Used: Display Name
  902. # Guest Name
  903. # ?
  904. function sf_filter_name_display($content)
  905. {
  906. # 1: Convert Chars
  907. $content = sf_filter_display_chars($content);
  908. # 2: remove escape slashes
  909. $content = sf_filter_display_stripslashes($content);
  910. return $content;
  911. }
  912. # ==================================================================
  913. #
  914. # EMAIL ADDRESS - DISPLAY FILTERS UMBRELLA
  915. #
  916. # Used: Guest posts
  917. # User profile
  918. # ?
  919. function sf_filter_email_display($email)
  920. {
  921. # 1: Convert Chars
  922. $email = sf_filter_display_chars($email);
  923. # 2: remove escape slashes
  924. $email = sf_filter_display_stripslashes($email);
  925. return $email;
  926. }
  927. # ==================================================================
  928. #
  929. # URL - DISPLAY FILTERS UMBRELLA
  930. #
  931. # Used: All URLs
  932. # ?
  933. function sf_filter_url_display($url)
  934. {
  935. # 1: Clean url for display
  936. $url = sf_filter_display_cleanurl($url);
  937. return $url;
  938. }
  939. # ===START OF DISPLAY FILTERS=======================================
  940. # ------------------------------------------------------------------
  941. # sf_filter_display_links()
  942. #
  943. # Makes unanchored links clickable. This is here for backward
  944. # compatibility with older storage of posts that incuded p tags
  945. #
  946. # $content: Unfiltered post content
  947. # ------------------------------------------------------------------
  948. function sf_filter_display_links($content)
  949. {
  950. # dont make clickable in pre or code tags
  951. $content = sf_make_clickable($content);
  952. return $content;
  953. }
  954. # ------------------------------------------------------------------
  955. # sf_convert_custom_smileys()
  956. #
  957. # Swaps codes for smileys if using custom images
  958. # $content: Unfiltered post content
  959. # ------------------------------------------------------------------
  960. function sf_filter_display_smileys($content)
  961. {
  962. global $sfglobals;
  963. # Custom
  964. if($sfglobals['smileyoptions']['sfsmallow'] && $sfglobals['smileyoptions']['sfsmtype']==1)
  965. {
  966. if($sfglobals['smileys'])
  967. {
  968. foreach ($sfglobals['smileys'] as $sname => $sinfo)
  969. {
  970. $content = str_replace($sinfo[1], '<img src="'.SFSMILEYS.$sinfo[0].'" title="'.$sname.'" alt="'.$sname.'" />', $content);
  971. }
  972. }
  973. }
  974. # WP versions
  975. if($sfglobals['smileyoptions']['sfsmallow'] && $sfglobals['smileyoptions']['sfsmtype']==3)
  976. {
  977. $content = convert_smilies($content);
  978. $content = str_replace("'", '"', $content);
  979. }
  980. return $content;
  981. }
  982. # ------------------------------------------------------------------
  983. # sf_filter_display_chars()
  984. #
  985. # Converts specific chars to entities
  986. # $content: Unfiltered post content
  987. # ------------------------------------------------------------------
  988. function sf_filter_display_chars($content)
  989. {
  990. $content = convert_chars($content);
  991. # This simply replaces those odd 0003 chars we have seen
  992. $content = str_replace(chr(003), "'", $content);
  993. return $content;
  994. }
  995. # ------------------------------------------------------------------
  996. # sf_filter_display_paragraphs()
  997. #
  998. # Breaks up into paragraphs - excluding syntax highlighted blocks
  999. # $content: Unfiltered post content
  1000. # ------------------------------------------------------------------
  1001. function sf_filter_display_paragraphs($content)
  1002. {
  1003. # check if syntax hoighlighted
  1004. $sfsyntax = sf_get_option('sfsyntax');
  1005. if($sfsyntax['sfsyntaxforum'] == true && strpos($content, 'brush-'))
  1006. {
  1007. $base = explode('<div class="sfcode">', $content);
  1008. if($base)
  1009. {
  1010. $comp = array();
  1011. foreach($base as $part)
  1012. {
  1013. if(substr(trim($part), 0, 18) == '<pre class="brush-')
  1014. {
  1015. $subparts = explode('</pre>', $part);
  1016. $comp[] = '<div class="sfcode">' . $subparts[0] .'</pre></div>';
  1017. $pos = strpos($subparts[1], '</div>');
  1018. $subparts[1] = substr($subparts[1], ($pos+6));
  1019. $comp[] = wpautop($subparts[1]);
  1020. unset($subparts);
  1021. } else {
  1022. $comp[] = wpautop($part);
  1023. }
  1024. }
  1025. $content = implode($comp);
  1026. }
  1027. } else {
  1028. $content = wpautop($content);
  1029. }
  1030. $content = shortcode_unautop($content);
  1031. return $content;
  1032. }
  1033. # ------------------------------------------------------------------
  1034. # sf_filter_display_codeselect()
  1035. #
  1036. # Adds the 'Select Code' button to code blocks
  1037. # ------------------------------------------------------------------
  1038. function sf_filter_display_codeselect($content)
  1039. {
  1040. # add the 'select code' button
  1041. $pos = strpos($content, '<div class="sfcode">');
  1042. if($pos === false) return $content;
  1043. # check if syntax hoighlighted
  1044. $sfsyntax = sf_get_option('sfsyntax');
  1045. if($sfsyntax['sfsyntaxforum'] == true && strpos($content, 'brush-'))
  1046. {
  1047. return $content;
  1048. }
  1049. while($pos !== false)
  1050. {
  1051. $id = rand(100, 10000);
  1052. $selector = '#sfcode'.$id;
  1053. $replace = '<p><input type="button" class="sfcodeselect" name="sfselectit'.$id.'" value="'.__("Select Code", "sforum").'" onclick="sfjSelectCode(\'sfcode'.$id.'\');" /></p><div class="sfcode" id="sfcode'.$id.'">';
  1054. $content = substr_replace ($content, $replace, $pos, 20);
  1055. $pos = $pos + 140;
  1056. $pos = strpos($content, '<div class="sfcode">', $pos);
  1057. }
  1058. return $content;
  1059. }
  1060. # ------------------------------------------------------------------
  1061. # sf_filter_display_images() and support functions
  1062. #
  1063. # Change large images to small thumbnails and embed
  1064. # $content: Unfiltered post content
  1065. # ------------------------------------------------------------------
  1066. function sf_filter_display_images($content)
  1067. {
  1068. return sf_swap_IMGs($content);
  1069. }
  1070. function sf_swap_IMGs($content)
  1071. {
  1072. $content = preg_replace_callback('/<img[^>]*>/', 'sf_check_width' , $content);
  1073. return $content;
  1074. }
  1075. function sf_check_width($match)
  1076. {
  1077. global $SFPATHS;
  1078. $out = '';
  1079. $sfimage = array();
  1080. $sfimage = sf_get_option('sfimage');
  1081. # is any of this needed?
  1082. if ($sfimage['enlarge']==false && $sfimage['process']==false) return $match[0];
  1083. $thumb = $sfimage['thumbsize'];
  1084. if ((empty($thumb)) || ($thumb < 100)) $thumb=100;
  1085. preg_match('/title\s*=\s*"([^"]*)"|title\s*=\s*\'([^\']*)\'/i', $match[0], $title);
  1086. preg_match('/alt\s*=\s*"([^"]*)"|alt\s*=\s*\'([^\']*)\'/i', $match[0], $alt);
  1087. preg_match('/width\s*=\s*"([^"]*)"|width\s*=\s*\'([^\']*)\'/i', $match[0], $width);
  1088. preg_match('/src\s*=\s*"([^"]*)"|src\s*=\s*\'([^\']*)\'/i', $match[0], $src);
  1089. preg_match('/style\s*=\s*"([^"]*)"|style\s*=\s*\'([^\']*)\'/i', $match[0], $style);
  1090. preg_match('/class\s*=\s*"([^"]*)"|class\s*=\s*\'([^\']*)\'/i', $match[0], $class);
  1091. if (isset($class[1])) return $match[0];
  1092. if ((strpos($src[1], 'plugins/emotions')) || (strpos($src[1], 'images/smilies')) || (strpos($src[1], $SFPATHS['smileys'])))
  1093. {
  1094. $out = str_replace('img src', 'img class="sfsmiley" src', $match[0]);
  1095. return $out;
  1096. }
  1097. # see if we can determoine if the image still exists before going further. So is it relative?
  1098. if (empty($width[1]) && substr($src[1], 0, 7) == 'http://')
  1099. {
  1100. if(function_exists('curl_init'))
  1101. {
  1102. $fcheck = curl_init();
  1103. curl_setopt($fcheck, CURLOPT_URL,$src[1]);
  1104. curl_setopt($fcheck, CURLOPT_NOBODY, 1);
  1105. curl_setopt($fcheck, CURLOPT_FAILONERROR, 1);
  1106. curl_setopt($fcheck, CURLOPT_RETURNTRANSFER, 1);
  1107. if(curl_exec($fcheck)===false)
  1108. {
  1109. return '['.__('Image Can Not Be Found', 'sforum').']';
  1110. }
  1111. }
  1112. }
  1113. if (empty($style[1]))
  1114. {
  1115. if ($sfimage['style'] == 'left' || $sfimage['style']=='right')
  1116. {
  1117. $style[1] = 'float: '.$sfimage['style'];
  1118. } else {
  1119. $style[1] = 'vertical-align: '.$sfimage['style'];
  1120. }
  1121. }
  1122. $iclass='';
  1123. $mclass="sfmouseother";
  1124. switch ($style[1])
  1125. {
  1126. case 'float: left':
  1127. $iclass="sfimageleft";
  1128. $mclass="sfmouseleft";
  1129. break;
  1130. case 'float: right':
  1131. $iclass="sfimageright";
  1132. $mclass="sfmouseright";
  1133. break;
  1134. case 'vertical-align: baseline':
  1135. $iclass="sfimagebaseline";
  1136. break;
  1137. case 'vertical-align: top':
  1138. $iclass="sfimagetop";
  1139. break;
  1140. case 'vertical-align: middle':
  1141. $iclass="sfimagemiddle";
  1142. break;
  1143. case 'vertical-align: bottom':
  1144. $iclass="sfimagebottom";
  1145. break;
  1146. case 'vertical-align: text-top':
  1147. $iclass="sfimagetexttop";
  1148. break;
  1149. case 'vertical-align: text-bottom':
  1150. $iclass="sfimagetextbottom";
  1151. break;
  1152. }
  1153. # figure out whether its relative path (same server) or a url
  1154. $parsed = parse_url($src[1]);
  1155. if (array_key_exists('scheme', $parsed))
  1156. {
  1157. $srcfile = $src[1]; # url, so leave it alone
  1158. } else {
  1159. $srcfile = $_SERVER['DOCUMENT_ROOT'].$src[1]; # relative path, so add DOCUMENT_ROOT to path
  1160. }
  1161. /*
  1162. global $gis_error;
  1163. $gis_error = '';
  1164. set_error_handler('sf_gis_error');
  1165. if (empty($width[1]))
  1166. {
  1167. $size = getimagesize($srcfile);
  1168. restore_error_handler();
  1169. if ($gis_error == '')
  1170. {
  1171. if ($size[0])
  1172. {
  1173. $width[1] = $size[0];
  1174. } else {
  1175. return '['.__('Image Can Not Be Found', 'sforum').']';
  1176. }
  1177. }
  1178. }
  1179. */
  1180. if (isset($src[1])) $thissrc = 'src="'.$src[1].'" '; else $thissrc = '';
  1181. if (isset($title[1])) $thistitle = 'title="'.$title[1].'" '; else $thistitle = '';
  1182. if (isset($alt[1])) $thisalt = 'alt="'.$alt[1].'" '; else $thisalt = '';
  1183. if ((int) $width[1] > (int)$thumb) { # is width > thumb size
  1184. $thiswidth = 'width="'.$thumb.'" ';
  1185. $anchor = true;
  1186. } else if (!empty($width)) { # width is smaller than thumb, so use the width
  1187. $thiswidth = 'width="'.$width[1].'" ';
  1188. $mclass = '';
  1189. $anchor = false;
  1190. } else { # couldnt determine width, so dont output it
  1191. // $thiswidth = '';
  1192. // $mclass = '';
  1193. $thiswidth = 'width="'.$thumb.'" ';
  1194. // $anchor = false;
  1195. $anchor = true;
  1196. }
  1197. if (!empty($iclass))
  1198. {
  1199. $thisformat = 'class="'.$iclass.'" ';
  1200. } else {
  1201. $thisformat = 'style="'.$style[1].'" ';
  1202. }
  1203. if ($anchor)
  1204. {
  1205. # Use highslide popup
  1206. if($sfimage['enlarge'] == true)
  1207. {
  1208. $out = '<a onclick="return hs.expand(this)" class="highslide" href="'.$src[1].'" '.$thistitle.'>';
  1209. } else {
  1210. $out = '<a href="'.$src[1].'" '.$thistitle.'>';
  1211. }
  1212. }
  1213. $out.= '<img '.$thissrc.$thiswidth.$thisformat.$thistitle.$thisalt.'/>';
  1214. if ($gis_error) $out.= '<br /><span class="sfimgerror small">['.__("Image Error", "sforum").': '.$gis_error.']</span>';
  1215. if ($mclass)
  1216. {
  1217. $out.= '<img src="'.SFRESOURCES.'mouse.png" class="'.$iclass.' '.$mclass.'" alt="" />';
  1218. }
  1219. if ($anchor)
  1220. {
  1221. $out.= '</a>';
  1222. }
  1223. return $out;
  1224. }
  1225. # ------------------------------------------------------------------
  1226. # sf_filter_display_stripslashes()
  1227. #
  1228. # Remov escaped slashes
  1229. # $content: Unfiltered post content
  1230. # ------------------------------------------------------------------
  1231. function sf_filter_display_stripslashes($content)
  1232. {
  1233. $content = stripslashes($content);
  1234. return $content;
  1235. }
  1236. # ------------------------------------------------------------------
  1237. # sf_filter_display_cleanurl()
  1238. #
  1239. # Cleans up url for display
  1240. # $url: Unfiltered url
  1241. # ------------------------------------------------------------------
  1242. function sf_filter_display_cleanurl($url)
  1243. {
  1244. $url = esc_url($url);
  1245. return $url;
  1246. }
  1247. # ------------------------------------------------------------------
  1248. # sf_filter_display_shortcodes()
  1249. #
  1250. # Removes non allowed shortcodes
  1251. # ------------------------------------------------------------------
  1252. function sf_filter_display_shortcodes($content)
  1253. {
  1254. global $shortcode_tags;
  1255. # Backup current registered shortcodes
  1256. $orig_shortcode_tags = $shortcode_tags;
  1257. $allowed_shortcodes = explode("\n", stripslashes(sf_get_option('sfshortcodes')));
  1258. if ($allowed_shortcodes)
  1259. {
  1260. foreach ($allowed_shortcodes as $tag)
  1261. {
  1262. If (array_key_exists($tag, $orig_shortcode_tags)) unset($shortcode_tags[$tag]);
  1263. }
  1264. }
  1265. # be sure to allow our spoilers
  1266. unset($shortcode_tags['spoiler']);
  1267. # strip all but allowed shortcodes
  1268. $content = strip_shortcodes($content);
  1269. # Restore registered shortcodes
  1270. $shortcode_tags = $orig_shortcode_tags;
  1271. return $content;
  1272. }
  1273. # ------------------------------------------------------------------
  1274. # sf_filter_display_hidelinks()
  1275. #
  1276. # Option: Removes links from post content
  1277. # ------------------------------------------------------------------
  1278. function sf_filter_display_hidelinks($content)
  1279. {
  1280. $sffilters = sf_get_option('sffilters');
  1281. $string = sf_filter_save_nohtml($sffilters['sfnolinksmsg']);
  1282. $content = preg_replace("#(<a.*>).*(</a>)#", $string, $content);
  1283. return $content;
  1284. }
  1285. # ==================================================================
  1286. #
  1287. # SPECIAL FILTERS - ONE OFFS
  1288. #
  1289. # The following filters are specific to one task - usually display
  1290. # ------------------------------------------------------------------
  1291. # sf_filter_signature_display() and support function
  1292. #
  1293. # Filters the display of signature images
  1294. # $content: Unfiltered signature content
  1295. # ------------------------------------------------------------------
  1296. function sf_filter_signature_display($content)
  1297. {
  1298. $sfsigimagesize = sf_get_option('sfsigimagesize');
  1299. if ($sfsigimagesize['sfsigwidth'] > 0 || $sfsigimagesize['sfsigheight'] > 0)
  1300. {
  1301. $content = preg_replace_callback('/<img[^>]*>/', 'sf_check_sig' , $content);
  1302. }
  1303. return $content;
  1304. }
  1305. function sf_check_sig($match)
  1306. {
  1307. $sfsigimagesize = sf_get_option('sfsigimagesize');
  1308. # get the elements of the img tags
  1309. preg_match('/title\s*=\s*"([^"]*)"|title\s*=\s*\'([^\']*)\'/i', $match[0], $title);
  1310. preg_match('/width\s*=\s*"([^"]*)"|width\s*=\s*\'([^\']*)\'/i', $match[0], $width);
  1311. preg_match('/height\s*=\s*"([^"]*)"|height\s*=\s*\'([^\']*)\'/i', $match[0], $height);
  1312. preg_match('/src\s*=\s*"([^"]*)"|src\s*=\s*\'([^\']*)\'/i', $match[0], $src);
  1313. preg_match('/style\s*=\s*"([^"]*)"|style\s*=\s*\'([^\']*)\'/i', $match[0], $style);
  1314. preg_match('/alt\s*=\s*"([^"]*)"|alt\s*=\s*\'([^\']*)\'/i', $match[0], $alt);
  1315. # check for possible single quote match or double quote
  1316. if (empty($title[1]) && !empty($title[2])) $title[1] = $title[2] ;
  1317. if (empty($width[1]) && !empty($width[2])) $width[1] = $width[2] ;
  1318. if (empty($height[1]) && !empty($height[2])) $height[1] = $height[2] ;
  1319. if (empty($src[1]) && !empty($src[2])) $src[1] = $src[2] ;
  1320. if (empty($style[1]) && !empty($style[2])) $style[1] = $style[2] ;
  1321. if (empty($alt[1]) && !empty($alt[2])) $alt[1] = $alt[2] ;
  1322. # if user defined heights are valid, just return
  1323. if ((!isset($width[1]) || $width[1] <= $sfsigimagesize['sfsigwidth']) &&
  1324. (!isset($height[1]) || $height[1] <= $sfsigimagesize['sfsigheight']))
  1325. {
  1326. return $match[0];
  1327. }
  1328. # insepct the image itself
  1329. global $gis_error;
  1330. $gis_error = '';
  1331. set_error_handler('sf_gis_error');
  1332. $display_width = '';
  1333. $display_height = '';
  1334. $size = getimagesize($src[1]);
  1335. restore_error_handler();
  1336. if ($gis_error == '')
  1337. {
  1338. # Did image exist?
  1339. if ($size[0] && $size[1])
  1340. {
  1341. # check width
  1342. if (isset($width[1]) && ($width[1] <= $sfsigimagesize['sfsigwidth'] || $sfsigimagesize['sfsigwidth'] == 0)) # width specified and less than max allowed
  1343. {
  1344. $display_width = ' width="'.$width[1].'"';
  1345. } else if ($sfsigimagesize['sfsigwidth'] > 0 && $size[0] > $sfsigimagesize['sfsigwidth']) {
  1346. $display_width = ' width="'.$sfsigimagesize['sfsigwidth'].'"';
  1347. }
  1348. # check the height
  1349. if (isset($height[1]) && ($height[1] <= $sfsigimagesize['sfsigheight'] || $sfsigimagesize['sfsigheight'] == 0)) # height specified and less than max allowed
  1350. {
  1351. $display_height = ' height="'.$height[1].'"';
  1352. } else if ($sfsigimagesize['sfsigheight'] > 0 && $size[1] > $sfsigimagesize['sfsigheight']) {
  1353. $display_height = ' height="'.$sfsigimagesize['sfsigheight'].'"';
  1354. }
  1355. } else {
  1356. # image not found, strip tags
  1357. return '';
  1358. }
  1359. } else {
  1360. # problem checking sizes, so just limit
  1361. $display_width = ' width="'.$sfsigimagesize['sfsigwidth'].'"';
  1362. $display_height = ' height="'.$sfsigimagesize['sfsigheight'].'"';
  1363. }
  1364. #
  1365. return '<img src="'.$src[1].'"'.$display_width.$display_height.' style="'.$style[1].'" title="'.$title[1].'" alt="'.$alt[1].'" />';
  1366. }
  1367. # ------------------------------------------------------------------
  1368. # sf_filter_tooltip_display()
  1369. #
  1370. # Filters the display of topic linked post 'tooltips'
  1371. # $content: Unfiltered post content
  1372. # $status: False if post awaiting moderation
  1373. # ------------------------------------------------------------------
  1374. function sf_filter_tooltip_display($content, $status)
  1375. {
  1376. global $current_user;
  1377. # can the current user view this post?
  1378. if($current_user->moderator == false && $status == 1)
  1379. {
  1380. $content = __("Post Awaiting Approval by Forum Administrator", "sforum");
  1381. } else {
  1382. $content = addslashes($content);
  1383. $content = sf_filter_save_nohtml($content);
  1384. # remove shortcodes to prevent messing up tooltip
  1385. $content = strip_shortcodes($content);
  1386. if(strlen($content) > 320)
  1387. {
  1388. $pos = strpos($content, ' ', 300);
  1389. $content = substr($content, 0, $pos).'...';
  1390. }
  1391. $content = htmlspecialchars($content, ENT_QUOTES, 'UTF-8');
  1392. $content = str_replace('&amp;', '&', $content);
  1393. # link urls to prevent oembed problems
  1394. $content = esc_attr(sf_make_clickable($content));
  1395. }
  1396. return $content;
  1397. }
  1398. # ------------------------------------------------------------------
  1399. # sf_filter_rss_display()
  1400. #
  1401. # Filters the display of post content in rss feed
  1402. # $content: Unfiltered post content
  1403. # ------------------------------------------------------------------
  1404. # Used: RSS Feeds
  1405. function sf_filter_rss_display($content)
  1406. {
  1407. global $current_user;
  1408. # 1: Backwards compatible make links clickable
  1409. $content = sf_filter_display_links($content);
  1410. # 2: Convert smiley codes to images
  1411. $content = sf_filter_display_smileys($content);
  1412. # 3: Convert Chars
  1413. $content = sf_filter_display_chars($content);
  1414. # 4: Format the paragraphs
  1415. $content = sf_filter_display_paragraphs($content);
  1416. # 5: strip shortcodes
  1417. if (sf_get_option('sffiltershortcodes'))
  1418. {
  1419. $content = sf_filter_display_shortcodes($content);
  1420. }
  1421. # 6: hide links
  1422. if (!$current_user->sfviewlinks)
  1423. {
  1424. $content = sf_filter_display_hidelinks($content);
  1425. }
  1426. # 7: apply any users custom filters
  1427. $content = apply_filters('sf_show_post_content', $content);
  1428. return $content;
  1429. }
  1430. # ------------------------------------------------------------------
  1431. # sf_filter_table_prefix()
  1432. #
  1433. # Filters the prefix from table names
  1434. # $content: Unfiltered content
  1435. # ------------------------------------------------------------------
  1436. # Used as a filter in seach values - aids killing SQL injections
  1437. function sf_filter_table_prefix($content)
  1438. {
  1439. $long = array(
  1440. SF_PREFIX.'commentmeta', SF_PREFIX.'comments', SF_PREFIX.'links', SF_PREFIX.'options', SF

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