PageRenderTime 57ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/phpBB/includes/bbcode.php

http://github.com/phpbb/phpbb3
PHP | 705 lines | 518 code | 82 blank | 105 comment | 61 complexity | caa9f2c9a3426c3c0336908174431d72 MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. *
  4. * This file is part of the phpBB Forum Software package.
  5. *
  6. * @copyright (c) phpBB Limited <https://www.phpbb.com>
  7. * @license GNU General Public License, version 2 (GPL-2.0)
  8. *
  9. * For full copyright and license information, please see
  10. * the docs/CREDITS.txt file.
  11. *
  12. */
  13. /**
  14. * @ignore
  15. */
  16. if (!defined('IN_PHPBB'))
  17. {
  18. exit;
  19. }
  20. /**
  21. * BBCode class
  22. */
  23. class bbcode
  24. {
  25. var $bbcode_uid = '';
  26. var $bbcode_bitfield = '';
  27. var $bbcode_cache = array();
  28. var $bbcode_template = array();
  29. var $bbcodes = array();
  30. var $template_bitfield;
  31. /**
  32. * Constructor
  33. */
  34. function __construct($bitfield = '')
  35. {
  36. $this->bbcode_set_bitfield($bitfield);
  37. }
  38. /**
  39. * Init bbcode cache entries if bitfield is specified
  40. *
  41. * @param string $bitfield The bbcode bitfield
  42. */
  43. function bbcode_set_bitfield($bitfield = '')
  44. {
  45. if ($bitfield)
  46. {
  47. $this->bbcode_bitfield = $bitfield;
  48. $this->bbcode_cache_init();
  49. }
  50. }
  51. /**
  52. * Second pass bbcodes
  53. */
  54. function bbcode_second_pass(&$message, $bbcode_uid = '', $bbcode_bitfield = false)
  55. {
  56. if ($bbcode_uid)
  57. {
  58. $this->bbcode_uid = $bbcode_uid;
  59. }
  60. if ($bbcode_bitfield !== false)
  61. {
  62. $this->bbcode_bitfield = $bbcode_bitfield;
  63. // Init those added with a new bbcode_bitfield (already stored codes will not get parsed again)
  64. $this->bbcode_cache_init();
  65. }
  66. if (!$this->bbcode_bitfield)
  67. {
  68. // Remove the uid from tags that have not been transformed into HTML
  69. if ($this->bbcode_uid)
  70. {
  71. $message = str_replace(':' . $this->bbcode_uid, '', $message);
  72. }
  73. return;
  74. }
  75. $str = array('search' => array(), 'replace' => array());
  76. $preg = array('search' => array(), 'replace' => array());
  77. $bitfield = new bitfield($this->bbcode_bitfield);
  78. $bbcodes_set = $bitfield->get_all_set();
  79. $undid_bbcode_specialchars = false;
  80. foreach ($bbcodes_set as $bbcode_id)
  81. {
  82. if (!empty($this->bbcode_cache[$bbcode_id]))
  83. {
  84. foreach ($this->bbcode_cache[$bbcode_id] as $type => $array)
  85. {
  86. foreach ($array as $search => $replace)
  87. {
  88. ${$type}['search'][] = str_replace('$uid', $this->bbcode_uid, $search);
  89. ${$type}['replace'][] = $replace;
  90. }
  91. if (count($str['search']))
  92. {
  93. $message = str_replace($str['search'], $str['replace'], $message);
  94. $str = array('search' => array(), 'replace' => array());
  95. }
  96. if (count($preg['search']))
  97. {
  98. // we need to turn the entities back into their original form to allow the
  99. // search patterns to work properly
  100. if (!$undid_bbcode_specialchars)
  101. {
  102. $message = str_replace(array('&#58;', '&#46;'), array(':', '.'), $message);
  103. $undid_bbcode_specialchars = true;
  104. }
  105. foreach ($preg['search'] as $key => $search)
  106. {
  107. if (is_callable($preg['replace'][$key]))
  108. {
  109. $message = preg_replace_callback($search, $preg['replace'][$key], $message);
  110. }
  111. else
  112. {
  113. $message = preg_replace($search, $preg['replace'][$key], $message);
  114. }
  115. }
  116. $preg = array('search' => array(), 'replace' => array());
  117. }
  118. }
  119. }
  120. }
  121. // Remove the uid from tags that have not been transformed into HTML
  122. $message = str_replace(':' . $this->bbcode_uid, '', $message);
  123. }
  124. /**
  125. * Init bbcode cache
  126. *
  127. * requires: $this->bbcode_bitfield
  128. * sets: $this->bbcode_cache with bbcode templates needed for bbcode_bitfield
  129. */
  130. function bbcode_cache_init()
  131. {
  132. global $user, $phpbb_dispatcher, $phpbb_extension_manager, $phpbb_container, $phpbb_filesystem;
  133. if (empty($this->template_filename))
  134. {
  135. $this->template_bitfield = new bitfield($user->style['bbcode_bitfield']);
  136. $template = new \phpbb\template\twig\twig(
  137. $phpbb_container->get('path_helper'),
  138. $phpbb_container->get('config'),
  139. new \phpbb\template\context(),
  140. new \phpbb\template\twig\environment(
  141. $phpbb_container->get('config'),
  142. $phpbb_container->get('filesystem'),
  143. $phpbb_container->get('path_helper'),
  144. $phpbb_container->getParameter('core.cache_dir'),
  145. $phpbb_container->get('ext.manager'),
  146. new \phpbb\template\twig\loader()
  147. ),
  148. $phpbb_container->getParameter('core.cache_dir'),
  149. $phpbb_container->get('user'),
  150. $phpbb_container->get('template.twig.extensions.collection'),
  151. $phpbb_extension_manager
  152. );
  153. $template->set_style();
  154. $template->set_filenames(array('bbcode.html' => 'bbcode.html'));
  155. $this->template_filename = $template->get_source_file_for_handle('bbcode.html');
  156. }
  157. $bbcode_ids = $rowset = $sql = array();
  158. $bitfield = new bitfield($this->bbcode_bitfield);
  159. $bbcodes_set = $bitfield->get_all_set();
  160. foreach ($bbcodes_set as $bbcode_id)
  161. {
  162. if (isset($this->bbcode_cache[$bbcode_id]))
  163. {
  164. // do not try to re-cache it if it's already in
  165. continue;
  166. }
  167. $bbcode_ids[] = $bbcode_id;
  168. if ($bbcode_id > NUM_CORE_BBCODES)
  169. {
  170. $sql[] = $bbcode_id;
  171. }
  172. }
  173. if (count($sql))
  174. {
  175. global $db;
  176. $sql = 'SELECT *
  177. FROM ' . BBCODES_TABLE . '
  178. WHERE ' . $db->sql_in_set('bbcode_id', $sql);
  179. $result = $db->sql_query($sql, 3600);
  180. while ($row = $db->sql_fetchrow($result))
  181. {
  182. // To circumvent replacing newlines with <br /> for the generated html,
  183. // we use carriage returns here. They are later changed back to newlines
  184. $row['bbcode_tpl'] = str_replace("\n", "\r", $row['bbcode_tpl']);
  185. $row['second_pass_replace'] = str_replace("\n", "\r", $row['second_pass_replace']);
  186. $rowset[$row['bbcode_id']] = $row;
  187. }
  188. $db->sql_freeresult($result);
  189. }
  190. foreach ($bbcode_ids as $bbcode_id)
  191. {
  192. switch ($bbcode_id)
  193. {
  194. case BBCODE_ID_QUOTE:
  195. $this->bbcode_cache[$bbcode_id] = array(
  196. 'str' => array(
  197. '[/quote:$uid]' => $this->bbcode_tpl('quote_close', $bbcode_id)
  198. ),
  199. 'preg' => array(
  200. '#\[quote(?:=&quot;(.*?)&quot;)?:$uid\]((?!\[quote(?:=&quot;.*?&quot;)?:$uid\]).)?#is' => function ($match) {
  201. if (!isset($match[2]))
  202. {
  203. $match[2] = '';
  204. }
  205. return $this->bbcode_second_pass_quote($match[1], $match[2]);
  206. },
  207. )
  208. );
  209. break;
  210. case BBCODE_ID_B:
  211. $this->bbcode_cache[$bbcode_id] = array(
  212. 'str' => array(
  213. '[b:$uid]' => $this->bbcode_tpl('b_open', $bbcode_id),
  214. '[/b:$uid]' => $this->bbcode_tpl('b_close', $bbcode_id),
  215. )
  216. );
  217. break;
  218. case BBCODE_ID_I:
  219. $this->bbcode_cache[$bbcode_id] = array(
  220. 'str' => array(
  221. '[i:$uid]' => $this->bbcode_tpl('i_open', $bbcode_id),
  222. '[/i:$uid]' => $this->bbcode_tpl('i_close', $bbcode_id),
  223. )
  224. );
  225. break;
  226. case BBCODE_ID_URL:
  227. $this->bbcode_cache[$bbcode_id] = array(
  228. 'preg' => array(
  229. '#\[url:$uid\]((.*?))\[/url:$uid\]#s' => $this->bbcode_tpl('url', $bbcode_id),
  230. '#\[url=([^\[]+?):$uid\](.*?)\[/url:$uid\]#s' => $this->bbcode_tpl('url', $bbcode_id),
  231. )
  232. );
  233. break;
  234. case BBCODE_ID_IMG:
  235. if ($user->optionget('viewimg'))
  236. {
  237. $this->bbcode_cache[$bbcode_id] = array(
  238. 'preg' => array(
  239. '#\[img:$uid\](.*?)\[/img:$uid\]#s' => $this->bbcode_tpl('img', $bbcode_id),
  240. )
  241. );
  242. }
  243. else
  244. {
  245. $this->bbcode_cache[$bbcode_id] = array(
  246. 'preg' => array(
  247. '#\[img:$uid\](.*?)\[/img:$uid\]#s' => str_replace('$2', '[ img ]', $this->bbcode_tpl('url', $bbcode_id, true)),
  248. )
  249. );
  250. }
  251. break;
  252. case BBCODE_ID_SIZE:
  253. $this->bbcode_cache[$bbcode_id] = array(
  254. 'preg' => array(
  255. '#\[size=([\-\+]?\d+):$uid\](.*?)\[/size:$uid\]#s' => $this->bbcode_tpl('size', $bbcode_id),
  256. )
  257. );
  258. break;
  259. case BBCODE_ID_COLOR:
  260. $this->bbcode_cache[$bbcode_id] = array(
  261. 'preg' => array(
  262. '!\[color=(#[0-9a-f]{3}|#[0-9a-f]{6}|[a-z\-]+):$uid\](.*?)\[/color:$uid\]!is' => $this->bbcode_tpl('color', $bbcode_id),
  263. )
  264. );
  265. break;
  266. case BBCODE_ID_U:
  267. $this->bbcode_cache[$bbcode_id] = array(
  268. 'str' => array(
  269. '[u:$uid]' => $this->bbcode_tpl('u_open', $bbcode_id),
  270. '[/u:$uid]' => $this->bbcode_tpl('u_close', $bbcode_id),
  271. )
  272. );
  273. break;
  274. case BBCODE_ID_CODE:
  275. $this->bbcode_cache[$bbcode_id] = array(
  276. 'preg' => array(
  277. '#\[code(?:=([a-z]+))?:$uid\](.*?)\[/code:$uid\]#is' => function ($match) {
  278. return $this->bbcode_second_pass_code($match[1], $match[2]);
  279. },
  280. )
  281. );
  282. break;
  283. case BBCODE_ID_LIST:
  284. $this->bbcode_cache[$bbcode_id] = array(
  285. 'preg' => array(
  286. '#(\[\/?(list|\*):[mou]?:?$uid\])[\n]{1}#' => "\$1",
  287. '#(\[list=([^\[]+):$uid\])[\n]{1}#' => "\$1",
  288. '#\[list=([^\[]+):$uid\]#' => function ($match) {
  289. return $this->bbcode_list($match[1]);
  290. },
  291. ),
  292. 'str' => array(
  293. '[list:$uid]' => $this->bbcode_tpl('ulist_open_default', $bbcode_id),
  294. '[/list:u:$uid]' => $this->bbcode_tpl('ulist_close', $bbcode_id),
  295. '[/list:o:$uid]' => $this->bbcode_tpl('olist_close', $bbcode_id),
  296. '[*:$uid]' => $this->bbcode_tpl('listitem', $bbcode_id),
  297. '[/*:$uid]' => $this->bbcode_tpl('listitem_close', $bbcode_id),
  298. '[/*:m:$uid]' => $this->bbcode_tpl('listitem_close', $bbcode_id)
  299. ),
  300. );
  301. break;
  302. case BBCODE_ID_EMAIL:
  303. $this->bbcode_cache[$bbcode_id] = array(
  304. 'preg' => array(
  305. '#\[email:$uid\]((.*?))\[/email:$uid\]#is' => $this->bbcode_tpl('email', $bbcode_id),
  306. '#\[email=([^\[]+):$uid\](.*?)\[/email:$uid\]#is' => $this->bbcode_tpl('email', $bbcode_id)
  307. )
  308. );
  309. break;
  310. case BBCODE_ID_FLASH:
  311. if ($user->optionget('viewflash'))
  312. {
  313. $this->bbcode_cache[$bbcode_id] = array(
  314. 'preg' => array(
  315. '#\[flash=([0-9]+),([0-9]+):$uid\](.*?)\[/flash:$uid\]#' => $this->bbcode_tpl('flash', $bbcode_id),
  316. )
  317. );
  318. }
  319. else
  320. {
  321. $this->bbcode_cache[$bbcode_id] = array(
  322. 'preg' => array(
  323. '#\[flash=([0-9]+),([0-9]+):$uid\](.*?)\[/flash:$uid\]#' => str_replace('$1', '$3', str_replace('$2', '[ flash ]', $this->bbcode_tpl('url', $bbcode_id, true)))
  324. )
  325. );
  326. }
  327. break;
  328. case BBCODE_ID_ATTACH:
  329. $this->bbcode_cache[$bbcode_id] = array(
  330. 'str' => array(
  331. '[/attachment:$uid]' => $this->bbcode_tpl('inline_attachment_close', $bbcode_id)
  332. ),
  333. 'preg' => array(
  334. '#\[attachment=([0-9]+):$uid\]#' => $this->bbcode_tpl('inline_attachment_open', $bbcode_id)
  335. )
  336. );
  337. break;
  338. default:
  339. if (isset($rowset[$bbcode_id]))
  340. {
  341. if ($this->template_bitfield->get($bbcode_id))
  342. {
  343. // The bbcode requires a custom template to be loaded
  344. if (!$bbcode_tpl = $this->bbcode_tpl($rowset[$bbcode_id]['bbcode_tag'], $bbcode_id))
  345. {
  346. // For some reason, the required template seems not to be available, use the default template
  347. $bbcode_tpl = (!empty($rowset[$bbcode_id]['second_pass_replace'])) ? $rowset[$bbcode_id]['second_pass_replace'] : $rowset[$bbcode_id]['bbcode_tpl'];
  348. }
  349. else
  350. {
  351. // In order to use templates with custom bbcodes we need
  352. // to replace all {VARS} to corresponding backreferences
  353. // Note that backreferences are numbered from bbcode_match
  354. if (preg_match_all('/\{(URL|LOCAL_URL|EMAIL|TEXT|SIMPLETEXT|INTTEXT|IDENTIFIER|COLOR|NUMBER)[0-9]*\}/', $rowset[$bbcode_id]['bbcode_match'], $m))
  355. {
  356. foreach ($m[0] as $i => $tok)
  357. {
  358. $bbcode_tpl = str_replace($tok, '$' . ($i + 1), $bbcode_tpl);
  359. }
  360. }
  361. }
  362. }
  363. else
  364. {
  365. // Default template
  366. $bbcode_tpl = (!empty($rowset[$bbcode_id]['second_pass_replace'])) ? $rowset[$bbcode_id]['second_pass_replace'] : $rowset[$bbcode_id]['bbcode_tpl'];
  367. }
  368. // Replace {L_*} lang strings
  369. $bbcode_tpl = preg_replace_callback('/{L_([A-Z0-9_]+)}/', function ($match) use ($user) {
  370. return (!empty($user->lang[$match[1]])) ? $user->lang($match[1]) : ucwords(strtolower(str_replace('_', ' ', $match[1])));
  371. }, $bbcode_tpl);
  372. if (!empty($rowset[$bbcode_id]['second_pass_replace']))
  373. {
  374. // The custom BBCode requires second-pass pattern replacements
  375. $this->bbcode_cache[$bbcode_id] = array(
  376. 'preg' => array($rowset[$bbcode_id]['second_pass_match'] => $bbcode_tpl)
  377. );
  378. }
  379. else
  380. {
  381. $this->bbcode_cache[$bbcode_id] = array(
  382. 'str' => array($rowset[$bbcode_id]['second_pass_match'] => $bbcode_tpl)
  383. );
  384. }
  385. }
  386. else
  387. {
  388. $this->bbcode_cache[$bbcode_id] = false;
  389. }
  390. break;
  391. }
  392. }
  393. $bbcode_cache = $this->bbcode_cache;
  394. $bbcode_bitfield = $this->bbcode_bitfield;
  395. $bbcode_uid = $this->bbcode_uid;
  396. /**
  397. * Use this event to modify the bbcode_cache
  398. *
  399. * @event core.bbcode_cache_init_end
  400. * @var array bbcode_cache The array of cached search and replace patterns of bbcodes
  401. * @var string bbcode_bitfield The bbcode bitfield
  402. * @var string bbcode_uid The bbcode uid
  403. * @since 3.1.3-RC1
  404. */
  405. $vars = array('bbcode_cache', 'bbcode_bitfield', 'bbcode_uid');
  406. extract($phpbb_dispatcher->trigger_event('core.bbcode_cache_init_end', compact($vars)));
  407. $this->bbcode_cache = $bbcode_cache;
  408. $this->bbcode_bitfield = $bbcode_bitfield;
  409. $this->bbcode_uid = $bbcode_uid;
  410. }
  411. /**
  412. * Return bbcode template
  413. */
  414. function bbcode_tpl($tpl_name, $bbcode_id = -1, $skip_bitfield_check = false)
  415. {
  416. static $bbcode_hardtpl = array();
  417. if (empty($bbcode_hardtpl))
  418. {
  419. global $user;
  420. $bbcode_hardtpl = array(
  421. 'b_open' => '<span style="font-weight: bold">',
  422. 'b_close' => '</span>',
  423. 'i_open' => '<span style="font-style: italic">',
  424. 'i_close' => '</span>',
  425. 'u_open' => '<span style="text-decoration: underline">',
  426. 'u_close' => '</span>',
  427. 'img' => '<img src="$1" class="postimage" alt="' . $user->lang['IMAGE'] . '" />',
  428. 'size' => '<span style="font-size: $1%; line-height: normal">$2</span>',
  429. 'color' => '<span style="color: $1">$2</span>',
  430. 'email' => '<a href="mailto:$1">$2</a>'
  431. );
  432. }
  433. if ($bbcode_id != -1 && !$skip_bitfield_check && !$this->template_bitfield->get($bbcode_id))
  434. {
  435. return (isset($bbcode_hardtpl[$tpl_name])) ? $bbcode_hardtpl[$tpl_name] : false;
  436. }
  437. if (empty($this->bbcode_template))
  438. {
  439. if (($tpl = file_get_contents($this->template_filename)) === false)
  440. {
  441. trigger_error('Could not load bbcode template', E_USER_ERROR);
  442. }
  443. // replace \ with \\ and then ' with \'.
  444. $tpl = str_replace('\\', '\\\\', $tpl);
  445. $tpl = str_replace("'", "\'", $tpl);
  446. // strip newlines and indent
  447. $tpl = preg_replace("/\n[\n\r\s\t]*/", '', $tpl);
  448. // Turn template blocks into PHP assignment statements for the values of $bbcode_tpl..
  449. $this->bbcode_template = array();
  450. // Capture the BBCode template matches
  451. // Allow phpBB template or the Twig syntax
  452. $matches = (preg_match_all('#<!-- BEGIN (.*?) -->(.*?)<!-- END (?:.*?) -->#', $tpl, $match)) ?:
  453. preg_match_all('#{% for (.*?) in .*? %}(.*?){% endfor %}#s', $tpl, $match);
  454. for ($i = 0; $i < $matches; $i++)
  455. {
  456. if (empty($match[1][$i]))
  457. {
  458. continue;
  459. }
  460. $this->bbcode_template[$match[1][$i]] = $this->bbcode_tpl_replace($match[1][$i], $match[2][$i]);
  461. }
  462. }
  463. return (isset($this->bbcode_template[$tpl_name])) ? $this->bbcode_template[$tpl_name] : ((isset($bbcode_hardtpl[$tpl_name])) ? $bbcode_hardtpl[$tpl_name] : false);
  464. }
  465. /**
  466. * Return bbcode template replacement
  467. */
  468. function bbcode_tpl_replace($tpl_name, $tpl)
  469. {
  470. global $user;
  471. static $replacements = array(
  472. 'quote_username_open' => array('{USERNAME}' => '$1'),
  473. 'color' => array('{COLOR}' => '$1', '{TEXT}' => '$2'),
  474. 'size' => array('{SIZE}' => '$1', '{TEXT}' => '$2'),
  475. 'img' => array('{URL}' => '$1'),
  476. 'flash' => array('{WIDTH}' => '$1', '{HEIGHT}' => '$2', '{URL}' => '$3'),
  477. 'url' => array('{URL}' => '$1', '{DESCRIPTION}' => '$2'),
  478. 'email' => array('{EMAIL}' => '$1', '{DESCRIPTION}' => '$2')
  479. );
  480. $tpl = preg_replace_callback('/{L_([A-Z0-9_]+)}/', function ($match) use ($user) {
  481. return (!empty($user->lang[$match[1]])) ? $user->lang($match[1]) : ucwords(strtolower(str_replace('_', ' ', $match[1])));
  482. }, $tpl);
  483. if (!empty($replacements[$tpl_name]))
  484. {
  485. $tpl = strtr($tpl, $replacements[$tpl_name]);
  486. }
  487. return trim($tpl);
  488. }
  489. /**
  490. * Second parse list bbcode
  491. */
  492. function bbcode_list($type)
  493. {
  494. if ($type == '')
  495. {
  496. $tpl = 'ulist_open_default';
  497. $type = 'default';
  498. }
  499. else if ($type == 'i')
  500. {
  501. $tpl = 'olist_open';
  502. $type = 'lower-roman';
  503. }
  504. else if ($type == 'I')
  505. {
  506. $tpl = 'olist_open';
  507. $type = 'upper-roman';
  508. }
  509. else if (preg_match('#^(disc|circle|square)$#i', $type))
  510. {
  511. $tpl = 'ulist_open';
  512. $type = strtolower($type);
  513. }
  514. else if (preg_match('#^[a-z]$#', $type))
  515. {
  516. $tpl = 'olist_open';
  517. $type = 'lower-alpha';
  518. }
  519. else if (preg_match('#[A-Z]#', $type))
  520. {
  521. $tpl = 'olist_open';
  522. $type = 'upper-alpha';
  523. }
  524. else if (is_numeric($type))
  525. {
  526. $tpl = 'olist_open';
  527. $type = 'decimal';
  528. }
  529. else
  530. {
  531. $tpl = 'olist_open';
  532. $type = 'decimal';
  533. }
  534. return str_replace('{LIST_TYPE}', $type, $this->bbcode_tpl($tpl));
  535. }
  536. /**
  537. * Second parse quote tag
  538. */
  539. function bbcode_second_pass_quote($username, $quote)
  540. {
  541. // when using the /e modifier, preg_replace slashes double-quotes but does not
  542. // seem to slash anything else
  543. $quote = str_replace('\"', '"', $quote);
  544. $username = str_replace('\"', '"', $username);
  545. // remove newline at the beginning
  546. if ($quote == "\n")
  547. {
  548. $quote = '';
  549. }
  550. $quote = (($username) ? str_replace('$1', $username, $this->bbcode_tpl('quote_username_open')) : $this->bbcode_tpl('quote_open')) . $quote;
  551. return $quote;
  552. }
  553. /**
  554. * Second parse code tag
  555. */
  556. function bbcode_second_pass_code($type, $code)
  557. {
  558. // when using the /e modifier, preg_replace slashes double-quotes but does not
  559. // seem to slash anything else
  560. $code = str_replace('\"', '"', $code);
  561. switch ($type)
  562. {
  563. case 'php':
  564. // Not the english way, but valid because of hardcoded syntax highlighting
  565. if (strpos($code, '<span class="syntaxdefault"><br /></span>') === 0)
  566. {
  567. $code = substr($code, 41);
  568. }
  569. // no break;
  570. default:
  571. $code = str_replace("\t", '&nbsp; &nbsp;', $code);
  572. $code = str_replace(' ', '&nbsp; ', $code);
  573. $code = str_replace(' ', ' &nbsp;', $code);
  574. $code = str_replace("\n ", "\n&nbsp;", $code);
  575. // keep space at the beginning
  576. if (!empty($code) && $code[0] == ' ')
  577. {
  578. $code = '&nbsp;' . substr($code, 1);
  579. }
  580. // remove newline at the beginning
  581. if (!empty($code) && $code[0] == "\n")
  582. {
  583. $code = substr($code, 1);
  584. }
  585. break;
  586. }
  587. $code = $this->bbcode_tpl('code_open') . $code . $this->bbcode_tpl('code_close');
  588. return $code;
  589. }
  590. /**
  591. * Function to perform custom bbcode second pass by extensions
  592. * can be used to assign bbcode pattern replacement
  593. * Example: '#\[list=([^\[]+):$uid\]#e' => "\$this->bbcode_second_pass_by_extension('\$1')"
  594. *
  595. * Accepts variable number of parameters
  596. *
  597. * @return mixed Second pass result
  598. *
  599. * @deprecated 3.2.10 (To be removed 4.0.0)
  600. */
  601. function bbcode_second_pass_by_extension()
  602. {
  603. global $phpbb_dispatcher;
  604. $return = false;
  605. $params_array = func_get_args();
  606. /**
  607. * Event to perform bbcode second pass with
  608. * the custom validating methods provided by extensions
  609. *
  610. * @event core.bbcode_second_pass_by_extension
  611. * @var array params_array Array with the function parameters
  612. * @var mixed return Second pass result to return
  613. *
  614. * @since 3.1.5-RC1
  615. */
  616. $vars = array('params_array', 'return');
  617. extract($phpbb_dispatcher->trigger_event('core.bbcode_second_pass_by_extension', compact($vars)));
  618. return $return;
  619. }
  620. }