Просмотр файла includes/bbcode.php

Размер файла: 15.39Kb
  1. <?php
  2. /***************************************************************************
  3. * mides.ru
  4. * -------------------
  5. ***************************************************************************/
  6. if ( !defined('IN_PHPBB') )
  7. {
  8. die("Hacking attempt");
  9. }
  10.  
  11. define("BBCODE_UID_LEN", 10);
  12.  
  13. $bbcode_tpl = null;
  14.  
  15. function load_bbcode_template()
  16. {
  17. global $template;
  18. $tpl_filename = $template->make_filename('bbcode.tpl');
  19. $tpl = fread(fopen($tpl_filename, 'r'), filesize($tpl_filename));
  20. $tpl = str_replace('\\', '\\\\', $tpl);
  21. $tpl = str_replace('\'', '\\\'', $tpl);
  22. $tpl = str_replace("\n", '', $tpl);
  23. $tpl = preg_replace('#<!-- BEGIN (.*?) -->(.*?)<!-- END (.*?) -->#', "\n" . '$bbcode_tpls[\'\\1\'] = \'\\2\';', $tpl);
  24.  
  25. $bbcode_tpls = array();
  26.  
  27. eval($tpl);
  28.  
  29. return $bbcode_tpls;
  30. }
  31.  
  32. function prepare_bbcode_template($bbcode_tpl)
  33. {
  34. global $lang;
  35.  
  36. $bbcode_tpl['olist_open'] = str_replace('{LIST_TYPE}', '\\1', $bbcode_tpl['olist_open']);
  37.  
  38. $bbcode_tpl['color_open'] = str_replace('{COLOR}', '\\1', $bbcode_tpl['color_open']);
  39.  
  40. $bbcode_tpl['size_open'] = str_replace('{SIZE}', '\\1', $bbcode_tpl['size_open']);
  41.  
  42. $bbcode_tpl['quote_open'] = str_replace('{L_QUOTE}', '<div class="q">', $bbcode_tpl['quote_open']);
  43.  
  44. $bbcode_tpl['quote_username_open'] = str_replace('{L_QUOTE}', $lang['Quote'], $bbcode_tpl['quote_username_open']);
  45. $bbcode_tpl['quote_username_open'] = str_replace('{L_WROTE}', $lang['wrote'], $bbcode_tpl['quote_username_open']);
  46. $bbcode_tpl['quote_username_open'] = str_replace('{USERNAME}', '\\1', $bbcode_tpl['quote_username_open']);
  47.  
  48. $bbcode_tpl['code_open'] = str_replace('{L_CODE}', '<div class="d">', $bbcode_tpl['code_open']);
  49.  
  50. $bbcode_tpl['img'] = str_replace('{URL}', '\\1', $bbcode_tpl['img']);
  51.  
  52. $bbcode_tpl['url1'] = str_replace('{URL}', '\\1', $bbcode_tpl['url']);
  53. $bbcode_tpl['url1'] = str_replace('{DESCRIPTION}', '\\1', $bbcode_tpl['url1']);
  54.  
  55. $bbcode_tpl['url2'] = str_replace('{URL}', 'http://\\1', $bbcode_tpl['url']);
  56. $bbcode_tpl['url2'] = str_replace('{DESCRIPTION}', '\\1', $bbcode_tpl['url2']);
  57.  
  58. $bbcode_tpl['url3'] = str_replace('{URL}', '\\1', $bbcode_tpl['url']);
  59. $bbcode_tpl['url3'] = str_replace('{DESCRIPTION}', '\\2', $bbcode_tpl['url3']);
  60.  
  61. $bbcode_tpl['url4'] = str_replace('{URL}', 'http://\\1', $bbcode_tpl['url']);
  62. $bbcode_tpl['url4'] = str_replace('{DESCRIPTION}', '\\3', $bbcode_tpl['url4']);
  63.  
  64. $bbcode_tpl['email'] = str_replace('{EMAIL}', '\\1', $bbcode_tpl['email']);
  65.  
  66. define("BBCODE_TPL_READY", true);
  67.  
  68. return $bbcode_tpl;
  69. }
  70.  
  71. function bbencode_second_pass($text, $uid)
  72. {
  73. global $lang, $bbcode_tpl;
  74.  
  75. $text = preg_replace('#(script|about|applet|activex|chrome):#is', "\\1&#058;", $text);
  76. $text = " " . $text;
  77.  
  78. if (! (strpos($text, "[") && strpos($text, "]")) )
  79. {
  80. // Remove padding, return.
  81. $text = substr($text, 1);
  82. return $text;
  83. }
  84.  
  85. if (!defined("BBCODE_TPL_READY"))
  86. {
  87. $bbcode_tpl = load_bbcode_template();
  88. $bbcode_tpl = prepare_bbcode_template($bbcode_tpl);
  89. }
  90.  
  91. $text = bbencode_second_pass_code($text, $uid, $bbcode_tpl);
  92. $text = str_replace("[quote:$uid]", $bbcode_tpl['quote_open'], $text);
  93. $text = str_replace("[/quote:$uid]", $bbcode_tpl['quote_close'], $text);
  94. $text = preg_replace("/\[quote:$uid=\"(.*?)\"\]/si", $bbcode_tpl['quote_username_open'], $text);
  95. $text = str_replace("[list:$uid]", $bbcode_tpl['ulist_open'], $text);
  96. $text = str_replace("[*:$uid]", $bbcode_tpl['listitem'], $text);
  97. $text = str_replace("[/list:u:$uid]", $bbcode_tpl['ulist_close'], $text);
  98. $text = str_replace("[/list:o:$uid]", $bbcode_tpl['olist_close'], $text);
  99. $text = preg_replace("/\[list=([a1]):$uid\]/si", $bbcode_tpl['olist_open'], $text);
  100. $text = preg_replace("/\[color=(\#[0-9A-F]{6}|[a-z]+):$uid\]/si", $bbcode_tpl['color_open'], $text);
  101. $text = str_replace("[/color:$uid]", $bbcode_tpl['color_close'], $text);
  102. $text = preg_replace("/\[size=([1-2]?[0-9]):$uid\]/si", $bbcode_tpl['size_open'], $text);
  103. $text = str_replace("[/size:$uid]", $bbcode_tpl['size_close'], $text);
  104. $text = str_replace("[b:$uid]", $bbcode_tpl['b_open'], $text);
  105. $text = str_replace("[/b:$uid]", $bbcode_tpl['b_close'], $text);
  106. $text = str_replace("[u:$uid]", $bbcode_tpl['u_open'], $text);
  107. $text = str_replace("[/u:$uid]", $bbcode_tpl['u_close'], $text);
  108. $text = str_replace("[i:$uid]", $bbcode_tpl['i_open'], $text);
  109. $text = str_replace("[/i:$uid]", $bbcode_tpl['i_close'], $text);
  110.  
  111. $patterns = array();
  112. $replacements = array();
  113.  
  114. $patterns[] = "#\[img:$uid\]([^?](?:[^\[]+|\[(?!url))*?)\[/img:$uid\]#i";
  115. $replacements[] = $bbcode_tpl['img'];
  116.  
  117. $patterns[] = "#\[url\]([\w]+?://([\w\#$%&~/.\-;:=,?@\]+]+|\[(?!url=))*?)\[/url\]#is";
  118. $replacements[] = $bbcode_tpl['url1'];
  119.  
  120. $patterns[] = "#\[url\]((www|ftp)\.([\w\#$%&~/.\-;:=,?@\]+]+|\[(?!url=))*?)\[/url\]#is";
  121. $replacements[] = $bbcode_tpl['url2'];
  122.  
  123. $patterns[] = "#\[url=([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*?)\]([^?\n\r\t].*?)\[/url\]#is";
  124. $replacements[] = $bbcode_tpl['url3'];
  125.  
  126. $patterns[] = "#\[url=((www|ftp)\.[\w\#$%&~/.\-;:=,?@\[\]+]*?)\]([^?\n\r\t].*?)\[/url\]#is";
  127. $replacements[] = $bbcode_tpl['url4'];
  128.  
  129. $patterns[] = "#\[email\]([a-z0-9&\-_.]+?@[\w\-]+\.([\w\-\.]+\.)?[\w]+)\[/email\]#si";
  130. $replacements[] = $bbcode_tpl['email'];
  131.  
  132. $text = preg_replace($patterns, $replacements, $text);
  133. $text = substr($text, 1);
  134.  
  135. return $text;
  136.  
  137. }
  138.  
  139. mt_srand( (double) microtime() * 1000000);
  140.  
  141. function make_bbcode_uid()
  142. {
  143. $uid = dss_rand();
  144. $uid = substr($uid, 0, BBCODE_UID_LEN);
  145.  
  146. return $uid;
  147. }
  148.  
  149. function bbencode_first_pass($text, $uid)
  150. {
  151. $text = " " . $text;
  152. $text = bbencode_first_pass_pda($text, $uid, '[code]', '[/code]', '', true, '');
  153. $text = bbencode_first_pass_pda($text, $uid, '[quote]', '[/quote]', '', false, '');
  154. $text = bbencode_first_pass_pda($text, $uid, '/\[quote=\\\\&quot;(.*?)\\\\&quot;\]/is', '[/quote]', '', false, '', "[quote:$uid=\\\"\\1\\\"]");
  155.  
  156. $open_tag = array();
  157. $open_tag[0] = "[list]";
  158.  
  159. $text = bbencode_first_pass_pda($text, $uid, $open_tag, "[/list]", "[/list:u]", false, 'replace_listitems');
  160.  
  161. $open_tag[0] = "[list=1]";
  162. $open_tag[1] = "[list=a]";
  163.  
  164. $text = bbencode_first_pass_pda($text, $uid, $open_tag, "[/list]", "[/list:o]", false, 'replace_listitems');
  165. $text = preg_replace("#\[color=(\#[0-9A-F]{6}|[a-z\-]+)\](.*?)\[/color\]#si", "[color=\\1:$uid]\\2[/color:$uid]", $text);
  166. $text = preg_replace("#\[size=([1-2]?[0-9])\](.*?)\[/size\]#si", "[size=\\1:$uid]\\2[/size:$uid]", $text);
  167. $text = preg_replace("#\[b\](.*?)\[/b\]#si", "[b:$uid]\\1[/b:$uid]", $text);
  168. $text = preg_replace("#\[u\](.*?)\[/u\]#si", "[u:$uid]\\1[/u:$uid]", $text);
  169. $text = preg_replace("#\[i\](.*?)\[/i\]#si", "[i:$uid]\\1[/i:$uid]", $text);
  170. $text = preg_replace("#\[img\]((http|ftp|https|ftps)://)([^ \?&=\#\"\n\r\t<]*?(\.(jpg|jpeg|gif|png)))\[/img\]#sie", "'[img:$uid]\\1' . str_replace(' ', '%20', '\\3') . '[/img:$uid]'", $text);
  171.  
  172. return substr($text, 1);;
  173.  
  174. }
  175.  
  176. function bbencode_first_pass_pda($text, $uid, $open_tag, $close_tag, $close_tag_new, $mark_lowest_level, $func, $open_regexp_replace = false)
  177. {
  178. $open_tag_count = 0;
  179.  
  180. if (!$close_tag_new || ($close_tag_new == ''))
  181. {
  182. $close_tag_new = $close_tag;
  183. }
  184.  
  185. $close_tag_length = strlen($close_tag);
  186. $close_tag_new_length = strlen($close_tag_new);
  187. $uid_length = strlen($uid);
  188.  
  189. $use_function_pointer = ($func && ($func != ''));
  190.  
  191. $stack = array();
  192.  
  193. if (is_array($open_tag))
  194. {
  195. if (0 == count($open_tag))
  196. {
  197. return $text;
  198. }
  199. $open_tag_count = count($open_tag);
  200. }
  201. else
  202. {
  203. $open_tag_temp = $open_tag;
  204. $open_tag = array();
  205. $open_tag[0] = $open_tag_temp;
  206. $open_tag_count = 1;
  207. }
  208.  
  209. $open_is_regexp = false;
  210.  
  211. if ($open_regexp_replace)
  212. {
  213. $open_is_regexp = true;
  214. if (!is_array($open_regexp_replace))
  215. {
  216. $open_regexp_temp = $open_regexp_replace;
  217. $open_regexp_replace = array();
  218. $open_regexp_replace[0] = $open_regexp_temp;
  219. }
  220. }
  221.  
  222. if ($mark_lowest_level && $open_is_regexp)
  223. {
  224. message_die(GENERAL_ERROR, "Unsupported operation for bbcode_first_pass_pda().");
  225. }
  226.  
  227. $curr_pos = 1;
  228. while ($curr_pos && ($curr_pos < strlen($text)))
  229. {
  230. $curr_pos = strpos($text, "[", $curr_pos);
  231.  
  232. if ($curr_pos)
  233. {
  234. $found_start = false;
  235. $which_start_tag = "";
  236. $start_tag_index = -1;
  237.  
  238. for ($i = 0; $i < $open_tag_count; $i++)
  239. {
  240. $possible_start = substr($text, $curr_pos, strpos($text, ']', $curr_pos + 1) - $curr_pos + 1);
  241.  
  242. if( preg_match('#\[quote=\\\&quot;#si', $possible_start, $match) && !preg_match('#\[quote=\\\&quot;(.*?)\\\&quot;\]#si', $possible_start) )
  243. {
  244. if ($close_pos = strpos($text, '&quot;]', $curr_pos + 14))
  245. {
  246. if (strpos(substr($text, $curr_pos + 14, $close_pos - ($curr_pos + 14)), '[quote') === false)
  247. {
  248. $possible_start = substr($text, $curr_pos, $close_pos - $curr_pos + 7);
  249. }
  250. }
  251. }
  252.  
  253. if ($open_is_regexp)
  254. {
  255. $match_result = array();
  256. if (preg_match($open_tag[$i], $possible_start, $match_result))
  257. {
  258. $found_start = true;
  259. $which_start_tag = $match_result[0];
  260. $start_tag_index = $i;
  261. break;
  262. }
  263. }
  264. else
  265. {
  266. if (0 == strcasecmp($open_tag[$i], $possible_start))
  267. {
  268. $found_start = true;
  269. $which_start_tag = $open_tag[$i];
  270. $start_tag_index = $i;
  271. break;
  272. }
  273. }
  274. }
  275.  
  276. if ($found_start)
  277. {
  278. $match = array("pos" => $curr_pos, "tag" => $which_start_tag, "index" => $start_tag_index);
  279. array_push($stack, $match);
  280. $curr_pos += strlen($possible_start);
  281. }
  282. else
  283. {
  284. $possible_end = substr($text, $curr_pos, $close_tag_length);
  285. if (0 == strcasecmp($close_tag, $possible_end))
  286. {
  287. if (sizeof($stack) > 0)
  288. {
  289. $curr_nesting_depth = sizeof($stack);
  290. $match = array_pop($stack);
  291. $start_index = $match['pos'];
  292. $start_tag = $match['tag'];
  293. $start_length = strlen($start_tag);
  294. $start_tag_index = $match['index'];
  295.  
  296. if ($open_is_regexp)
  297. {
  298. $start_tag = preg_replace($open_tag[$start_tag_index], $open_regexp_replace[$start_tag_index], $start_tag);
  299. }
  300.  
  301. $before_start_tag = substr($text, 0, $start_index);
  302. $between_tags = substr($text, $start_index + $start_length, $curr_pos - $start_index - $start_length);
  303.  
  304. if ($use_function_pointer)
  305. {
  306. $between_tags = $func($between_tags, $uid);
  307. }
  308.  
  309. $after_end_tag = substr($text, $curr_pos + $close_tag_length);
  310.  
  311. if ($mark_lowest_level && ($curr_nesting_depth == 1))
  312. {
  313. if ($open_tag[0] == '[code]')
  314. {
  315. $code_entities_match = array('#<#', '#>#', '#"#', '#:#', '#\[#', '#\]#', '#\(#', '#\)#', '#\{#', '#\}#');
  316. $code_entities_replace = array('&lt;', '&gt;', '&quot;', '&#58;', '&#91;', '&#93;', '&#40;', '&#41;', '&#123;', '&#125;');
  317. $between_tags = preg_replace($code_entities_match, $code_entities_replace, $between_tags);
  318. }
  319. $text = $before_start_tag . substr($start_tag, 0, $start_length - 1) . ":$curr_nesting_depth:$uid]";
  320. $text .= $between_tags . substr($close_tag_new, 0, $close_tag_new_length - 1) . ":$curr_nesting_depth:$uid]";
  321. }
  322. else
  323. {
  324. if ($open_tag[0] == '[code]')
  325. {
  326. $text = $before_start_tag . '&#91;code&#93;';
  327. $text .= $between_tags . '&#91;/code&#93;';
  328. }
  329. else
  330. {
  331. if ($open_is_regexp)
  332. {
  333. $text = $before_start_tag . $start_tag;
  334. }
  335. else
  336. {
  337. $text = $before_start_tag . substr($start_tag, 0, $start_length - 1) . ":$uid]";
  338. }
  339. $text .= $between_tags . substr($close_tag_new, 0, $close_tag_new_length - 1) . ":$uid]";
  340. }
  341. }
  342.  
  343. $text .= $after_end_tag;
  344.  
  345. if (sizeof($stack) > 0)
  346. {
  347. $match = array_pop($stack);
  348. $curr_pos = $match['pos'];
  349. }
  350. else
  351. {
  352. $curr_pos = 1;
  353. }
  354. }
  355. else
  356. {
  357. ++$curr_pos;
  358. }
  359. }
  360. else
  361. {
  362. ++$curr_pos;
  363. }
  364. }
  365. }
  366. }
  367.  
  368. return $text;
  369.  
  370. }
  371.  
  372. function bbencode_second_pass_code($text, $uid, $bbcode_tpl)
  373. {
  374. global $lang;
  375.  
  376. $code_start_html = $bbcode_tpl['code_open'];
  377. $code_end_html = $bbcode_tpl['code_close'];
  378. $match_count = preg_match_all("#\[code:1:$uid\](.*?)\[/code:1:$uid\]#si", $text, $matches);
  379.  
  380. for ($i = 0; $i < $match_count; $i++)
  381. {
  382. $before_replace = $matches[1][$i];
  383. $after_replace = $matches[1][$i];
  384. $after_replace = str_replace(" ", "&nbsp; ", $after_replace);
  385. $after_replace = str_replace(" ", " &nbsp;", $after_replace);
  386. $after_replace = str_replace("\t", "&nbsp; &nbsp;", $after_replace);
  387. $after_replace = preg_replace("/^ {1}/m", '&nbsp;', $after_replace);
  388.  
  389. $str_to_match = "[code:1:$uid]" . $before_replace . "[/code:1:$uid]";
  390.  
  391. $replacement = $code_start_html;
  392. $replacement .= $after_replace;
  393. $replacement .= $code_end_html;
  394.  
  395. $text = str_replace($str_to_match, $replacement, $text);
  396. }
  397.  
  398. $text = str_replace("[code:$uid]", $code_start_html, $text);
  399. $text = str_replace("[/code:$uid]", $code_end_html, $text);
  400.  
  401. return $text;
  402.  
  403. }
  404.  
  405. function make_clickable($text)
  406. {
  407. $text = preg_replace('#(script|about|applet|activex|chrome):#is', "\\1&#058;", $text);
  408.  
  409. $ret = ' ' . $text;
  410. $ret = preg_replace("#(^|[\n ])([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*)#is", "\\1<a href=\"\\2\" target=\"_blank\">\\2</a>", $ret);
  411. $ret = preg_replace("#(^|[\n ])((www|ftp)\.[\w\#$%&~/.\-;:=,?@\[\]+]*)#is", "\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a>", $ret);
  412. $ret = preg_replace("#(^|[\n ])([a-z0-9&\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)#i", "\\1<a href=\"mailto:\\2@\\3\">\\2@\\3</a>", $ret);
  413. $ret = substr($ret, 1);
  414.  
  415. return($ret);
  416. }
  417.  
  418. function undo_make_clickable($text)
  419. {
  420. $text = preg_replace("#<!-- BBCode auto-link start --><a href=\"(.*?)\" target=\"_blank\">.*?</a><!-- BBCode auto-link end -->#i", "\\1", $text);
  421. $text = preg_replace("#<!-- BBcode auto-mailto start --><a href=\"mailto:(.*?)\">.*?</a><!-- BBCode auto-mailto end -->#i", "\\1", $text);
  422.  
  423. return $text;
  424.  
  425. }
  426.  
  427. function undo_htmlspecialchars($input)
  428. {
  429. $input = preg_replace("/&gt;/i", ">", $input);
  430. $input = preg_replace("/&lt;/i", "<", $input);
  431. $input = preg_replace("/&quot;/i", "\"", $input);
  432. $input = preg_replace("/&amp;/i", "&", $input);
  433.  
  434. return $input;
  435. }
  436.  
  437. function replace_listitems($text, $uid)
  438. {
  439. $text = str_replace("[*]", "[*:$uid]", $text);
  440.  
  441. return $text;
  442. }
  443.  
  444. function escape_slashes($input)
  445. {
  446. $output = str_replace('/', '\/', $input);
  447. return $output;
  448. }
  449.  
  450. function bbcode_array_push(&$stack, $value)
  451. {
  452. $stack[] = $value;
  453. return(sizeof($stack));
  454. }
  455.  
  456. function bbcode_array_pop(&$stack)
  457. {
  458. $arrSize = count($stack);
  459. $x = 1;
  460.  
  461. while(list($key, $val) = each($stack))
  462. {
  463. if($x < count($stack))
  464. {
  465. $tmpArr[] = $val;
  466. }
  467. else
  468. {
  469. $return_val = $val;
  470. }
  471. $x++;
  472. }
  473.  
  474. $stack = $tmpArr;
  475.  
  476. return($return_val);
  477. }
  478.  
  479. function smilies_pass($message)
  480. {
  481. static $orig, $repl;
  482.  
  483. if (!isset($orig))
  484. {
  485. global $db, $board_config;
  486. $orig = $repl = array();
  487.  
  488. $sql = 'SELECT * FROM ' . SMILIES_TABLE;
  489. if( !$result = $db->sql_query($sql) )
  490. {
  491. message_die(GENERAL_ERROR, "Couldn't obtain smilies data", "", __LINE__, __FILE__, $sql);
  492. }
  493. $smilies = $db->sql_fetchrowset($result);
  494.  
  495. if (count($smilies))
  496. {
  497. usort($smilies, 'smiley_sort');
  498. }
  499.  
  500. for ($i = 0; $i < count($smilies); $i++)
  501. {
  502. $orig[] = "/(?<=.\W|\W.|^\W)" . preg_quote($smilies[$i]['code'], "/") . "(?=.\W|\W.|\W$)/";
  503. $repl[] = '<img src="'. $board_config['smilies_path'] . '/' . $smilies[$i]['smile_url'] . '" alt="' . $smilies[$i]['emoticon'] . '" border="0" />';
  504. }
  505. }
  506.  
  507. if (count($orig))
  508. {
  509. $message = preg_replace($orig, $repl, ' ' . $message . ' ');
  510. $message = substr($message, 1, -1);
  511. }
  512. return $message;
  513. }
  514.  
  515. function smiley_sort($a, $b)
  516. {
  517. if ( strlen($a['code']) == strlen($b['code']) )
  518. {
  519. return 0;
  520. }
  521.  
  522. return ( strlen($a['code']) > strlen($b['code']) ) ? -1 : 1;
  523. }
  524.  
  525. ?>