Guest User

My bbcode.php

a guest
Aug 9th, 2013
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 25.16 KB | None | 0 0
  1. <?php
  2.  
  3. if (!defined('BB_ROOT')) die(basename(__FILE__));
  4.  
  5. $datastore->enqueue(array(
  6.     'smile_replacements',
  7. ));
  8.  
  9. $page_cfg['include_bbcode_js'] = true;
  10.  
  11. //
  12. // BBCode templates
  13. //
  14. function get_bbcode_tpl ()
  15. {
  16. $bbcode_tpl = array();
  17.  
  18. // Quote
  19. $bbcode_tpl['quote_open'] = <<<HTML
  20.     <div class="q-wrap">
  21.         <div class="q">
  22. HTML;
  23.  
  24. $bbcode_tpl['quote_username_open'] = <<<HTML
  25.     <div class="q-wrap">
  26.         <div class="q" head="\\1">
  27. HTML;
  28.  
  29. $bbcode_tpl['quote_close'] = <<<HTML
  30.         </div>
  31.     </div>
  32. HTML;
  33.  
  34. // Code
  35. $bbcode_tpl['code_open'] = <<<HTML
  36.     <div class="c-wrap">
  37.         <div class="c-head"><b>Код:</b></div>
  38.         <div class="c-body">
  39. HTML;
  40.  
  41. $bbcode_tpl['code_close'] = <<<HTML
  42.         </div>
  43.     </div>
  44. HTML;
  45.  
  46. // Spoiler
  47. $bbcode_tpl['spoiler_open'] = <<<HTML
  48.     <div class="sp-wrap">
  49.         <div class="sp-body">
  50. HTML;
  51.  
  52. $bbcode_tpl['spoiler_title_open'] = <<<HTML
  53.     <div class="sp-wrap">
  54.         <div class="sp-body" title="\\1">
  55.         <h3 class="sp-title">\\1</h3>
  56. HTML;
  57.  
  58. $bbcode_tpl['spoiler_close'] = <<<HTML
  59.         </div>
  60.     </div>
  61. HTML;
  62.  
  63. // Image
  64. $bbcode_tpl['img'] = <<<HTML
  65.     <var class="postImg" title="$1">&#10;</var>
  66. HTML;
  67.  
  68. $bbcode_tpl['img_aligned'] = <<<HTML
  69.     <var class="postImg postImgAligned img-\\1" title="\\2">&#10;</var>
  70. HTML;
  71.  
  72. // HR
  73. $bbcode_tpl['hr'] = <<<HTML
  74.     <span class="post-hr">-</span>
  75. HTML;
  76.  
  77. array_deep($bbcode_tpl, 'bbcode_tpl_compact');
  78. return $bbcode_tpl;
  79. }
  80.  
  81. function bbcode_tpl_compact ($text)
  82. {
  83.     $text = str_compact($text);
  84.     $text = str_replace('> <', '><', $text);
  85.     return $text;
  86. }
  87.  
  88. // prepare a posted message for entry into the database
  89. function prepare_message ($message)
  90. {
  91.     $message = bbcode::clean_up($message);
  92.     $message = htmlCHR($message, false, ENT_NOQUOTES);
  93.     return $message;
  94. }
  95.  
  96. // Fill smiley templates (or just the variables) with smileys
  97. // Either in a window or inline
  98. function generate_smilies($mode)
  99. {
  100.     global $bb_cfg, $template, $lang, $images, $user, $datastore;
  101.  
  102.     $inline_columns = 4;
  103.     $inline_rows = 7;
  104.     $window_columns = 8;
  105.  
  106.     if ($mode == 'window')
  107.     {
  108.         $user->session_start();
  109.     }
  110.  
  111.     $data = $datastore->get('smile_replacements');
  112.  
  113.     if ($sql = $data['smile'])
  114.     {
  115.         $num_smilies = 0;
  116.         $rowset = array();
  117.         foreach ($sql as $row)
  118.         {
  119.             if (empty($rowset[$row['smile_url']]))
  120.             {
  121.                 $rowset[$row['smile_url']]['code'] = str_replace("'", "\\'", str_replace('\\', '\\\\', $row['code']));
  122.                 $rowset[$row['smile_url']]['emoticon'] = $row['emoticon'];
  123.                 $num_smilies++;
  124.             }
  125.         }
  126.  
  127.         if ($num_smilies)
  128.         {
  129.             $smilies_count = ($mode == 'inline') ? min(19, $num_smilies) : $num_smilies;
  130.             $smilies_split_row = ($mode == 'inline') ? $inline_columns - 1 : $window_columns - 1;
  131.  
  132.             $s_colspan = 0;
  133.             $row = 0;
  134.             $col = 0;
  135.  
  136.             while (list($smile_url, $data) = @each($rowset))
  137.             {
  138.                 if (!$col)
  139.                 {
  140.                     $template->assign_block_vars('smilies_row', array());
  141.                 }
  142.  
  143.                 $template->assign_block_vars('smilies_row.smilies_col', array(
  144.                     'SMILEY_CODE' => $data['code'],
  145.                     'SMILEY_IMG' => $bb_cfg['smilies_path'] . '/' . $smile_url,
  146.                     'SMILEY_DESC' => $data['emoticon'])
  147.                 );
  148.  
  149.                 $s_colspan = max($s_colspan, $col + 1);
  150.  
  151.                 if ($col == $smilies_split_row)
  152.                 {
  153.                     if ($mode == 'inline' && $row == $inline_rows - 1)
  154.                     {
  155.                         break;
  156.                     }
  157.                     $col = 0;
  158.                     $row++;
  159.                 }
  160.                 else
  161.                 {
  162.                     $col++;
  163.                 }
  164.             }
  165.  
  166.             if ($mode == 'inline' && $num_smilies > $inline_rows * $inline_columns)
  167.             {
  168.                 $template->assign_block_vars('switch_smilies_extra', array());
  169.  
  170.                 $template->assign_vars(array(
  171.                     'U_MORE_SMILIES' => "posting.php?mode=smilies")
  172.                 );
  173.             }
  174.  
  175.             $template->assign_vars(array(
  176.                 'PAGE_TITLE' => $lang['EMOTICONS'],
  177.                 'S_SMILIES_COLSPAN' => $s_colspan,
  178.             ));
  179.         }
  180.     }
  181.  
  182.     if ($mode == 'window')
  183.     {
  184.         print_page('posting_smilies.tpl', 'simple');
  185.     }
  186. }
  187.  
  188. // some functions from vB
  189. // #############################################################################
  190. /**
  191. * Strips away [quote] tags and their contents from the specified string
  192. *
  193. * @param    string  Text to be stripped of quote tags
  194. *
  195. * @return   string
  196. */
  197. function strip_quotes ($text)
  198. {
  199.     $lowertext = strtolower($text);
  200.  
  201.     // find all [quote tags
  202.     $start_pos = array();
  203.     $curpos = 0;
  204.     do
  205.     {
  206.         $pos = strpos($lowertext, '[quote', $curpos);
  207.         if ($pos !== false)
  208.         {
  209.             $start_pos["$pos"] = 'start';
  210.             $curpos = $pos + 6;
  211.         }
  212.     }
  213.     while ($pos !== false);
  214.  
  215.     if (sizeof($start_pos) == 0)
  216.     {
  217.         return $text;
  218.     }
  219.  
  220.     // find all [/quote] tags
  221.     $end_pos = array();
  222.     $curpos = 0;
  223.     do
  224.     {
  225.         $pos = strpos($lowertext, '[/quote', $curpos);
  226.         if ($pos !== false)
  227.         {
  228.             $end_pos["$pos"] = 'end';
  229.             $curpos = $pos + 8;
  230.         }
  231.     }
  232.     while ($pos !== false);
  233.  
  234.     if (sizeof($end_pos) == 0)
  235.     {
  236.         return $text;
  237.     }
  238.  
  239.     // merge them together and sort based on position in string
  240.     $pos_list = $start_pos + $end_pos;
  241.     ksort($pos_list);
  242.  
  243.     do
  244.     {
  245.         // build a stack that represents when a quote tag is opened
  246.         // and add non-quote text to the new string
  247.         $stack = array();
  248.         $newtext = '[...] ';
  249.         $substr_pos = 0;
  250.         foreach ($pos_list AS $pos => $type)
  251.         {
  252.             $stacksize = sizeof($stack);
  253.             if ($type == 'start')
  254.             {
  255.                 // empty stack, so add from the last close tag or the beginning of the string
  256.                 if ($stacksize == 0)
  257.                 {
  258.                     $newtext .= substr($text, $substr_pos, $pos - $substr_pos);
  259.                 }
  260.                 array_push($stack, $pos);
  261.             }
  262.             else
  263.             {
  264.                 // pop off the latest opened tag
  265.                 if ($stacksize)
  266.                 {
  267.                     array_pop($stack);
  268.                     $substr_pos = $pos + 8;
  269.                 }
  270.             }
  271.         }
  272.  
  273.         // add any trailing text
  274.         $newtext .= substr($text, $substr_pos);
  275.  
  276.         // check to see if there's a stack remaining, remove those points
  277.         // as key points, and repeat. Allows emulation of a non-greedy-type
  278.         // recursion.
  279.         if ($stack)
  280.         {
  281.             foreach ($stack AS $pos)
  282.             {
  283.                 unset($pos_list["$pos"]);
  284.             }
  285.         }
  286.     }
  287.     while ($stack);
  288.  
  289.     return $newtext;
  290. }
  291.  
  292. // #############################################################################
  293. /**
  294. * Strips away bbcode from a given string, leaving plain text
  295. *
  296. * @param    string  Text to be stripped of bbcode tags
  297. * @param    boolean If true, strip away quote tags AND their contents
  298. * @param    boolean If true, use the fast-and-dirty method rather than the shiny and nice method
  299. *
  300. * @return   string
  301. */
  302. function strip_bbcode ($message, $stripquotes = true, $fast_and_dirty = false, $showlinks = true)
  303. {
  304.     $find = array();
  305.     $replace = array();
  306.  
  307.     if ($stripquotes)
  308.     {
  309.         // [quote=username] and [quote]
  310.         $message = strip_quotes($message);
  311.     }
  312.  
  313.     // a really quick and rather nasty way of removing bbcode
  314.     if ($fast_and_dirty)
  315.     {
  316.         // any old thing in square brackets
  317.         $find[] = '#\[.*/?\]#siU';
  318.         $replace = '';
  319.  
  320.         $message = preg_replace($find, $replace, $message);
  321.     }
  322.     // the preferable way to remove bbcode
  323.     else
  324.     {
  325.         // simple links
  326.         $find[] = '#\[(email|url)=("??)(.+)\\2\]\\3\[/\\1\]#siU';
  327.         $replace[] = '\3';
  328.  
  329.         // named links
  330.         $find[] = '#\[(email|url)=("??)(.+)\\2\](.+)\[/\\1\]#siU';
  331.         $replace[] = ($showlinks ? '\4 (\3)' : '\4');
  332.  
  333.         // smilies
  334.         $find[] = '#(?<=^|\W)(:\w+?:)(?=$|\W)#';
  335.         $replace[] = '';
  336.  
  337.         // replace
  338.         $message = preg_replace($find, $replace, $message);
  339.  
  340.         // strip out all other instances of [x]...[/x]
  341.         while (preg_match('#\[([a-z]+)\s*?(?:[^\]]*?)\](.*?)(\[/\1\])#is', $message, $m))
  342.         {
  343.             $message = str_replace($m[0], $m[2], $message);
  344.         }
  345.  
  346.         $replace = array('[*]', '[hr]', '[br]', '[align=center]', '[align=left]', '[align=right]');
  347.         $message = str_replace($replace, ' ', $message);
  348.     }
  349.  
  350.     return $message;
  351. }
  352.  
  353. function extract_search_words ($text)
  354. {
  355.     global $bb_cfg;
  356.  
  357.     $max_words_count = $bb_cfg['max_search_words_per_post'];
  358.     $min_word_len    = max(2, $bb_cfg['search_min_word_len'] - 1);
  359.     $max_word_len    = $bb_cfg['search_max_word_len'];
  360.  
  361.     $text = ' ' . str_compact(strip_tags(mb_strtolower($text))) . ' ';
  362.     $text = str_replace(array('&#91;', '&#93;'), array('[', ']'), $text);
  363.  
  364.     // HTML entities like &nbsp;
  365.     $text = preg_replace('/(\w*?)&#?[0-9a-z]+;(\w*?)/iu', '', $text);
  366.     // Remove URL's       ((www|ftp)\.[\w\#!$%&~/.\-;:=,?@а-яА-Я\[\]+]*?)
  367.     $text = preg_replace('#\b[a-z0-9]+://[\w\#!$%&~/.\-;:=,?@а-яА-Я\[\]+]+(/[0-9a-z\?\.%_\-\+=&/]+)?#u', ' ', $text);
  368.     $text = str_replace('[url=', ' ', $text);
  369.     $text = str_replace('?', ' ', $text);
  370.     $text = str_replace('!', ' ', $text);
  371.  
  372.     $text = strip_bbcode($text);
  373.  
  374.     // Filter out characters like ^, $, &, change "it's" to "its"
  375.     $text = preg_replace('#[.,:;]#u', ' ', $text);
  376.  
  377.     // short & long words
  378.     // $text = preg_replace('#(?<=^|\s)(\S{1,'.$min_word_len.'}|\S{'.$max_word_len.',}|\W*)(?=$|\s)#u', ' ', $text);
  379.  
  380.     $text = remove_stopwords($text);
  381. #   $text = replace_synonyms($text);
  382.  
  383.     // Trim 1+ spaces to one space and split this string into unique words
  384.     $text = array_unique(explode(' ', str_compact($text)));
  385.  
  386.     // short & long words 2
  387.     $text_out = array();
  388.     foreach ($text as $word)
  389.     {
  390.         if (mb_strlen($word) > $min_word_len && mb_strlen($word) <= $max_word_len) $text_out[] = $word;
  391.     }
  392.     $text = $text_out;
  393.  
  394.     if (sizeof($text) > $max_words_count)
  395.     {
  396. #       shuffle($text);
  397.         $text = array_splice($text, 0, $max_words_count);
  398.     }
  399.  
  400.     return $text;
  401. }
  402.  
  403. function replace_synonyms ($text)
  404. {
  405.     static $syn_match = null, $syn_replace = null;
  406.  
  407.     if (is_null($syn_match))
  408.     {
  409.         preg_match_all("#(\w+) (\w+)(\r?\n|$)#", @file_get_contents(LANG_DIR .'search_synonyms.txt'), $m);
  410.  
  411.         $syn_match   = $m[2];
  412.         $syn_replace = $m[1];
  413.  
  414.         array_deep($syn_match,   'pad_with_space');
  415.         array_deep($syn_replace, 'pad_with_space');
  416.     }
  417.  
  418.     return ($syn_match && $syn_replace) ? str_replace($syn_match, $syn_replace, $text) : $text;
  419. }
  420.  
  421. function add_search_words ($post_id, $post_message, $post_title = '', $only_return_words = false)
  422. {
  423.     $text  = $post_title .' '. $post_message;
  424.     $text  = strip_bbcode_uid($text);
  425.     $words = ($text) ? extract_search_words($text) : array();
  426.  
  427.     if ($only_return_words)
  428.     {
  429.         return join("\n", $words);
  430.     }
  431.     else
  432.     {
  433.         DB()->query("DELETE FROM ". BB_POSTS_SEARCH ." WHERE post_id = $post_id");
  434.  
  435.         if ($words_sql = DB()->escape(join("\n", $words)))
  436.         {
  437.             DB()->query("REPLACE INTO ". BB_POSTS_SEARCH ." (post_id, search_words) VALUES ($post_id, '$words_sql')");
  438.         }
  439.     }
  440. }
  441.  
  442. class bbcode
  443. {
  444.     var $tpl        = array(); // шаблоны для замены тегов
  445.     var $smilies    = null;    // смайлы
  446.     var $found_spam = null;    // найденные спам "слова"
  447.     var $del_words  = array(); // см. get_words_rate()
  448.     var $tidy_cfg   = array(
  449.                 'drop-empty-paras'  => false,
  450.                 'fix-uri'           => false,
  451.                 'force-output'      => true,
  452.                 'hide-comments'     => true,
  453.                 'join-classes'      => false,
  454.                 'join-styles'       => false,
  455.                 'merge-divs'        => false,
  456.                 'merge-spans'       => false,
  457.                 'newline'           => 'LF',
  458.                 'output-xhtml'      => true,
  459.                 'preserve-entities' => true,
  460.                 'quiet'             => true,
  461.                 'quote-ampersand'   => false,
  462.                 'show-body-only'    => true,
  463.                 'show-errors'       => false,
  464.                 'show-warnings'     => false,
  465.                 'wrap'              => 0,
  466.     );
  467.     var $block_tags = array(
  468.                 'align',
  469.                 'br',
  470.                 'clear',
  471.                 'hr',
  472.                 'list',
  473.                 'pre',
  474.                 'quote',
  475.                 'spoiler',
  476.     );
  477.     var $preg        = array();
  478.     var $str         = array();
  479.     var $preg_search = array();
  480.     var $preg_repl   = array();
  481.     var $str_search  = array();
  482.     var $str_repl    = array();
  483.  
  484.     /**
  485.     * Constructor
  486.     */
  487.     function bbcode ()
  488.     {
  489.         $this->tpl = get_bbcode_tpl();
  490.  
  491.         $this->init_replacements();
  492.     }
  493.  
  494.     /**
  495.     * init_replacements
  496.     */
  497.     function init_replacements ()
  498.     {
  499.         $tpl         = $this->tpl;
  500.         $img_url_exp = 'http://[^\s\?&;=\#\"<>]+?\.(jpg|jpeg|gif|png)';
  501.         $email_exp   = '[a-z0-9&\-_.]+?@[\w\-]+\.([\w\-\.]+\.)?[\w]+';
  502.         $url_exp     = '[\w\#!$%&~/.\-;:=,?@а-яА-Я\[\]+]+?';
  503.  
  504.         $this->preg = array(
  505.             '#\[quote="(.+?)"\]#isu'                                 => $tpl['quote_username_open'],
  506.             '#\[spoiler="(.+?)"\]#isu'                               => $tpl['spoiler_title_open'],
  507.             '#\[list=(a|A|i|I|1)\]#isu'                              => '<ul type="$1">',
  508.             '#\[\*=(\d+)\]#isu'                                      => '<li value="$1">',
  509.             '#\[pre\](.*?)\[/pre\]#isu'                              => '<pre class="post-pre">$1</pre>',
  510.             '#\[mp3\](.*?)\[/mp3\]#isu'                              => '<object type="application/x-shockwave-flash" data="http://'.$_SERVER['HTTP_HOST'].'/player.swf" height="70" width="470"><param name="wmode" value="transparent" /><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="movie" value="http://'.$_SERVER['HTTP_HOST'].'/player.swf" /><param name="FlashVars" value="way=$1&amp;swf=http://'.$_SERVER['HTTP_HOST'].'/player.swf&amp;w=470&amp;h=70&amp;time_seconds=164&amp;autoplay=0&amp;q=&amp;skin=white&amp;volume=70&amp;comment=" /></object>',
  511.             '#\[youtube\](.*?)\[/youtube\]#isu'                      => '<iframe width="600" height="400" src="//www.youtube.com/embed/$1" frameborder="0" allowfullscreen></iframe>',
  512.             '#\[name=([a-zA-Z0-9_]+?)\]#isu'                         => '<a name="$1"></a>',
  513.             '#\[url=\#([a-zA-Z0-9_]+?)\](.*?)\[/url\]#isu'           => '<a class="postLink-name" href="/redir/?#$1">$2</a>',
  514.             '#\[color=([\#0-9a-zA-Z]+)\]#isu'                        => '<span style="color: $1;">',
  515.             '#\[size=([1-2]?[0-9])\]#isu'                            => '<span style="font-size: $1px; line-height: normal;">',
  516.             '#\[align=(left|right|center|justify)\]#isu'             => '<span class="post-align" style="text-align: $1;">',
  517.             '#\[font="([\w\- \']+)"\]#isu'                           => '<span style="font-family: $1;">',
  518.             "#\[img\]($img_url_exp)\[/img\]#isu"                     => $tpl['img'],
  519.             "#\[img=(left|right)\]($img_url_exp)\[/img\]\s*#isu"     => $tpl['img_aligned'],
  520.             "#\[url\](https?://$url_exp)\[/url\]#isu"                => '<a href="/redir/?$1" target="_blank" class="postLink">$1</a>',
  521.             "#\[url\](www\.$url_exp)\[/url\]#isu"                    => '<a href="/redir/?http://$1" target="_blank" class="postLink">$1</a>',
  522.             "#\[url=(https?://$url_exp)\]([^?\n\t].*?)\[/url\]#isu"  => '<a href="/redir/?$1" target="_blank" class="postLink">$2</a>',
  523.             "#\[url=(www\.$url_exp)\]([^?\n\t].*?)\[/url\]#isu"      => '<a href="/redir/?http://$1" target="_blank" class="postLink">$2</a>',
  524.             "#\[email\]($email_exp)\[/email\]#isu"                   => '<a href="mailto:$1">$1</a>',
  525.             "#\[qpost=([0-9]*)\]#isu"                                => '<u class="q-post">$1</u>',
  526.         );
  527.  
  528.         $this->str = array(
  529.             '[quote]'    => $tpl['quote_open'],
  530.             '[/quote]'   => $tpl['quote_close'],
  531.             '[spoiler]'  => $tpl['spoiler_open'],
  532.             '[/spoiler]' => $tpl['spoiler_close'],
  533.             '[list]'     => '<ul>',
  534.             '[*]'        => '<li>',
  535.             '[/list]'    => '</ul>',
  536.             '[/color]'   => '</span>',
  537.             '[/size]'    => '</span>',
  538.             '[/align]'   => '</span>',
  539.             '[/font]'    => '</span>',
  540.             '[tab]'      => ' ',
  541.             '[br]'       => "\n\n",
  542.             '[hr]'       => $tpl['hr'],
  543.             '[b]'        => '<span class="post-b">',
  544.             '[/b]'       => '</span>',
  545.             '[u]'        => '<span class="post-u">',
  546.             '[/u]'       => '</span>',
  547.             '[i]'        => '<span class="post-i">',
  548.             '[/i]'       => '</span>',
  549.             '[s]'        => '<span class="post-s">',
  550.             '[/s]'       => '</span>',
  551.             '[del]'      => '<span class="post-s">',
  552.             '[/del]'     => '</span>',
  553.             '[clear]'    => '<div class="clear">&nbsp;</div>',
  554.         );
  555.  
  556.         $this->preg_search = array_keys($this->preg);
  557.         $this->preg_repl   = array_values($this->preg);
  558.         $this->str_search  = array_keys($this->str);
  559.         $this->str_repl    = array_values($this->str);
  560.     }
  561.  
  562.     /**
  563.     * bbcode2html
  564.     * $text должен быть уже обработан htmlCHR($text, false, ENT_NOQUOTES);
  565.     */
  566.     function bbcode2html ($text)
  567.     {
  568.         global $bb_cfg;
  569.  
  570.         $text = " $text ";
  571.         $text = $this->clean_up($text);
  572.         $text = $this->spam_filter($text);
  573.  
  574.         // парсинг тегов
  575.         if (strpos($text, '[') !== false)
  576.         {
  577.             // [CODE]
  578.             $text = preg_replace_callback('#(\s*)\[code\](.+?)\[/code\](\s*)#s', array(&$this, 'code_callback'), $text);
  579.  
  580.             // Escape tags inside tiltes in [quote="tilte"]
  581.             $text = preg_replace_callback('#(\[(quote|spoiler)=")(.+?)("\])#', array(&$this, 'escape_tiltes_callback'), $text);
  582.  
  583.             // Normalize block level tags wrapped with new lines
  584.             $block_tags = join('|', $this->block_tags);
  585.             $text = str_replace("\n\n[hr]\n\n", '[br][hr][br]', $text);
  586.             $text = preg_replace("#(\s*)(\[/?($block_tags)(.*?)\])(\s*)#", '$2', $text);
  587.  
  588.             // Tag replacements
  589.             $text = preg_replace($this->preg_search, $this->preg_repl, $text);
  590.             $text = str_replace($this->str_search, $this->str_repl, $text);
  591.         }
  592.  
  593.         $text = $this->make_clickable($text);
  594.         $text = $this->smilies_pass($text);
  595.         $text = $this->new_line2html($text);
  596.         $text = trim($text);
  597.  
  598.         if ($bb_cfg['tidy_post'])
  599.         {
  600.             $text = $this->tidy($text);
  601.         }
  602.  
  603.         return trim($text);
  604.     }
  605.  
  606.     /**
  607.     * Clean up
  608.     */
  609.     static function clean_up ($text)
  610.     {
  611.         $text = trim($text);
  612.         $text = str_replace("\r", '', $text);
  613.         $text = preg_replace('#[ \t]+$#m', '', $text); // trailing spaces
  614.         $text = preg_replace('#\n{3,}#', "\n\n", $text);
  615.         return $text;
  616.     }
  617.  
  618.     /**
  619.     * Spam filter
  620.     */
  621.     static function spam_filter ($text)
  622.     {
  623.         global $bb_cfg;
  624.         static $spam_words = null;
  625.         static $spam_replace = ' СПАМ';
  626.  
  627.         if (isset($this))
  628.         {
  629.             $found_spam =& $this->found_spam;
  630.         }
  631.  
  632.         // set $spam_words and $spam_replace
  633.         if (!$bb_cfg['spam_filter_file_path'])
  634.         {
  635.             return $text;
  636.         }
  637.         if (is_null($spam_words))
  638.         {
  639.             $spam_words = file_get_contents($bb_cfg['spam_filter_file_path']);
  640.             $spam_words = strtolower($spam_words);
  641.             $spam_words = explode("\n", $spam_words);
  642.         }
  643.  
  644.         $found_spam = array();
  645.  
  646.         $tm_start = utime();
  647.  
  648.         $msg_decoded = $text;
  649.         $msg_decoded = html_entity_decode($msg_decoded);
  650.         $msg_decoded = urldecode($msg_decoded);
  651.         $msg_decoded = str_replace('&', ' &', $msg_decoded);
  652.  
  653.         $msg_search = strtolower($msg_decoded);
  654.  
  655.         foreach ($spam_words as $spam_str)
  656.         {
  657.             if (!$spam_str = trim($spam_str))
  658.             {
  659.                 continue;
  660.             }
  661.             if (strpos($msg_search, $spam_str) !== false)
  662.             {
  663.                 $found_spam[] = $spam_str;
  664.             }
  665.         }
  666.         if ($found_spam)
  667.         {
  668.             $spam_exp = array();
  669.             foreach ($found_spam as $keyword)
  670.             {
  671.                 $spam_exp[] = preg_quote($keyword, '/');
  672.             }
  673.             $spam_exp = join('|', $spam_exp);
  674.  
  675.             $text = preg_replace("/($spam_exp)(\S*)/i", $spam_replace, $msg_decoded);
  676.             $text = htmlCHR($text, false, ENT_NOQUOTES);
  677. #           bb_log(date("H:i:s") ." | ". sprintf('%.4f', (utime() - $tm_start)) ." | ". sprintf('%-6s', strlen($text)) ." | ". join(' ** ', $found_spam) ."\n", 'spam_filter');
  678.         }
  679.  
  680.         return $text;
  681.     }
  682.  
  683.     /**
  684.     * [code] callback
  685.     */
  686.     function code_callback ($m)
  687.     {
  688.         $code = trim($m[2]);
  689.         $code = str_replace('  ', '&nbsp; ', $code);
  690.         $code = str_replace('  ', ' &nbsp;', $code);
  691.         $code = str_replace("\t", '&nbsp; ', $code);
  692.         $code = str_replace(array('[', ']', ':', ')'), array('&#91;', '&#93;', '&#58;', '&#41;'), $code);
  693.         return $this->tpl['code_open'] . $code . $this->tpl['code_close'];
  694.     }
  695.  
  696.     /**
  697.     * Escape tags inside tiltes in [quote="tilte"]
  698.     */
  699.     function escape_tiltes_callback ($m)
  700.     {
  701.         $tilte = substr($m[3], 0, 250);
  702.         $tilte = str_replace(array('[', ']', ':', ')', '"'), array('&#91;', '&#93;', '&#58;', '&#41;', '&#34;'), $tilte);
  703.         // еще раз htmlspecialchars, т.к. при извлечении из title происходит обратное преобразование
  704.         $tilte = htmlspecialchars($tilte, ENT_QUOTES);
  705.         return $m[1] . $tilte . $m[4];
  706.     }
  707.  
  708.     /**
  709.     * make_clickable
  710.     */
  711.     function make_clickable ($text)
  712.     {
  713.         global $bb_cfg;
  714.  
  715.         $url_regexp = "#
  716.             (?<![\"'=])
  717.             \b
  718.             (
  719.                 https?://[\w\#!$%&~/.\-;:=?@а-яА-Я\[\]+]+
  720.             )
  721.             (?![\"']|\[/url|\[/img|</a)
  722.             (?=[,!]?\s|[\)<!])
  723.         #xiu";
  724.  
  725.         // pad it with a space so we can match things at the start of the 1st line.
  726.         $ret = " $text ";
  727.  
  728.         // hide passkey
  729.         $ret = hide_passkey($ret);
  730.  
  731.         // matches an "xxxx://yyyy" URL at the start of a line, or after a space.
  732.         $ret = preg_replace_callback($url_regexp, array(&$this, 'make_url_clickable_callback'), $ret);
  733.  
  734.         // Remove our padding..
  735.         $ret = substr(substr($ret, 0, -1), 1);
  736.  
  737.         return($ret);
  738.     }
  739.  
  740.     /**
  741.     * make_url_clickable_callback
  742.     */
  743.     function make_url_clickable_callback ($m)
  744.     {
  745.         $max_len = 70;
  746.         $href    = $m[1];
  747.         $name    = (mb_strlen($href, 'UTF-8') > $max_len) ? mb_substr($href, 0, $max_len - 19) .'...'. mb_substr($href, -16) : $href;
  748.  
  749.         return "<a href=\"/redir/?$href\" target='_blank' class=\"postLink\">$name</a>";
  750.     }
  751.  
  752.     /**
  753.     * smilies_pass
  754.     */
  755.     function smilies_pass ($text)
  756.     {
  757.         global $datastore;
  758.  
  759.         if (is_null($this->smilies))
  760.         {
  761.             $this->smilies = $datastore->get('smile_replacements');
  762.         }
  763.         if ($this->smilies)
  764.         {
  765.             $parsed_text = preg_replace($this->smilies['orig'], $this->smilies['repl'], $text, 101, $smilies_cnt);
  766.             $text = ($smilies_cnt <= 100) ? $parsed_text : $text;
  767.         }
  768.  
  769.         return $text;
  770.     }
  771.  
  772.     /**
  773.     * new_line2html
  774.     */
  775.     function new_line2html ($text)
  776.     {
  777.         $text = preg_replace('#\n{2,}#', '<span class="post-br"><br /></span>', $text);
  778.         $text = str_replace("\n", '<br />', $text);
  779.         return $text;
  780.     }
  781.  
  782.     /**
  783.     * tidy
  784.     */
  785.     function tidy ($text)
  786.     {
  787.         if (!function_exists('tidy_repair_string')) die('(see $bb_cfg[\'tidy_post\'] in config.php)');
  788.  
  789.         $text = tidy_repair_string($text, $this->tidy_cfg, 'utf8');
  790.         return $text;
  791.     }
  792. }
  793.  
  794. function bbcode2html ($text)
  795. {
  796.     global $bbcode;
  797.  
  798.     if (!isset($bbcode))
  799.     {
  800.         $bbcode = new bbcode();
  801.     }
  802.     $orig_word = array();
  803.     $replacement_word = array();
  804.     obtain_word_list($orig_word, $replacement_word);
  805.     if ( count($orig_word) )
  806.     {
  807.         $text = preg_replace($orig_word, $replacement_word, $text);
  808.     }
  809.     return $bbcode->bbcode2html($text);
  810. }
  811.  
  812. function strip_bbcode_uid ($text)
  813. {
  814.     $text = str_replace('[tab]',   ' ',     $text);
  815.     $text = str_replace('&quot;',  '"',     $text);
  816.     $text = str_replace('code:1:', 'code:', $text);
  817.     $text = str_replace('list:u:', 'list:', $text);
  818.     $text = str_replace('list:o:', 'list:', $text);
  819.     return $text;
  820. }
  821.  
  822. class words_rate
  823. {
  824.     var $dbg_mode      = false;
  825.     var $words_rate    = 0;
  826.     var $deleted_words = array();
  827.     var $del_text_hl   = '';
  828.     var $words_del_exp = '';
  829.     var $words_cnt_exp = '#[a-zA-Zа-яА-ЯёЁ]{4,}#';
  830.  
  831.     function words_rate ()
  832.     {
  833.         // слова начинающиеся на..
  834.         $del_list = file_get_contents(BB_ROOT .'/misc/words_rate_del_list.txt');
  835.         $del_list = str_compact($del_list);
  836.         $del_list = str_replace(' ', '|', preg_quote($del_list, '/'));
  837.         $del_exp  = '/\b('.$del_list.')[\w\-]*/i';
  838.  
  839.         $this->words_del_exp = $del_exp;
  840.     }
  841.  
  842.     /**
  843.     * возвращает "показатель полезности" сообщения используемый для автоудаления коротких сообщений типа "спасибо", "круто" и т.д.
  844.     */
  845.     function get_words_rate ($text)
  846.     {
  847.         $this->words_rate    = 127;     // максимальное значение по умолчанию
  848.         $this->deleted_words = array();
  849.         $this->del_text_hl   = $text;
  850.  
  851.         // длинное сообщение
  852.         if (strlen($text) > 600)
  853.         {
  854.             return $this->words_rate;
  855.         }
  856.         // вырезаем цитаты если содержит +1
  857.         if (preg_match('#\+\d+#', $text))
  858.         {
  859.             $text = strip_quotes($text);
  860.         }
  861.         // содержит ссылку
  862.         if (strpos($text, '://'))
  863.         {
  864.             return $this->words_rate;
  865.         }
  866.         // вопрос
  867.         if ($questions = preg_match_all('#\w\?+#', $text, $m))
  868.         {
  869.             if ($questions >= 1)
  870.             {
  871.                 return $this->words_rate;
  872.             }
  873.         }
  874.  
  875.         if ($this->dbg_mode)
  876.         {
  877.             preg_match_all($this->words_del_exp, $text, $this->deleted_words);
  878.             $text_dbg = preg_replace($this->words_del_exp, '<span class="del-word">$0</span>', $text);
  879.             $this->del_text_hl = '<div class="prune-post">'. $text_dbg . '</div>';
  880.         }
  881.         $text = preg_replace($this->words_del_exp, '', $text);
  882.  
  883.         // удаление смайлов
  884.         $text = preg_replace('#:\w+:#', '', $text);
  885.         // удаление bbcode тегов
  886.         $text = preg_replace('#\[\S+\]#', '', $text);
  887.  
  888.         $words_count = preg_match_all($this->words_cnt_exp, $text, $m);
  889.  
  890.         if ($words_count !== false && $words_count < 127)
  891.         {
  892.             $this->words_rate = ($words_count == 0) ? 1 : $words_count;
  893.         }
  894.  
  895.         return $this->words_rate;
  896.     }
  897. }
  898.  
  899. function get_words_rate ($text)
  900. {
  901.     static $wr = null;
  902.     if (!isset($wr))
  903.     {
  904.         $wr = new words_rate();
  905.     }
  906.     return $wr->get_words_rate($text);
  907. }
  908.  
  909. function hide_passkey ($str)
  910. {
  911.     global $bb_cfg;
  912.     return preg_replace("#\?{$bb_cfg['passkey_key']}=[a-zA-Z0-9]{". BT_AUTH_KEY_LENGTH ."}#", "?{$bb_cfg['passkey_key']}=passkey", $str);
  913. }
  914.  
  915. function get_parsed_post ($postrow, $mode = 'full', $return_chars = 600)
  916. {
  917.     global $bb_cfg;
  918.  
  919.     if ($bb_cfg['use_posts_cache'] && !empty($postrow['post_html']))
  920.     {
  921.         return $postrow['post_html'];
  922.     }
  923.  
  924.     $message = bbcode2html($postrow['post_text']);
  925.  
  926.     // Posts cache
  927.     if ($bb_cfg['use_posts_cache'])
  928.     {
  929.         DB()->shutdown['post_html'][] = array(
  930.             'post_id'   => (int) $postrow['post_id'],
  931.             'post_html' => (string) $message,
  932.         );
  933.     }
  934.  
  935.     return $message;
  936. }
  937.  
  938. function update_post_html ($postrow)
  939. {
  940.     DB()->query("DELETE FROM ". BB_POSTS_HTML ." WHERE post_id = ". (int) $postrow['post_id'] ." LIMIT 1");
  941. }
Advertisement
Add Comment
Please, Sign In to add comment