L
ler
Гость
Посоветуйте как правильно сделать?
vietopic.php
bbcode.php
Класс bbcode из bbcode.php
PHP:
else if ($user_sig)
{
$user_sig = bbcode2html($user_sig);
}
bbcode.php
PHP:
function bbcode2html ($text)
{
global $bbcode;
if (!isset($bbcode))
{
$bbcode = new bbcode();
}
$orig_word = array();
$replacement_word = array();
obtain_word_list($orig_word, $replacement_word);
if ( count($orig_word) )
{
$text = preg_replace($orig_word, $replacement_word, $text);
}
return $bbcode->bbcode2html($text);
}
Класс bbcode из bbcode.php
PHP:
class bbcode
{
var $tpl = array(); // шаблоны для замены тегов
var $smilies = null; // смайлы
var $found_spam = null; // найденные спам "слова"
var $del_words = array(); // см. get_words_rate()
var $tidy_cfg = array(
'drop-empty-paras' => false,
'fix-uri' => false,
'force-output' => true,
'hide-comments' => true,
'join-classes' => false,
'join-styles' => false,
'merge-divs' => false,
'merge-spans' => false,
'newline' => 'LF',
'output-xhtml' => true,
'preserve-entities' => true,
'quiet' => true,
'quote-ampersand' => false,
'show-body-only' => true,
'show-errors' => false,
'show-warnings' => false,
'wrap' => 0,
);
var $block_tags = array(
'align',
'br',
'clear',
'hr',
'list',
'pre',
'quote',
'spoiler',
);
var $preg = array();
var $str = array();
var $preg_search = array();
var $preg_repl = array();
var $str_search = array();
var $str_repl = array();
/**
* Constructor
*/
function bbcode ()
{
$this->tpl = get_bbcode_tpl();
$this->init_replacements();
}
/**
* init_replacements
*/
function init_replacements ()
{
$tpl = $this->tpl;
$img_url_exp = 'http://[^\s\?&;=\#\"<>]+?\.(jpg|jpeg|gif|png|gif\?graph\=yes|gif\?period\=week\;graph\=yes)';
$email_exp = '[a-z0-9&\-_.]+?@[\w\-]+\.([\w\-\.]+\.)?[\w]+';
$url_exp = '[\w\#!$%&_\)\(~/.\-;:=,?@а-яА-Яa-zA-Z0-9\[\]+]+?';
$this->preg = array(
'#\[kp\](.+?)\[/kp\]#isu' => '<a href="http://www.kinopoisk.ru/level/1/film/$1"><img src="./ratings/kinopoisk.php?url=http://www.kinopoisk.ru/level/1/film/$1" ></a>',
"#\[youtube\]http://(?:www\.)?youtube.com/watch\?v=([0-9A-Za-z-_]{11})[^[]*\[/youtube\]#is" => $tpl['youtube'],
"#\[youtube\]http://(?:www\.)?youtube.com/v/([0-9A-Za-z-_]{11})[^[]*\[/youtube\]#is" => $tpl['youtube'],
"#\[youtube\]([a-zA-Z0-9_]+)\[/youtube\]#is" => $tpl['youtube'],
'#\[quote="(.+?)"\]#isu' => $tpl['quote_username_open'],
'#\[imdb\](.+?)\[/imdb\]#isu' => '<a href="http://www.imdb.com/title/$1/"><img src="imdb.php?id=$1" ></a>',
'#\[spoiler="(.+?)"\]#isu' => $tpl['spoiler_title_open'],
'#\[list=(a|A|i|I|1)\]#isu' => '<ul type="$1">',
'#\[\*=(\d+)\]#isu' => '<li value="$1">',
'#\[pre\](.*?)\[/pre\]#isu' => '<pre class="post-pre">$1</pre>',
'#\[name=([a-zA-Z0-9_]+?)\]#isu' => '<a name="$1"></a>',
'#\[url=\#([a-zA-Z0-9_\)\(]+?)\](.*?)\[/url\]#isu' => '<a class="postLink-name" href="#$1">$2</a>',
'#\[color=([\#0-9a-zA-Z]+)\]#isu' => '<span style="color: $1;">',
'#\[size=([1-2]?[0-9])\]#isu' => '<span style="font-size: $1px; line-height: normal;">',
'#\[h2\]#isu' => '<h2>',
'#\[align=(left|right|center|justify)\]#isu' => '<span class="post-align" style="text-align: $1;">',
'#\[font="([\w\- \']+)"\]#isu' => '<span style="font-family: $1;">',
'#\[thumbnails\]($img_url_exp)\[/thumbnails\]\s*#i' => $tpl['thumbnails'],
"#\[img\]($img_url_exp)\[/img\]#isu" => $tpl['img'],
"#\[img=(left|right)\]($img_url_exp)\[/img\]\s*#isu" => $tpl['img_aligned'],
"#\[url\](https?://$url_exp)\[/url\]#isu" => '<a href="$1" class="postLink">$1</a>',
"#\[url\](www\.$url_exp)\[/url\]#isu" => '<a href="http://$1" class="postLink">$1</a>',
"#\[url=(https?://$url_exp)\]([^?\n\t].*?)\[/url\]#isu" => '<a href="$1" class="postLink">$2</a>',
"#\[url=(www\.$url_exp)\]([^?\n\t].*?)\[/url\]#isu" => '<a href="http://$1" class="postLink">$2</a>',
"#\[email\]($email_exp)\[/email\]#isu" => '<a href="mailto:$1">$1</a>',
);
$this->str = array(
'[quote]' => $tpl['quote_open'],
'[/quote]' => $tpl['quote_close'],
'[spoiler]' => $tpl['spoiler_open'],
'[/spoiler]' => $tpl['spoiler_close'],
'[list]' => '<ul>',
'[*]' => '<li>',
'[/list]' => '</ul>',
'[/color]' => '</span>',
'[/size]' => '</span>',
'[/h2]' => '</h2>',
'[/align]' => '</span>',
'[/font]' => '</span>',
'[tab]' => ' ',
'[br]' => "\n\n",
'[hr]' => $tpl['hr'],
'[b]' => '<span class="post-b">',
'[/b]' => '</span>',
'[u]' => '<span class="post-u">',
'[/u]' => '</span>',
'[i]' => '<span class="post-i">',
'[/i]' => '</span>',
'[s]' => '<span class="post-s">',
'[/s]' => '</span>',
'[sh]' => '<span class="post-sh">',
'[/sh]' => '</span>',
'[del]' => '<span class="post-s">',
'[/del]' => '</span>',
'[clear]' => '<div class="clear"> </div>',
);
$this->preg_search = array_keys($this->preg);
$this->preg_repl = array_values($this->preg);
$this->str_search = array_keys($this->str);
$this->str_repl = array_values($this->str);
}
/**
* bbcode2html
* $text должен быть уже обработан htmlCHR($text, false, ENT_NOQUOTES);
*/
function bbcode2html ($text)
{
global $bb_cfg;
$text = " $text ";
$text = $this->clean_up($text);
$text = $this->spam_filter($text);
// парсинг тегов
if (strpos($text, '[') !== false)
{
// [CODE]
$text = preg_replace_callback('#(\s*)\[code\](.+?)\[/code\](\s*)#s', array(&$this, 'code_callback'), $text);
// Escape tags inside tiltes in [quote="tilte"]
$text = preg_replace_callback('#(\[(quote|spoiler)=")(.+?)("\])#', array(&$this, 'escape_tiltes_callback'), $text);
// Normalize block level tags wrapped with new lines
$block_tags = join('|', $this->block_tags);
$text = str_replace("\n\n[hr]\n\n", '[br][hr][br]', $text);
$text = preg_replace("#(\s*)(\[/?($block_tags)(.*?)\])(\s*)#", '$2', $text);
// Tag replacements
$text = preg_replace($this->preg_search, $this->preg_repl, $text);
$text = str_replace($this->str_search, $this->str_repl, $text);
}
$text = $this->make_clickable($text);
$text = $this->smilies_pass($text);
$text = $this->new_line2html($text);
$text = trim($text);
if ($bb_cfg['tidy_post'])
{
$text = $this->tidy($text);
}
return trim($text);
}
/**
* Clean up
*/
static function clean_up ($text)
{
$text = trim($text);
$text = str_replace("\r", '', $text);
$text = preg_replace('#[ \t]+$#m', '', $text); // trailing spaces
$text = preg_replace('#\n{3,}#', "\n\n", $text);
return $text;
}
/**
* Spam filter
*/
static function spam_filter ($text)
{
global $bb_cfg;
static $spam_words = null;
static $spam_replace = ' СПАМ';
if (isset($this))
{
$found_spam =& $this->found_spam;
}
// set $spam_words and $spam_replace
if (!$bb_cfg['spam_filter_file_path'])
{
return $text;
}
if (is_null($spam_words))
{
$spam_words = file_get_contents($bb_cfg['spam_filter_file_path']);
$spam_words = strtolower($spam_words);
$spam_words = explode("\n", $spam_words);
}
$found_spam = array();
$tm_start = utime();
$msg_decoded = $text;
$msg_decoded = html_entity_decode($msg_decoded);
$msg_decoded = urldecode($msg_decoded);
$msg_decoded = str_replace('&', ' &', $msg_decoded);
$msg_search = strtolower($msg_decoded);
foreach ($spam_words as $spam_str)
{
if (!$spam_str = trim($spam_str))
{
continue;
}
if (strpos($msg_search, $spam_str) !== false)
{
$found_spam[] = $spam_str;
}
}
if ($found_spam)
{
$spam_exp = array();
foreach ($found_spam as $keyword)
{
$spam_exp[] = preg_quote($keyword, '/');
}
$spam_exp = join('|', $spam_exp);
$text = preg_replace("/($spam_exp)(\S*)/i", $spam_replace, $msg_decoded);
$text = htmlCHR($text, false, ENT_NOQUOTES);
# bb_log(date("H:i:s") ." | ". sprintf('%.4f', (utime() - $tm_start)) ." | ". sprintf('%-6s', strlen($text)) ." | ". join(' ** ', $found_spam) ."\n", 'spam_filter');
}
return $text;
}
/**
* [code] callback
*/
function code_callback ($m)
{
$code = trim($m[2]);
$code = str_replace(' ', ' ', $code);
$code = str_replace(' ', ' ', $code);
$code = str_replace("\t", ' ', $code);
$code = str_replace(array('[', ']', ':', ')'), array('[', ']', ':', ')'), $code);
return $this->tpl['code_open'] . $code . $this->tpl['code_close'];
}
/**
* Escape tags inside tiltes in [quote="tilte"]
*/
function escape_tiltes_callback ($m)
{
$tilte = substr($m[3], 0, 250);
$tilte = str_replace(array('[', ']', ':', ')', '"'), array('[', ']', ':', ')', '"'), $tilte);
// еще раз htmlspecialchars, т.к. при извлечении из title происходит обратное преобразование
$tilte = htmlspecialchars($tilte, ENT_QUOTES);
return $m[1] . $tilte . $m[4];
}
/**
* make_clickable
*/
function make_clickable ($text)
{
global $bb_cfg;
$url_regexp = "#
(?<![\"'=])
\b
(
https?://[\w\#!$%&~/.\-;:=?@а-яА-Я\[\]+]+
)
(?![\"']|\[/url|\[/img|</a)
(?=[,!]?\s|[\)<!])
#xiu";
// pad it with a space so we can match things at the start of the 1st line.
$ret = " $text ";
// hide passkey
$ret = hide_passkey($ret);
// matches an "xxxx://yyyy" URL at the start of a line, or after a space.
$ret = preg_replace_callback($url_regexp, array(&$this, 'make_url_clickable_callback'), $ret);
// Remove our padding..
$ret = substr(substr($ret, 0, -1), 1);
return($ret);
}
/**
* make_url_clickable_callback
*/
function make_url_clickable_callback ($m)
{
$max_len = 70;
$href = $m[1];
$name = (mb_strlen($href, 'UTF-8') > $max_len) ? mb_substr($href, 0, $max_len - 19) .'...'. mb_substr($href, -16) : $href;
return "<a href=\"$href\" class=\"postLink\">$name</a>";
}
/**
* smilies_pass
*/
function smilies_pass ($text)
{
global $datastore;
if (is_null($this->smilies))
{
$this->smilies = $datastore->get('smile_replacements');
}
if ($this->smilies)
{
$parsed_text = preg_replace($this->smilies['orig'], $this->smilies['repl'], $text, 101, $smilies_cnt);
$text = ($smilies_cnt <= 100) ? $parsed_text : $text;
}
return $text;
}
/**
* new_line2html
*/
function new_line2html ($text)
{
$text = preg_replace('#\n{2,}#', '<span class="post-br"><br /></span>', $text);
$text = str_replace("\n", '<br />', $text);
return $text;
}
/**
* tidy
*/
function tidy ($text)
{
if (!function_exists('tidy_repair_string')) die('(see $bb_cfg[\'tidy_post\'] in config.php)');
$text = tidy_repair_string($text, $this->tidy_cfg, 'utf8');
return $text;
}
}