daily pastebin goal
50%
SHARE
TWEET

Untitled

a guest Feb 17th, 2019 57 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2.  
  3. /**
  4.  * Copyright (C) 2008-2012 FluxBB
  5.  * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
  6.  * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
  7.  */
  8.  
  9. // Make sure no one attempts to run this script "directly"
  10. if (!defined('PUN'))
  11.     exit;
  12.  
  13. // Global variables
  14. /* regular expression to match nested BBCode LIST tags
  15. '%
  16. \[list                # match opening bracket and tag name of outermost LIST tag
  17. (?:=([1a*]))?+        # optional attribute capture in group 1
  18. \]                    # closing bracket of outermost opening LIST tag
  19. (                     # capture contents of LIST tag in group 2
  20.   (?:                 # non capture group for either contents or whole nested LIST
  21.     [^\[]*+           # unroll the loop! consume everything up to next [ (normal *)
  22.     (?:               # (See "Mastering Regular Expressions" chapter 6 for details)
  23.       (?!             # negative lookahead ensures we are NOT on [LIST*] or [/LIST]
  24.         \[list        # opening LIST tag
  25.         (?:=[1a*])?+  # with optional attribute
  26.         \]            # closing bracket of opening LIST tag
  27.         |             # or...
  28.         \[/list\]     # a closing LIST tag
  29.       )               # end negative lookahead assertion (we are not on a LIST tag)
  30.       \[              # match the [ which is NOT the start of LIST tag (special)
  31.       [^\[]*+         # consume everything up to next [ (normal *)
  32.     )*+               # finish up "unrolling the loop" technique (special (normal*))*
  33.   |                   # or...
  34.     (?R)              # recursively match a whole nested LIST element
  35.   )*                  # as many times as necessary until deepest nested LIST tag grabbed
  36. )                     # end capturing contents of LIST tag into group 2
  37. \[/list\]             # match outermost closing LIST tag
  38. %iex' */
  39. $re_list = '%\[list(?:=([1a*]))?+\]((?:[^\[]*+(?:(?!\[list(?:=[1a*])?+\]|\[/list\])\[[^\[]*+)*+|(?R))*)\[/list\]%i';
  40.  
  41. // Here you can add additional smilies if you like (please note that you must escape single quote and backslash)
  42. $smilies = array(
  43.     ':)' => 'smile.png',
  44.     '=)' => 'smile.png',
  45.     ':|' => 'neutral.png',
  46.     '=|' => 'neutral.png',
  47.     ':(' => 'sad.png',
  48.     '=(' => 'sad.png',
  49.     ':D' => 'big_smile.png',
  50.     '=D' => 'big_smile.png',
  51.     ':o' => 'yikes.png',
  52.     ':O' => 'yikes.png',
  53.     ';)' => 'wink.png',
  54.     ':/' => 'hmm.png',
  55.     ':P' => 'tongue.png',
  56.     ':p' => 'tongue.png',
  57.     ':lol:' => 'lol.png',
  58.     ':mad:' => 'mad.png',
  59.     ':rolleyes:' => 'roll.png',
  60.     ':cool:' => 'cool.png');
  61.  
  62. //
  63. // Make sure all BBCodes are lower case and do a little cleanup
  64. //
  65. function preparse_bbcode($text, &$errors, $is_signature = false)
  66. {
  67.     global $pun_config, $lang_common, $lang_post, $re_list;
  68.  
  69.     // Remove empty tags
  70.     while (($new_text = strip_empty_bbcode($text)) !== false)
  71.     {
  72.         if ($new_text != $text)
  73.         {
  74.             $text = $new_text;
  75.             if ($new_text == '')
  76.             {
  77.                 $errors[] = $lang_post['Empty after strip'];
  78.                 return '';
  79.             }
  80.         }
  81.         else
  82.             break;
  83.     }
  84.  
  85.     if ($is_signature)
  86.     {
  87.         global $lang_profile;
  88.  
  89.         if (preg_match('%\[/?(?:spoiler|profil|quote|code|list|h)\b[^\]]*\]%i', $text))
  90.             $errors[] = $lang_profile['Signature quote/code/list/h'];
  91.     }
  92.  
  93.     // If the message contains a code tag we have to split it up (text within [code][/code] shouldn't be touched)
  94.     if (strpos($text, '[code]') !== false && strpos($text, '[/code]') !== false)
  95.         list($inside, $text) = extract_blocks($text, '[code]', '[/code]');
  96.  
  97.     // Tidy up lists
  98.     $temp = preg_replace_callback($re_list, create_function('$matches', 'return preparse_list_tag($matches[2], $matches[1]);'), $text);
  99.  
  100.     // If the regex failed
  101.     if (is_null($temp))
  102.         //$errors[] = $lang_common['BBCode list size error'];
  103.     else
  104.         $text = str_replace('*'."\0".']', '*]', $temp);
  105.  
  106.     if ($pun_config['o_make_links'] == '1')
  107.         $text = do_clickable($text);
  108.  
  109.     $temp_text = false;
  110.     if (empty($errors))
  111.         $temp_text = preparse_tags($text, $errors, $is_signature);
  112.  
  113.     if ($temp_text !== false)
  114.         $text = $temp_text;
  115.  
  116.     // If we split up the message before we have to concatenate it together again (code tags)
  117.     if (isset($inside))
  118.     {
  119.         $outside = explode("\1", $text);
  120.         $text = '';
  121.  
  122.         $num_tokens = count($outside);
  123.         for ($i = 0; $i < $num_tokens; ++$i)
  124.         {
  125.             $text .= $outside[$i];
  126.             if (isset($inside[$i]))
  127.                 $text .= '[code]'.$inside[$i].'[/code]';
  128.         }
  129.  
  130.         unset($inside);
  131.     }
  132.  
  133.     // Remove empty tags
  134.     while (($new_text = strip_empty_bbcode($text)) !== false)
  135.     {
  136.         if ($new_text != $text)
  137.         {
  138.             $text = $new_text;
  139.             if ($new_text == '')
  140.             {
  141.                 $errors[] = $lang_post['Empty after strip'];
  142.                 break;
  143.             }
  144.         }
  145.         else
  146.             break;
  147.     }
  148.  
  149.     return pun_trim($text);
  150. }
  151.  
  152.  
  153. //
  154. // Strip empty bbcode tags from some text
  155. //
  156. function strip_empty_bbcode($text)
  157. {
  158.     // If the message contains a code tag we have to split it up (empty tags within [code][/code] are fine)
  159.     if (strpos($text, '[code]') !== false && strpos($text, '[/code]') !== false)
  160.         list($inside, $text) = extract_blocks($text, '[code]', '[/code]');
  161.  
  162.     // Remove empty tags
  163.     while (!is_null($new_text = preg_replace('%\[(spoiler|profil|b|u|s|ins|del|em|i|h|colou?r|quote|img|url|email|list|topic|post|forum|user)(?:\=[^\]]*)?\]\s*\[/\1\]%', '', $text)))
  164.     {
  165.         if ($new_text != $text)
  166.             $text = $new_text;
  167.         else
  168.             break;
  169.     }
  170.  
  171.     // If we split up the message before we have to concatenate it together again (code tags)
  172.     if (isset($inside))
  173.     {
  174.         $parts = explode("\1", $text);
  175.         $text = '';
  176.         foreach ($parts as $i => $part)
  177.         {
  178.             $text .= $part;
  179.             if (isset($inside[$i]))
  180.                 $text .= '[code]'.$inside[$i].'[/code]';
  181.         }
  182.     }
  183.  
  184.     // Remove empty code tags
  185.     while (!is_null($new_text = preg_replace('%\[(code)\]\s*\[/\1\]%', '', $text)))
  186.     {
  187.         if ($new_text != $text)
  188.             $text = $new_text;
  189.         else
  190.             break;
  191.     }
  192.  
  193.     return $text;
  194. }
  195.  
  196.  
  197. //
  198. // Check the structure of bbcode tags and fix simple mistakes where possible
  199. //
  200. function preparse_tags($text, &$errors, $is_signature = false)
  201. {
  202.     global $lang_common, $pun_config, $pun_user;
  203.  
  204.     // Start off by making some arrays of bbcode tags and what we need to do with each one
  205.  
  206.     // List of all the tags
  207.     $tags = array('spoiler', 'profil', ‘size’, ‘font’, ‘hr’, ‘center’, ‘left’, ‘right’, 'quote', 'code', 'b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'img', 'list', '*', 'h', 'topic', 'post', 'forum', 'user');
  208.     // List of tags that we need to check are open (You could not put b,i,u in here then illegal nesting like [b][i][/b][/i] would be allowed)
  209.     $tags_opened = $tags;
  210.     // and tags we need to check are closed (the same as above, added it just in case)
  211.     $tags_closed = $tags;
  212.     // Tags we can nest and the depth they can be nested to
  213.     $tags_nested = array('quote' => $pun_config['o_quote_depth'], 'list' => 5, '*' => 5, 'spoiler' => 5);
  214.     // Tags to ignore the contents of completely (just code)
  215.     $tags_ignore = array('code');
  216.     // Tags not allowed
  217.     $tags_forbidden = array();
  218.     // Block tags, block tags can only go within another block tag, they cannot be in a normal tag
  219.     $tags_block = array('quote', 'code', 'list', 'h', '*', 'spoiler', 'profil');
  220.     // Inline tags, we do not allow new lines in these
  221.     $tags_inline = array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'h', 'topic', 'post', 'forum', 'user');
  222.     // Tags we trim interior space
  223.     $tags_trim = array('img');
  224.     // Tags we remove quotes from the argument
  225.     $tags_quotes = array('url', 'email', 'img', 'topic', 'post', 'forum', 'user');
  226.     // Tags we limit bbcode in
  227.     $tags_limit_bbcode = array(
  228.         '*'     => array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'list', 'img', 'code', 'topic', 'post', 'forum', 'user'),
  229.         'list'  => array('*'),
  230.         'url'   => array('img'),
  231.         'email' => array('img'),
  232.         'topic' => array('img'),
  233.         'post'  => array('img'),
  234.         'forum' => array('img'),
  235.         'user'  => array('img'),
  236.         'img'   => array(),
  237.         'h'     => array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'topic', 'post', 'forum', 'user'),
  238.     );
  239.     // Tags we can automatically fix bad nesting
  240.     $tags_fix = array('quote', 'b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'h', 'topic', 'post', 'forum', 'user');
  241.  
  242.     // Disallow URL tags
  243.     if ($pun_user['g_post_links'] != '1')
  244.         $tags_forbidden[] = 'url';
  245.  
  246.     $split_text = preg_split('%(\[[\*a-zA-Z0-9-/]*?(?:=.*?)?\])%', $text, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
  247.  
  248.     $open_tags = array('fluxbb-bbcode');
  249.     $open_args = array('');
  250.     $opened_tag = 0;
  251.     $new_text = '';
  252.     $current_ignore = '';
  253.     $current_nest = '';
  254.     $current_depth = array();
  255.     $limit_bbcode = $tags;
  256.     $count_ignored = array();
  257.  
  258.     foreach ($split_text as $current)
  259.     {
  260.         if ($current == '')
  261.             continue;
  262.  
  263.         // Are we dealing with a tag?
  264.         if (substr($current, 0, 1) != '[' || substr($current, -1, 1) != ']')
  265.         {
  266.             // It's not a bbcode tag so we put it on the end and continue
  267.             // If we are nested too deeply don't add to the end
  268.             if ($current_nest)
  269.                 continue;
  270.  
  271.             $current = str_replace("\r\n", "\n", $current);
  272.             $current = str_replace("\r", "\n", $current);
  273.             if (in_array($open_tags[$opened_tag], $tags_inline) && strpos($current, "\n") !== false)
  274.             {
  275.                 // Deal with new lines
  276.                 $split_current = preg_split('%(\n\n+)%', $current, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
  277.                 $current = '';
  278.  
  279.                 if (!pun_trim($split_current[0], "\n")) // The first part is a linebreak so we need to handle any open tags first
  280.                     array_unshift($split_current, '');
  281.  
  282.                 for ($i = 1; $i < count($split_current); $i += 2)
  283.                 {
  284.                     $temp_opened = array();
  285.                     $temp_opened_arg = array();
  286.                     $temp = $split_current[$i - 1];
  287.                     while (!empty($open_tags))
  288.                     {
  289.                         $temp_tag = array_pop($open_tags);
  290.                         $temp_arg = array_pop($open_args);
  291.  
  292.                         if (in_array($temp_tag , $tags_inline))
  293.                         {
  294.                             array_push($temp_opened, $temp_tag);
  295.                             array_push($temp_opened_arg, $temp_arg);
  296.                             $temp .= '[/'.$temp_tag.']';
  297.                         }
  298.                         else
  299.                         {
  300.                             array_push($open_tags, $temp_tag);
  301.                             array_push($open_args, $temp_arg);
  302.                             break;
  303.                         }
  304.                     }
  305.                     $current .= $temp.$split_current[$i];
  306.                     $temp = '';
  307.                     while (!empty($temp_opened))
  308.                     {
  309.                         $temp_tag = array_pop($temp_opened);
  310.                         $temp_arg = array_pop($temp_opened_arg);
  311.                         if (empty($temp_arg))
  312.                             $temp .= '['.$temp_tag.']';
  313.                         else
  314.                             $temp .= '['.$temp_tag.'='.$temp_arg.']';
  315.                         array_push($open_tags, $temp_tag);
  316.                         array_push($open_args, $temp_arg);
  317.                     }
  318.                     $current .= $temp;
  319.                 }
  320.  
  321.                 if (array_key_exists($i - 1, $split_current))
  322.                     $current .= $split_current[$i - 1];
  323.             }
  324.  
  325.             if (in_array($open_tags[$opened_tag], $tags_trim))
  326.                 $new_text .= pun_trim($current);
  327.             else
  328.                 $new_text .= $current;
  329.  
  330.             continue;
  331.         }
  332.  
  333.         // Get the name of the tag
  334.         $current_arg = '';
  335.         if (strpos($current, '/') === 1)
  336.         {
  337.             $current_tag = substr($current, 2, -1);
  338.         }
  339.         else if (strpos($current, '=') === false)
  340.         {
  341.             $current_tag = substr($current, 1, -1);
  342.         }
  343.         else
  344.         {
  345.             $current_tag = substr($current, 1, strpos($current, '=')-1);
  346.             $current_arg = substr($current, strpos($current, '=')+1, -1);
  347.         }
  348.         $current_tag = strtolower($current_tag);
  349.  
  350.         // Is the tag defined?
  351.         if (!in_array($current_tag, $tags))
  352.         {
  353.             // It's not a bbcode tag so we put it on the end and continue
  354.             if (!$current_nest)
  355.                 $new_text .= $current;
  356.  
  357.             continue;
  358.         }
  359.  
  360.         // We definitely have a bbcode tag
  361.  
  362.         // Make the tag string lower case
  363.         if ($equalpos = strpos($current,'='))
  364.         {
  365.             // We have an argument for the tag which we don't want to make lowercase
  366.             if (strlen(substr($current, $equalpos)) == 2)
  367.             {
  368.                 // Empty tag argument
  369.                 $errors[] = sprintf($lang_common['BBCode error empty attribute'], $current_tag);
  370.                 return false;
  371.             }
  372.             $current = strtolower(substr($current, 0, $equalpos)).substr($current, $equalpos);
  373.         }
  374.         else
  375.             $current = strtolower($current);
  376.  
  377.         // This is if we are currently in a tag which escapes other bbcode such as code
  378.         // We keep a count of ignored bbcodes (code tags) so we can nest them, but
  379.         // only balanced sets of tags can be nested
  380.         if ($current_ignore)
  381.         {
  382.             // Increase the current ignored tags counter
  383.             if ('['.$current_ignore.']' == $current)
  384.                 $count_ignored[$current_tag]++;
  385.  
  386.             // Decrease the current ignored tags counter
  387.             if ('[/'.$current_ignore.']' == $current)
  388.                 $count_ignored[$current_tag]--;
  389.  
  390.             if ('[/'.$current_ignore.']' == $current && $count_ignored[$current_tag] == 0)
  391.             {
  392.                 // We've finished the ignored section
  393.                 $current = '[/'.$current_tag.']';
  394.                 $current_ignore = '';
  395.                 $count_ignored = array();
  396.             }
  397.  
  398.             $new_text .= $current;
  399.  
  400.             continue;
  401.         }
  402.  
  403.         // Is the tag forbidden?
  404.         if (in_array($current_tag, $tags_forbidden))
  405.         {
  406.             if (isset($lang_common['BBCode error tag '.$current_tag.' not allowed']))
  407.                 $errors[] = sprintf($lang_common['BBCode error tag '.$current_tag.' not allowed']);
  408.             else
  409.                 $errors[] = sprintf($lang_common['BBCode error tag not allowed'], $current_tag);
  410.  
  411.             return false;
  412.         }
  413.  
  414.         if ($current_nest)
  415.         {
  416.             // We are currently too deeply nested so lets see if we are closing the tag or not
  417.             if ($current_tag != $current_nest)
  418.                 continue;
  419.  
  420.             if (substr($current, 1, 1) == '/')
  421.                 $current_depth[$current_nest]--;
  422.             else
  423.                 $current_depth[$current_nest]++;
  424.  
  425.             if ($current_depth[$current_nest] <= $tags_nested[$current_nest])
  426.                 $current_nest = '';
  427.  
  428.             continue;
  429.         }
  430.  
  431.         // Check the current tag is allowed here
  432.         if (!in_array($current_tag, $limit_bbcode) && $current_tag != $open_tags[$opened_tag])
  433.         {
  434.             $errors[] = sprintf($lang_common['BBCode error invalid nesting'], $current_tag, $open_tags[$opened_tag]);
  435.             return false;
  436.         }
  437.  
  438.         if (substr($current, 1, 1) == '/')
  439.         {
  440.             // This is if we are closing a tag
  441.             if ($opened_tag == 0 || !in_array($current_tag, $open_tags))
  442.             {
  443.                 // We tried to close a tag which is not open
  444.                 if (in_array($current_tag, $tags_opened))
  445.                 {
  446.                     $errors[] = sprintf($lang_common['BBCode error no opening tag'], $current_tag);
  447.                     return false;
  448.                 }
  449.             }
  450.             else
  451.             {
  452.                 // Check nesting
  453.                 while (true)
  454.                 {
  455.                     // Nesting is ok
  456.                     if ($open_tags[$opened_tag] == $current_tag)
  457.                     {
  458.                         array_pop($open_tags);
  459.                         array_pop($open_args);
  460.                         $opened_tag--;
  461.                         break;
  462.                     }
  463.  
  464.                     // Nesting isn't ok, try to fix it
  465.                     if (in_array($open_tags[$opened_tag], $tags_closed) && in_array($current_tag, $tags_closed))
  466.                     {
  467.                         if (in_array($current_tag, $open_tags))
  468.                         {
  469.                             $temp_opened = array();
  470.                             $temp_opened_arg = array();
  471.                             $temp = '';
  472.                             while (!empty($open_tags))
  473.                             {
  474.                                 $temp_tag = array_pop($open_tags);
  475.                                 $temp_arg = array_pop($open_args);
  476.  
  477.                                 if (!in_array($temp_tag, $tags_fix))
  478.                                 {
  479.                                     // We couldn't fix nesting
  480.                                     $errors[] = sprintf($lang_common['BBCode error no closing tag'], array_pop($temp_opened));
  481.                                     return false;
  482.                                 }
  483.                                 array_push($temp_opened, $temp_tag);
  484.                                 array_push($temp_opened_arg, $temp_arg);
  485.  
  486.                                 if ($temp_tag == $current_tag)
  487.                                     break;
  488.                                 else
  489.                                     $temp .= '[/'.$temp_tag.']';
  490.                             }
  491.                             $current = $temp.$current;
  492.                             $temp = '';
  493.                             array_pop($temp_opened);
  494.                             array_pop($temp_opened_arg);
  495.  
  496.                             while (!empty($temp_opened))
  497.                             {
  498.                                 $temp_tag = array_pop($temp_opened);
  499.                                 $temp_arg = array_pop($temp_opened_arg);
  500.                                 if (empty($temp_arg))
  501.                                     $temp .= '['.$temp_tag.']';
  502.                                 else
  503.                                     $temp .= '['.$temp_tag.'='.$temp_arg.']';
  504.                                 array_push($open_tags, $temp_tag);
  505.                                 array_push($open_args, $temp_arg);
  506.                             }
  507.                             $current .= $temp;
  508.                             $opened_tag--;
  509.                             break;
  510.                         }
  511.                         else
  512.                         {
  513.                             // We couldn't fix nesting
  514.                             $errors[] = sprintf($lang_common['BBCode error no opening tag'], $current_tag);
  515.                             return false;
  516.                         }
  517.                     }
  518.                     else if (in_array($open_tags[$opened_tag], $tags_closed))
  519.                         break;
  520.                     else
  521.                     {
  522.                         array_pop($open_tags);
  523.                         array_pop($open_args);
  524.                         $opened_tag--;
  525.                     }
  526.                 }
  527.             }
  528.  
  529.             if (in_array($current_tag, array_keys($tags_nested)))
  530.             {
  531.                 if (isset($current_depth[$current_tag]))
  532.                     $current_depth[$current_tag]--;
  533.             }
  534.  
  535.             if (in_array($open_tags[$opened_tag], array_keys($tags_limit_bbcode)))
  536.                 $limit_bbcode = $tags_limit_bbcode[$open_tags[$opened_tag]];
  537.             else
  538.                 $limit_bbcode = $tags;
  539.  
  540.             $new_text .= $current;
  541.  
  542.             continue;
  543.         }
  544.         else
  545.         {
  546.             // We are opening a tag
  547.             if (in_array($current_tag, array_keys($tags_limit_bbcode)))
  548.                 $limit_bbcode = $tags_limit_bbcode[$current_tag];
  549.             else
  550.                 $limit_bbcode = $tags;
  551.  
  552.             if (in_array($current_tag, $tags_block) && !in_array($open_tags[$opened_tag], $tags_block) && $opened_tag != 0)
  553.             {
  554.                 // We tried to open a block tag within a non-block tag
  555.                 $errors[] = sprintf($lang_common['BBCode error invalid nesting'], $current_tag, $open_tags[$opened_tag]);
  556.                 return false;
  557.             }
  558.  
  559.             if (in_array($current_tag, $tags_ignore))
  560.             {
  561.                 // It's an ignore tag so we don't need to worry about what's inside it
  562.                 $current_ignore = $current_tag;
  563.                 $count_ignored[$current_tag] = 1;
  564.                 $new_text .= $current;
  565.                 continue;
  566.             }
  567.  
  568.  
  569.             if (in_array($current_tag, array_keys($tags_nested)))
  570.             {
  571.                 // We are allowed to nest this tag
  572.  
  573.                 if (isset($current_depth[$current_tag]))
  574.                     $current_depth[$current_tag]++;
  575.                 else
  576.                     $current_depth[$current_tag] = 1;
  577.  
  578.                 // See if we are nested too deep
  579.                 if ($current_depth[$current_tag] > $tags_nested[$current_tag])
  580.                 {
  581.                     $current_nest = $current_tag;
  582.                     continue;
  583.                 }
  584.             }
  585.  
  586.             // Remove quotes from arguments for certain tags
  587.             if (strpos($current, '=') !== false && in_array($current_tag, $tags_quotes))
  588.             {
  589.                 $current = preg_replace('%\['.$current_tag.'=("|\'|)(.*?)\\1\]\s*%i', '['.$current_tag.'=$2]', $current);
  590.             }
  591.  
  592.             if (in_array($current_tag, array_keys($tags_limit_bbcode)))
  593.                 $limit_bbcode = $tags_limit_bbcode[$current_tag];
  594.  
  595.             $open_tags[] = $current_tag;
  596.             $open_args[] = $current_arg;
  597.             $opened_tag++;
  598.             $new_text .= $current;
  599.             continue;
  600.         }
  601.     }
  602.  
  603.     // Check we closed all the tags we needed to
  604.     foreach ($tags_closed as $check)
  605.     {
  606.         if (in_array($check, $open_tags))
  607.         {
  608.             // We left an important tag open
  609.             $errors[] = sprintf($lang_common['BBCode error no closing tag'], $check);
  610.             return false;
  611.         }
  612.     }
  613.  
  614.     if ($current_ignore)
  615.     {
  616.         // We left an ignore tag open
  617.         $errors[] = sprintf($lang_common['BBCode error no closing tag'], $current_ignore);
  618.         return false;
  619.     }
  620.  
  621.     return $new_text;
  622. }
  623.  
  624.  
  625. //
  626. // Preparse the contents of [list] bbcode
  627. //
  628. function preparse_list_tag($content, $type = '*')
  629. {
  630.     global $lang_common, $re_list;
  631.  
  632.     if (strlen($type) != 1)
  633.         $type = '*';
  634.  
  635.     if (strpos($content,'[list') !== false)
  636.     {
  637.         $content = preg_replace_callback($re_list, create_function('$matches', 'return preparse_list_tag($matches[2], $matches[1]);'), $content);
  638.     }
  639.  
  640.     $items = explode('[*]', str_replace('\"', '"', $content));
  641.  
  642.     $content = '';
  643.     foreach ($items as $item)
  644.     {
  645.         if (pun_trim($item) != '')
  646.             $content .= '[*'."\0".']'.str_replace('[/*]', '', pun_trim($item)).'[/*'."\0".']'."\n";
  647.     }
  648.  
  649.     return '[list='.$type.']'."\n".$content.'[/list]';
  650. }
  651.  
  652.  
  653. //
  654. // Truncate URL if longer than 55 characters (add http:// or ftp:// if missing)
  655. //
  656. function handle_url_tag($url, $link = '', $bbcode = false)
  657. {
  658.     $url = pun_trim($url);
  659.  
  660.     // Deal with [url][img]http://example.com/test.png[/img][/url]
  661.     if (preg_match('%<img src=\"(.*?)\"%', $url, $matches))
  662.         return handle_url_tag($matches[1], $url, $bbcode);
  663.  
  664.     $full_url = str_replace(array(' ', '\'', '`', '"'), array('%20', '', '', ''), $url);
  665.     if (strpos($url, 'www.') === 0) // If it starts with www, we add http://
  666.         $full_url = 'http://'.$full_url;
  667.     else if (strpos($url, 'ftp.') === 0) // Else if it starts with ftp, we add ftp://
  668.         $full_url = 'ftp://'.$full_url;
  669.     else if (strpos($url, '/') === 0) // Allow for relative URLs that start with a slash
  670.         $full_url = get_base_url(true).$full_url;
  671.     else if (!preg_match('#^([a-z0-9]{3,6})://#', $url)) // Else if it doesn't start with abcdef://, we add http://
  672.         $full_url = 'http://'.$full_url;
  673.  
  674.     // Ok, not very pretty :-)
  675.     if ($bbcode)
  676.     {
  677.         if ($full_url == $link)
  678.             return '[url]'.$link.'[/url]';
  679.         else
  680.             return '[url='.$full_url.']'.$link.'[/url]';
  681.     }
  682.     else
  683.     {
  684.         if ($link == '' || $link == $url)
  685.         {
  686.             $url = pun_htmlspecialchars_decode($url);
  687.             $link = utf8_strlen($url) > 55 ? utf8_substr($url, 0 , 39).' … '.utf8_substr($url, -10) : $url;
  688.             $link = pun_htmlspecialchars($link);
  689.         }
  690.         else
  691.             $link = stripslashes($link);
  692.  
  693.         return '<a href="'.$full_url.'" rel="nofollow">'.$link.'</a>';
  694.     }
  695. }
  696.  
  697.  
  698. //
  699. // Turns an URL from the [img] tag into an <img> tag or a <a href...> tag
  700. //
  701. function handle_img_tag($url, $is_signature = false, $alt = null)
  702. {
  703.     global $lang_common, $pun_user;
  704.  
  705.     if (is_null($alt))
  706.         $alt = basename($url);
  707.  
  708.     $img_tag = '<a href="'.$url.'" rel="nofollow">&lt;'.$lang_common['Image link'].' - '.$alt.'&gt;</a>';
  709.  
  710.     if ($is_signature && $pun_user['show_img_sig'] != '0')
  711.         $img_tag = '<img class="sigimage" src="'.$url.'" alt="'.$alt.'" />';
  712.     else if (!$is_signature && $pun_user['show_img'] != '0')
  713.         $img_tag = '<span class="postimg"><img src="'.$url.'" alt="'.$alt.'" /></span>';
  714.  
  715.     return $img_tag;
  716. }
  717.  
  718.  
  719. //
  720. // Parse the contents of [list] bbcode
  721. //
  722. function handle_list_tag($content, $type = '*')
  723. {
  724.     global $re_list;
  725.  
  726.     if (strlen($type) != 1)
  727.         $type = '*';
  728.  
  729.     if (strpos($content,'[list') !== false)
  730.     {
  731.         $content = preg_replace_callback($re_list, create_function('$matches', 'return handle_list_tag($matches[2], $matches[1]);'), $content);
  732.     }
  733.  
  734.     $content = preg_replace('#\s*\[\*\](.*?)\[/\*\]\s*#s', '<li><p>$1</p></li>', pun_trim($content));
  735.  
  736.     if ($type == '*')
  737.         $content = '<ul>'.$content.'</ul>';
  738.     else
  739.         if ($type == 'a')
  740.             $content = '<ol class="alpha">'.$content.'</ol>';
  741.         else
  742.             $content = '<ol class="decimal">'.$content.'</ol>';
  743.  
  744.     return '</p>'.$content.'<p>';
  745. }
  746.  
  747.  
  748.  
  749.  
  750.  
  751.  
  752. //
  753. // Convert BBCodes to their HTML equivalent
  754. //
  755. function do_bbcode($text, $is_signature = false)
  756. {
  757.    
  758.     global $db, $lang_common, $pun_user, $pun_config, $re_list;
  759.  
  760.     if (strpos($text, '[quote') !== false)
  761.     {
  762.         $text = preg_replace('%\[quote\]\s*%', '</p><div class="quotebox"><blockquote><div><p>', $text);
  763.         $text = preg_replace_callback('%\[quote=(&quot;|&\#039;|"|\'|)(.*?)\\1\]%s', create_function('$matches', 'global $lang_common; return "</p><div class=\"quotebox\"><cite>".str_replace(array(\'[\', \'\\"\'), array(\'&#91;\', \'"\'), $matches[2])." ".$lang_common[\'wrote\']."</cite><blockquote><div><p>";'), $text);
  764.         $text = preg_replace('%\s*\[\/quote\]%S', '</p></div></blockquote></div><p>', $text);
  765.     }
  766.    
  767.     if (strpos($text, '[spoiler') !== false)
  768.     {
  769.         $text = str_replace('[spoiler]', "</p><div class=\"spoiler\"><div onclick=\"var e,d,c=this.parentNode,a=c.getElementsByTagName('div')[1],b=this.getElementsByTagName('span')[0];if(a.style.display!=''){while(c.parentNode&&(!d||!e||d==e)){e=d;d=(window.getComputedStyle?getComputedStyle(c, null):c.currentStyle)['backgroundColor'];if(d=='transparent'||d=='rgba(0, 0, 0, 0)')d=e;c=c.parentNode;}a.style.display='';a.style.backgroundColor=d;b.innerHTML='&#9650;';}else{a.style.display='none';b.innerHTML='&#9660;';}\" style=\"color:#a3a3a3;text-transform:uppercase; cursor: pointer; font-size: 0.9em;\"><span style=\"padding: 0 5px;\">&#9660;</span>".$lang_common['Hidden text']."</div><div style=\"padding: 6px; margin: 0; display: none;\"><p>", $text);
  770.         $text = preg_replace('#\[spoiler=(.*?)\]#s', '</p><div class="spoiler"><div onclick="var e,d,c=this.parentNode,a=c.getElementsByTagName(\'div\')[1],b=this.getElementsByTagName(\'span\')[0];if(a.style.display!=\'\'){while(c.parentNode&&(!d||!e||d==e)){e=d;d=(window.getComputedStyle?getComputedStyle(c, null):c.currentStyle)[\'backgroundColor\'];if(d==\'transparent\'||d==\'rgba(0, 0, 0, 0)\')d=e;c=c.parentNode;}a.style.display=\'\';a.style.backgroundColor=d;b.innerHTML=\'&#9650;\';}else{a.style.display=\'none\';b.innerHTML=\'&#9660;\';}" style="color:#a3a3a3;text-transform:uppercase; cursor: pointer; font-size: 0.9em;"><span style="padding: 0 5px;">&#9660;</span>$1</div><div style="padding: 6px; margin: 0; display: none;"><p>', $text);
  771.         $text = str_replace('[/spoiler]', '</p></div></div><p>', $text);
  772.     }
  773.     if (!$is_signature)
  774.     {
  775.         $pattern_callback[] = $re_list;
  776.         $replace_callback[] = 'handle_list_tag($matches[2], $matches[1])';
  777.     }
  778.  
  779.     $pattern[] = '%\[b\](.*?)\[/b\]%ms';
  780.     $pattern[] = '%\[i\](.*?)\[/i\]%ms';
  781.     $pattern[] = '%\[u\](.*?)\[/u\]%ms';
  782.     $pattern[] = '%\[s\](.*?)\[/s\]%ms';
  783.     $pattern[] = '%\[del\](.*?)\[/del\]%ms';
  784.     $pattern[] = '%\[ins\](.*?)\[/ins\]%ms';
  785.     $pattern[] = '%\[em\](.*?)\[/em\]%ms';
  786.     $pattern[] = '%\[colou?r=([a-zA-Z]{3,20}|\#[0-9a-fA-F]{6}|\#[0-9a-fA-F]{3})](.*?)\[/colou?r\]%ms';
  787.     $pattern[] = '%\[h\](.*?)\[/h\]%ms';
  788.     $pattern[] = '%\[size=([0-9])\](.*?)\[/size\]%ms';
  789.     $pattern[] = '%\[font=(.*?)\](.*?)\[/font\]%ms';
  790.     $pattern[] = '%\[hr\]%ms';
  791.     $pattern[] = '%\[center\](.*?)\[/center\]%ms';
  792.     $pattern[] = '%\[left\](.*?)\[/left\]%ms';
  793.     $pattern[] = '%\[right\](.*?)\[/right\]%ms';
  794.     $pattern[] = '%\[box\](.*?)\[/box\]%ms';
  795.     $pattern[] = '%\[box=([a-zA-Z]{3,20}|\#[0-9a-fA-F]{6}|\#[0-9a-fA-F]{3})\](.*?)\[/box\]%ms';
  796.     $pattern[] = '%\[background=([a-zA-Z]{3,20}|\#[0-9a-fA-F]{6}|\#[0-9a-fA-F]{3})\](.*?)\[/background\]%ms';
  797.     $pattern[] = '#\[table\](.*?)\[/table\]#si';
  798.     $pattern[] = '#\[tr\](.*?)\[/tr\]#si';
  799.     $pattern[] = '#\[td\](.*?)\[/td\]#si';
  800.     $pattern[] = '#\[td=([0-9].*?)\](.*?)\[/td\]#si';
  801.     $pattern[] = '#\[imgwrap left=(.*?)\](.*?)\[/imgwrap\]#s';
  802.     $pattern[] = '#\[imgwrap right=(.*?)\](.*?)\[/imgwrap\]#s';
  803.     $pattern[] = '#\[video\]([-\w]{11})\[/video\]#';
  804.     $pattern[] = '%\[floatright\](.*?)\[/float\]%ms';
  805.     $pattern[] = '%\[floatleft\](.*?)\[/float\]%ms';
  806.  
  807.     $replace[] = '<strong>$1</strong>';
  808.     $replace[] = '<em>$1</em>';
  809.     $replace[] = '<span class="bbu">$1</span>';
  810.     $replace[] = '<span class="bbs">$1</span>';
  811.     $replace[] = '<del>$1</del>';
  812.     $replace[] = '<ins>$1</ins>';
  813.     $replace[] = '<em>$1</em>';
  814.     $replace[] = '<span style="color: $1">$2</span>';
  815.     $replace[] = '</p><h5>$1</h5><p>';
  816.     $replace[] = '<font size="$1">$2</font>';
  817.     $replace[] = '<font face="$1">$2</font>';
  818.     $replace[] = '</p><hr><p>';
  819.     $replace[] = '<div style="text-align: center">$1</div>';
  820.     $replace[] = '<div style="text-align: left">$1</div>';
  821.     $replace[] = '<div style="text-align: right">$1</div>';
  822.     $replace[] = '<div style="border:1px solid #dbdbdb;padding:20px;">$1</div>';
  823.     $replace[] = '<div style="border:1px solid $1;padding:20px;">$2</div>';
  824.     $replace[] = '<div style="background-color:$1;padding:5px;">$2</div>';
  825.     $replace[] = '<div style="margin-top:-300px;" class=\'bbcodetable\'><table width=\'100%\'>\1</table></div>';
  826.     $replace[] = '<tr>\1</tr>';
  827.     $replace[] = '<td>\1</td>';
  828.     $replace[] = '<td colspan=\'\1\'>\2</td>';
  829.     $replace[] = '<img src="$1" align="left" style="margin: 0px 15px;">$2</img>';
  830.     $replace[] = '<img src="$1" align="right" style="margin: 0px 15px; float:right;">$2</img>';
  831.     $replace[] = '<iframe width="600" height="370" src="https://www.youtube.com/embed/$1?rel=0" frameborder="0"></iframe>';
  832.     $replace[] = '<div style="float: left">$1</div>';
  833.     $replace[] = '<div style="float: right">$1</div>';
  834.  
  835.  
  836.     if (($is_signature && $pun_config['p_sig_img_tag'] == '1') || (!$is_signature && $pun_config['p_message_img_tag'] == '1'))
  837.     {
  838.         $pattern_callback[] = '%\[img\]((ht|f)tps?://)([^\s<"]*?)\[/img\]%';
  839.         $pattern_callback[] = '%\[img=([^\[]*?)\]((ht|f)tps?://)([^\s<"]*?)\[/img\]%';
  840.         if ($is_signature)
  841.         {
  842.             $replace_callback[] = 'handle_img_tag($matches[1].$matches[3], true)';
  843.             $replace_callback[] = 'handle_img_tag($matches[2].$matches[4], true, $matches[1])';
  844.         }
  845.         else
  846.         {
  847.             $replace_callback[] = 'handle_img_tag($matches[1].$matches[3], false)';
  848.             $replace_callback[] = 'handle_img_tag($matches[2].$matches[4], false, $matches[1])';
  849.         }
  850.     }
  851.  
  852.     $pattern_callback[] = '%\[url\]([^\[]*?)\[/url\]%';
  853.     $pattern_callback[] = '%\[url=([^\[]+?)\](.*?)\[/url\]%';
  854.     $pattern[] = '%\[email\]([^\[]*?)\[/email\]%';
  855.     $pattern[] = '%\[email=([^\[]+?)\](.*?)\[/email\]%';
  856.     $pattern_callback[] = '%\[topic\]([1-9]\d*)\[/topic\]%';
  857.     $pattern_callback[] = '%\[topic=([1-9]\d*)\](.*?)\[/topic\]%';
  858.     $pattern_callback[] = '%\[post\]([1-9]\d*)\[/post\]%';
  859.     $pattern_callback[] = '%\[post=([1-9]\d*)\](.*?)\[/post\]%';
  860.     $pattern_callback[] = '%\[forum\]([1-9]\d*)\[/forum\]%';
  861.     $pattern_callback[] = '%\[forum=([1-9]\d*)\](.*?)\[/forum\]%';
  862.  
  863.     $replace_callback[] = 'handle_url_tag($matches[1])';
  864.     $replace_callback[] = 'handle_url_tag($matches[1], $matches[2])';
  865.     $replace[] = '<a href="mailto:$1">$1</a>';
  866.     $replace[] = '<a href="mailto:$1">$2</a>';
  867.     $replace_callback[] = 'handle_url_tag(\''.get_base_url(true).'/viewtopic.php?id=\'.$matches[1])';
  868.     $replace_callback[] = 'handle_url_tag(\''.get_base_url(true).'/viewtopic.php?id=\'.$matches[1], $matches[2])';
  869.     $replace_callback[] = 'handle_url_tag(\''.get_base_url(true).'/viewtopic.php?pid=\'.$matches[1].\'#p\'.$matches[1])';
  870.     $replace_callback[] = 'handle_url_tag(\''.get_base_url(true).'/viewtopic.php?pid=\'.$matches[1].\'#p\'.$matches[1], $matches[2])';
  871.     $replace_callback[] = 'handle_url_tag(\''.get_base_url(true).'/viewforum.php?id=\'.$matches[1])';
  872.     $replace_callback[] = 'handle_url_tag(\''.get_base_url(true).'/viewforum.php?id=\'.$matches[1], $matches[2])';
  873.  
  874.     // This thing takes a while! :)
  875.     $text = preg_replace($pattern, $replace, $text);
  876.     $count = count($pattern_callback);
  877.     for($i = 0 ; $i < $count ; $i++)
  878.     {
  879.         $text = preg_replace_callback($pattern_callback[$i], create_function('$matches', 'return '.$replace_callback[$i].';'), $text);
  880.     }
  881.  
  882.     if (strpos($text, '[profil') !== false) {
  883.        
  884.         $username = preg_replace('#(.*?)\[profil\](.*?)\[/profil\](.*?)#si','$2', $text);
  885.         $username = str_replace('</p></div></div><p>', '', $username);
  886.         $username = str_replace('</div>', '', $username);
  887.         $username = str_replace(' ', '', $username);
  888.         $username = str_replace("\n", '', $username);
  889.  
  890.         $result = $db->query('SELECT id,username,num_posts,registered,last_visit,Character1,Character2 FROM '.$db->prefix.'users WHERE username = "'.$db->escape($username).'"');
  891.         $cur_user = $db->fetch_assoc($result);
  892.        
  893.         $reqperso1 = $db->query('SELECT id,Name,Skin FROM server_characters WHERE id = "'.$cur_user['Character1'].'"');
  894.         $cur_perso1 = $db->fetch_assoc($reqperso1);
  895.         $reqperso2 = $db->query('SELECT id,Name,Skin FROM server_characters WHERE id = "'.$cur_user['Character2'].'"');
  896.         $cur_perso2 = $db->fetch_assoc($reqperso2);
  897.        
  898.         $avatar_field = generate_avatar_markup($cur_user['id']);
  899.         if ($avatar_field != '')
  900.             $avatar_profil = $avatar_field;
  901.         else
  902.             $avatar_profil = '<img src="img/avatars/no_avatar.jpg"/>';
  903.  
  904.         $requete = '</p><div id="u_profil_bbcode">'.$avatar_profil.'<div id="u_profil_bbcode_right_content" style="margin-top:12px;"><div id="u_profil_bbcode_pseudo"><a href="profile.php?u='.$cur_user['username'].'">'.$username.'</a></div><a href="pmsnew.php?mdl=post&uid='.$cur_user['id'].'"><div id="u_profil_bbcode_sendmsg"></div></a><div id="u_profil_bbcode_inscription">'.format_time($cur_user['registered'], true).'</div><div id="u_profil_bbcode_dernierecos">'.format_time($cur_user['last_visit'], true).'</div><div id="u_profil_bbcode_messages">'.forum_number_format($cur_user['num_posts']).'</div></div><div id="u_profil_bbcode_right_content_perso" style="margin-left:35px;">'.(($db->num_rows($reqperso1)) ? '<div id="u_profil_perso" style="background: url(./img/skinv2/'.$cur_perso1['Skin'].'.png);background-size: 100px; "><div>'.$cur_perso1['Name'].'</div></div>' : '<div id="u_profil_perso_silou"></div>').''.(($db->num_rows($reqperso2)) ? '<div id="u_profil_perso" style="margin-left:12px;background: url(./img/skinv2/'.$cur_perso2['Skin'].'.png);background-size: 100px; "><div>'.$cur_perso2['Name'].'</div></div>' : '<div id="u_profil_perso_silou"></div>').'</div></div><div style="display:none"><p>';
  905.         $text = preg_replace('%\[profil\]\s*%', $requete, $text);
  906.         $text = str_replace('[/profil]', '</div></p><p>', $text);
  907.     }
  908.  
  909.  
  910.     return $text;
  911. }
  912.  
  913.  
  914. //
  915. // Make hyperlinks clickable
  916. //
  917. function do_clickable($text)
  918. {
  919.     $text = ' '.$text;
  920.     $text = ucp_preg_replace_callback('%(?<=[\s\]\)])(<)?(\[)?(\()?([\'"]?)(https?|ftp|news){1}://([\p{L}\p{N}\-]+\.([\p{L}\p{N}\-]+\.)*[\p{L}\p{N}]+(:[0-9]+)?(/(?:[^\s\[]*[^\s.,?!\[;:-])?)?)\4(?(3)(\)))(?(2)(\]))(?(1)(>))(?![^\s]*\[/(?:url|img)\])%ui', 'stripslashes($matches[1].$matches[2].$matches[3].$matches[4]).handle_url_tag($matches[5]."://".$matches[6], $matches[5]."://".$matches[6], true).stripslashes($matches[4].forum_array_key($matches, 10).forum_array_key($matches, 11).forum_array_key($matches, 12))', $text);
  921.     $text = ucp_preg_replace_callback('%(?<=[\s\]\)])(<)?(\[)?(\()?([\'"]?)(www|ftp)\.(([\p{L}\p{N}\-]+\.)+[\p{L}\p{N}]+(:[0-9]+)?(/(?:[^\s\[]*[^\s.,?!\[;:-])?)?)\4(?(3)(\)))(?(2)(\]))(?(1)(>))(?![^\s]*\[/(?:url|img)\])%ui','stripslashes($matches[1].$matches[2].$matches[3].$matches[4]).handle_url_tag($matches[5].".".$matches[6], $matches[5].".".$matches[6], true).stripslashes($matches[4].forum_array_key($matches, 10).forum_array_key($matches, 11).forum_array_key($matches, 12))', $text);
  922.  
  923.     return substr($text, 1);
  924. }
  925.  
  926.  
  927. //
  928. // Return an array key, if it exists, otherwise return an empty string
  929. //
  930. function forum_array_key($arr, $key)
  931. {
  932.     return isset($arr[$key]) ? $arr[$key] : '';
  933. }
  934.  
  935.  
  936. //
  937. // Convert a series of smilies to images
  938. //
  939. function do_smilies($text)
  940. {
  941.     global $smilies;
  942.  
  943.     $text = ' '.$text.' ';
  944.  
  945.     foreach ($smilies as $smiley_text => $smiley_img)
  946.     {
  947.     list($width, $height, $type, $attr) = getimagesize(pun_htmlspecialchars('img/smilies/'.$smiley_img));
  948.  
  949.         if (strpos($text, $smiley_text) !== false)
  950.             $text = ucp_preg_replace('%(?<=[>\s])'.preg_quote($smiley_text, '%').'(?=[^\p{L}\p{N}])%um', '<img src="'.pun_htmlspecialchars('/img/smilies/'.$smiley_img).'" width="'.$width.'" height="'.$height.'" alt="'.substr($smiley_img, 0, strrpos($smiley_img, '.')).'" />', $text);
  951.     }
  952.  
  953.     return substr($text, 1, -1);
  954. }
  955.  
  956.  
  957. //
  958. // Parse message text
  959. //
  960. function parse_message($text, $hide_smilies)
  961. {
  962.     global $pun_config, $lang_common, $pun_user;
  963.  
  964.     if ($pun_config['o_censoring'] == '1')
  965.         $text = censor_words($text);
  966.  
  967.     // Convert applicable characters to HTML entities
  968.     $text = pun_htmlspecialchars($text);
  969.  
  970.     // If the message contains a code tag we have to split it up (text within [code][/code] shouldn't be touched)
  971.     if (strpos($text, '[code]') !== false && strpos($text, '[/code]') !== false)
  972.         list($inside, $text) = extract_blocks($text, '[code]', '[/code]');
  973.  
  974.     if ($pun_config['p_message_bbcode'] == '1' && strpos($text, '[') !== false && strpos($text, ']') !== false)
  975.         $text = do_bbcode($text);
  976.  
  977.     if ($pun_config['o_smilies'] == '1' && $pun_user['show_smilies'] == '1' && $hide_smilies == '0')
  978.         $text = do_smilies($text);
  979.  
  980.     // Deal with newlines, tabs and multiple spaces
  981.     $pattern = array("\n", "\t", '  ', '  ');
  982.     $replace = array('<br />', '&#160; &#160; ', '&#160; ', ' &#160;');
  983.     $text = str_replace($pattern, $replace, $text);
  984.  
  985.     // If we split up the message before we have to concatenate it together again (code tags)
  986.     if (isset($inside))
  987.     {
  988.         $parts = explode("\1", $text);
  989.         $text = '';
  990.         foreach ($parts as $i => $part)
  991.         {
  992.             $text .= $part;
  993.             if (isset($inside[$i]))
  994.             {
  995.                 $num_lines = (substr_count($inside[$i], "\n"));
  996.                 $text .= '</p><div class="codebox"><pre'.(($num_lines > 28) ? ' class="vscroll"' : '').'><code>'.pun_trim($inside[$i], "\n\r").'</code></pre></div><p>';
  997.             }
  998.         }
  999.     }
  1000.  
  1001.     return clean_paragraphs($text);
  1002. }
  1003.  
  1004.  
  1005. //
  1006. // Clean up paragraphs and line breaks
  1007. //
  1008. function clean_paragraphs($text)
  1009. {
  1010.     // Add paragraph tag around post, but make sure there are no empty paragraphs
  1011.  
  1012.     $text = '<p>'.$text.'</p>';
  1013.  
  1014.     // Replace any breaks next to paragraphs so our replace below catches them
  1015.     $text = preg_replace('%(</?p>)(?:\s*?<br />){1,2}%i', '$1', $text);
  1016.     $text = preg_replace('%(?:<br />\s*?){1,2}(</?p>)%i', '$1', $text);
  1017.  
  1018.     // Remove any empty paragraph tags (inserted via quotes/lists/code/etc) which should be stripped
  1019.     $text = str_replace('<p></p>', '', $text);
  1020.  
  1021.     $text = preg_replace('%<br />\s*?<br />%i', '</p><p>', $text);
  1022.  
  1023.     $text = str_replace('<p><br />', '<br /><p>', $text);
  1024.     $text = str_replace('<br /></p>', '</p><br />', $text);
  1025.     $text = str_replace('<p></p>', '<br /><br />', $text);
  1026.  
  1027.     return $text;
  1028. }
  1029.  
  1030.  
  1031. //
  1032. // Parse signature text
  1033. //
  1034. function parse_signature($text)
  1035. {
  1036.     global $pun_config, $lang_common, $pun_user;
  1037.  
  1038.     if ($pun_config['o_censoring'] == '1')
  1039.         $text = censor_words($text);
  1040.  
  1041.     // Convert applicable characters to HTML entities
  1042.     $text = pun_htmlspecialchars($text);
  1043.  
  1044.     if ($pun_config['p_sig_bbcode'] == '1' && strpos($text, '[') !== false && strpos($text, ']') !== false)
  1045.         $text = do_bbcode($text, true);
  1046.  
  1047.     if ($pun_config['o_smilies_sig'] == '1' && $pun_user['show_smilies'] == '1')
  1048.         $text = do_smilies($text);
  1049.  
  1050.  
  1051.     // Deal with newlines, tabs and multiple spaces
  1052.     $pattern = array("\n", "\t", '  ', '  ');
  1053.     $replace = array('<br />', '&#160; &#160; ', '&#160; ', ' &#160;');
  1054.     $text = str_replace($pattern, $replace, $text);
  1055.  
  1056.     return clean_paragraphs($text);
  1057. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top