'smile.png', '=)' => 'smile.png', ':|' => 'neutral.png', '=|' => 'neutral.png', ':(' => 'sad.png', '=(' => 'sad.png', ':D' => 'big_smile.png', '=D' => 'big_smile.png', ':o' => 'yikes.png', ':O' => 'yikes.png', ';)' => 'wink.png', ':/' => 'hmm.png', ':P' => 'tongue.png', ':p' => 'tongue.png', ':lol:' => 'lol.png', ':mad:' => 'mad.png', ':rolleyes:' => 'roll.png', ':cool:' => 'cool.png'); // // Make sure all BBCodes are lower case and do a little cleanup // function preparse_bbcode($text, &$errors, $is_signature = false) { global $pun_config, $lang_common, $lang_post, $re_list; // Remove empty tags while (($new_text = strip_empty_bbcode($text)) !== false) { if ($new_text != $text) { $text = $new_text; if ($new_text == '') { $errors[] = $lang_post['Empty after strip']; return ''; } } else break; } if ($is_signature) { global $lang_profile; if (preg_match('%\[/?(?:quote|code|list|h)\b[^\]]*\]%i', $text)) $errors[] = $lang_profile['Signature quote/code/list/h']; } // If the message contains a code tag we have to split it up (text within [code][/code] shouldn't be touched) if (strpos($text, '[code]') !== false && strpos($text, '[/code]') !== false) list($inside, $text) = extract_blocks($text, '[code]', '[/code]'); // Tidy up lists $temp = preg_replace_callback($re_list, create_function('$matches', 'return preparse_list_tag($matches[2], $matches[1]);'), $text); // If the regex failed if (is_null($temp)) $errors[] = $lang_common['BBCode list size error']; else $text = str_replace('*'."\0".']', '*]', $temp); if ($pun_config['o_make_links'] == '1') $text = do_clickable($text); $temp_text = false; if (empty($errors)) $temp_text = preparse_tags($text, $errors, $is_signature); if ($temp_text !== false) $text = $temp_text; // If we split up the message before we have to concatenate it together again (code tags) if (isset($inside)) { $outside = explode("\1", $text); $text = ''; $num_tokens = count($outside); for ($i = 0; $i < $num_tokens; ++$i) { $text .= $outside[$i]; if (isset($inside[$i])) $text .= '[code]'.$inside[$i].'[/code]'; } unset($inside); } // Remove empty tags while (($new_text = strip_empty_bbcode($text)) !== false) { if ($new_text != $text) { $text = $new_text; if ($new_text == '') { $errors[] = $lang_post['Empty after strip']; break; } } else break; } return pun_trim($text); } // // Strip empty bbcode tags from some text // function strip_empty_bbcode($text) { // If the message contains a code tag we have to split it up (empty tags within [code][/code] are fine) if (strpos($text, '[code]') !== false && strpos($text, '[/code]') !== false) list($inside, $text) = extract_blocks($text, '[code]', '[/code]'); // Remove empty tags while (!is_null($new_text = preg_replace('%\[(b|u|s|ins|del|em|i|h|colou?r|quote|img|url|email|list|topic|post|forum|user)(?:\=[^\]]*)?\]\s*\[/\1\]%', '', $text))) { if ($new_text != $text) $text = $new_text; else break; } // If we split up the message before we have to concatenate it together again (code tags) if (isset($inside)) { $parts = explode("\1", $text); $text = ''; foreach ($parts as $i => $part) { $text .= $part; if (isset($inside[$i])) $text .= '[code]'.$inside[$i].'[/code]'; } } // Remove empty code tags while (!is_null($new_text = preg_replace('%\[(code)\]\s*\[/\1\]%', '', $text))) { if ($new_text != $text) $text = $new_text; else break; } return $text; } // // Check the structure of bbcode tags and fix simple mistakes where possible // function preparse_tags($text, &$errors, $is_signature = false) { global $lang_common, $pun_config, $pun_user; // Start off by making some arrays of bbcode tags and what we need to do with each one // List of all the tags $tags = array('quote', 'code', 'b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'img', 'list', '*', 'h', 'topic', 'post', 'forum', 'user'); // 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) $tags_opened = $tags; // and tags we need to check are closed (the same as above, added it just in case) $tags_closed = $tags; // Tags we can nest and the depth they can be nested to $tags_nested = array('quote' => $pun_config['o_quote_depth'], 'list' => 5, '*' => 5); // Tags to ignore the contents of completely (just code) $tags_ignore = array('code'); // Tags not allowed $tags_forbidden = array(); // Block tags, block tags can only go within another block tag, they cannot be in a normal tag $tags_block = array('quote', 'code', 'list', 'h', '*'); // Inline tags, we do not allow new lines in these $tags_inline = array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'h', 'topic', 'post', 'forum', 'user'); // Tags we trim interior space $tags_trim = array('img'); // Tags we remove quotes from the argument $tags_quotes = array('url', 'email', 'img', 'topic', 'post', 'forum', 'user'); // Tags we limit bbcode in $tags_limit_bbcode = array( '*' => array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'list', 'img', 'code', 'topic', 'post', 'forum', 'user'), 'list' => array('*'), 'url' => array('img'), 'email' => array('img'), 'topic' => array('img'), 'post' => array('img'), 'forum' => array('img'), 'user' => array('img'), 'img' => array(), 'h' => array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'topic', 'post', 'forum', 'user'), ); // Tags we can automatically fix bad nesting $tags_fix = array('quote', 'b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'h', 'topic', 'post', 'forum', 'user'); // Disallow URL tags if ($pun_user['g_post_links'] != '1') $tags_forbidden[] = 'url'; $split_text = preg_split('%(\[[\*a-zA-Z0-9-/]*?(?:=.*?)?\])%', $text, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); $open_tags = array('fluxbb-bbcode'); $open_args = array(''); $opened_tag = 0; $new_text = ''; $current_ignore = ''; $current_nest = ''; $current_depth = array(); $limit_bbcode = $tags; $count_ignored = array(); foreach ($split_text as $current) { if ($current == '') continue; // Are we dealing with a tag? if (substr($current, 0, 1) != '[' || substr($current, -1, 1) != ']') { // It's not a bbcode tag so we put it on the end and continue // If we are nested too deeply don't add to the end if ($current_nest) continue; $current = str_replace("\r\n", "\n", $current); $current = str_replace("\r", "\n", $current); if (in_array($open_tags[$opened_tag], $tags_inline) && strpos($current, "\n") !== false) { // Deal with new lines $split_current = preg_split('%(\n\n+)%', $current, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); $current = ''; if (!pun_trim($split_current[0], "\n")) // The first part is a linebreak so we need to handle any open tags first array_unshift($split_current, ''); for ($i = 1; $i < count($split_current); $i += 2) { $temp_opened = array(); $temp_opened_arg = array(); $temp = $split_current[$i - 1]; while (!empty($open_tags)) { $temp_tag = array_pop($open_tags); $temp_arg = array_pop($open_args); if (in_array($temp_tag , $tags_inline)) { array_push($temp_opened, $temp_tag); array_push($temp_opened_arg, $temp_arg); $temp .= '[/'.$temp_tag.']'; } else { array_push($open_tags, $temp_tag); array_push($open_args, $temp_arg); break; } } $current .= $temp.$split_current[$i]; $temp = ''; while (!empty($temp_opened)) { $temp_tag = array_pop($temp_opened); $temp_arg = array_pop($temp_opened_arg); if (empty($temp_arg)) $temp .= '['.$temp_tag.']'; else $temp .= '['.$temp_tag.'='.$temp_arg.']'; array_push($open_tags, $temp_tag); array_push($open_args, $temp_arg); } $current .= $temp; } if (array_key_exists($i - 1, $split_current)) $current .= $split_current[$i - 1]; } if (in_array($open_tags[$opened_tag], $tags_trim)) $new_text .= pun_trim($current); else $new_text .= $current; continue; } // Get the name of the tag $current_arg = ''; if (strpos($current, '/') === 1) { $current_tag = substr($current, 2, -1); } else if (strpos($current, '=') === false) { $current_tag = substr($current, 1, -1); } else { $current_tag = substr($current, 1, strpos($current, '=')-1); $current_arg = substr($current, strpos($current, '=')+1, -1); } $current_tag = strtolower($current_tag); // Is the tag defined? if (!in_array($current_tag, $tags)) { // It's not a bbcode tag so we put it on the end and continue if (!$current_nest) $new_text .= $current; continue; } // We definitely have a bbcode tag // Make the tag string lower case if ($equalpos = strpos($current,'=')) { // We have an argument for the tag which we don't want to make lowercase if (strlen(substr($current, $equalpos)) == 2) { // Empty tag argument $errors[] = sprintf($lang_common['BBCode error empty attribute'], $current_tag); return false; } $current = strtolower(substr($current, 0, $equalpos)).substr($current, $equalpos); } else $current = strtolower($current); // This is if we are currently in a tag which escapes other bbcode such as code // We keep a count of ignored bbcodes (code tags) so we can nest them, but // only balanced sets of tags can be nested if ($current_ignore) { // Increase the current ignored tags counter if ('['.$current_ignore.']' == $current) $count_ignored[$current_tag]++; // Decrease the current ignored tags counter if ('[/'.$current_ignore.']' == $current) $count_ignored[$current_tag]--; if ('[/'.$current_ignore.']' == $current && $count_ignored[$current_tag] == 0) { // We've finished the ignored section $current = '[/'.$current_tag.']'; $current_ignore = ''; $count_ignored = array(); } $new_text .= $current; continue; } // Is the tag forbidden? if (in_array($current_tag, $tags_forbidden)) { if (isset($lang_common['BBCode error tag '.$current_tag.' not allowed'])) $errors[] = sprintf($lang_common['BBCode error tag '.$current_tag.' not allowed']); else $errors[] = sprintf($lang_common['BBCode error tag not allowed'], $current_tag); return false; } if ($current_nest) { // We are currently too deeply nested so lets see if we are closing the tag or not if ($current_tag != $current_nest) continue; if (substr($current, 1, 1) == '/') $current_depth[$current_nest]--; else $current_depth[$current_nest]++; if ($current_depth[$current_nest] <= $tags_nested[$current_nest]) $current_nest = ''; continue; } // Check the current tag is allowed here if (!in_array($current_tag, $limit_bbcode) && $current_tag != $open_tags[$opened_tag]) { $errors[] = sprintf($lang_common['BBCode error invalid nesting'], $current_tag, $open_tags[$opened_tag]); return false; } if (substr($current, 1, 1) == '/') { // This is if we are closing a tag if ($opened_tag == 0 || !in_array($current_tag, $open_tags)) { // We tried to close a tag which is not open if (in_array($current_tag, $tags_opened)) { $errors[] = sprintf($lang_common['BBCode error no opening tag'], $current_tag); return false; } } else { // Check nesting while (true) { // Nesting is ok if ($open_tags[$opened_tag] == $current_tag) { array_pop($open_tags); array_pop($open_args); $opened_tag--; break; } // Nesting isn't ok, try to fix it if (in_array($open_tags[$opened_tag], $tags_closed) && in_array($current_tag, $tags_closed)) { if (in_array($current_tag, $open_tags)) { $temp_opened = array(); $temp_opened_arg = array(); $temp = ''; while (!empty($open_tags)) { $temp_tag = array_pop($open_tags); $temp_arg = array_pop($open_args); if (!in_array($temp_tag, $tags_fix)) { // We couldn't fix nesting $errors[] = sprintf($lang_common['BBCode error no closing tag'], $temp_tag); return false; } array_push($temp_opened, $temp_tag); array_push($temp_opened_arg, $temp_arg); if ($temp_tag == $current_tag) break; else $temp .= '[/'.$temp_tag.']'; } $current = $temp.$current; $temp = ''; array_pop($temp_opened); array_pop($temp_opened_arg); while (!empty($temp_opened)) { $temp_tag = array_pop($temp_opened); $temp_arg = array_pop($temp_opened_arg); if (empty($temp_arg)) $temp .= '['.$temp_tag.']'; else $temp .= '['.$temp_tag.'='.$temp_arg.']'; array_push($open_tags, $temp_tag); array_push($open_args, $temp_arg); } $current .= $temp; $opened_tag--; break; } else { // We couldn't fix nesting $errors[] = sprintf($lang_common['BBCode error no opening tag'], $current_tag); return false; } } else if (in_array($open_tags[$opened_tag], $tags_closed)) break; else { array_pop($open_tags); array_pop($open_args); $opened_tag--; } } } if (in_array($current_tag, array_keys($tags_nested))) { if (isset($current_depth[$current_tag])) $current_depth[$current_tag]--; } if (in_array($open_tags[$opened_tag], array_keys($tags_limit_bbcode))) $limit_bbcode = $tags_limit_bbcode[$open_tags[$opened_tag]]; else $limit_bbcode = $tags; $new_text .= $current; continue; } else { // We are opening a tag if (in_array($current_tag, array_keys($tags_limit_bbcode))) $limit_bbcode = $tags_limit_bbcode[$current_tag]; else $limit_bbcode = $tags; if (in_array($current_tag, $tags_block) && !in_array($open_tags[$opened_tag], $tags_block) && $opened_tag != 0) { // We tried to open a block tag within a non-block tag $errors[] = sprintf($lang_common['BBCode error invalid nesting'], $current_tag, $open_tags[$opened_tag]); return false; } if (in_array($current_tag, $tags_ignore)) { // It's an ignore tag so we don't need to worry about what's inside it $current_ignore = $current_tag; $count_ignored[$current_tag] = 1; $new_text .= $current; continue; } // Deal with nested tags if (in_array($current_tag, $open_tags) && !in_array($current_tag, array_keys($tags_nested))) { // We nested a tag we shouldn't $errors[] = sprintf($lang_common['BBCode error invalid self-nesting'], $current_tag); return false; } else if (in_array($current_tag, array_keys($tags_nested))) { // We are allowed to nest this tag if (isset($current_depth[$current_tag])) $current_depth[$current_tag]++; else $current_depth[$current_tag] = 1; // See if we are nested too deep if ($current_depth[$current_tag] > $tags_nested[$current_tag]) { $current_nest = $current_tag; continue; } } // Remove quotes from arguments for certain tags if (strpos($current, '=') !== false && in_array($current_tag, $tags_quotes)) { $current = preg_replace('%\['.$current_tag.'=("|\'|)(.*?)\\1\]\s*%i', '['.$current_tag.'=$2]', $current); } if (in_array($current_tag, array_keys($tags_limit_bbcode))) $limit_bbcode = $tags_limit_bbcode[$current_tag]; $open_tags[] = $current_tag; $open_args[] = $current_arg; $opened_tag++; $new_text .= $current; continue; } } // Check we closed all the tags we needed to foreach ($tags_closed as $check) { if (in_array($check, $open_tags)) { // We left an important tag open $errors[] = sprintf($lang_common['BBCode error no closing tag'], $check); return false; } } if ($current_ignore) { // We left an ignore tag open $errors[] = sprintf($lang_common['BBCode error no closing tag'], $current_ignore); return false; } return $new_text; } // // Preparse the contents of [list] bbcode // function preparse_list_tag($content, $type = '*') { global $lang_common, $re_list; if (strlen($type) != 1) $type = '*'; if (strpos($content,'[list') !== false) { $content = preg_replace_callback($re_list, create_function('$matches', 'return preparse_list_tag($matches[2], $matches[1]);'), $content); } $items = explode('[*]', str_replace('\"', '"', $content)); $content = ''; foreach ($items as $item) { if (pun_trim($item) != '') $content .= '[*'."\0".']'.str_replace('[/*]', '', pun_trim($item)).'[/*'."\0".']'."\n"; } return '[list='.$type.']'."\n".$content.'[/list]'; } // // Truncate URL if longer than 55 characters (add http:// or ftp:// if missing) // function handle_url_tag($url, $link = '', $bbcode = false) { $url = pun_trim($url); // Deal with [url][img]http://example.com/test.png[/img][/url] if (preg_match('% 55 ? utf8_substr($url, 0 , 39).' … '.utf8_substr($url, -10) : $url; $link = pun_htmlspecialchars($link); } else $link = stripslashes($link); return ''.$link.''; } } // // Turns an URL from the [img] tag into an tag or a tag // function handle_img_tag($url, $is_signature = false, $alt = null) { global $lang_common, $pun_user; if (is_null($alt)) $alt = basename($url); $img_tag = '<'.$lang_common['Image link'].' - '.$alt.'>'; if ($is_signature && $pun_user['show_img_sig'] != '0') $img_tag = ''.$alt.''; else if (!$is_signature && $pun_user['show_img'] != '0') $img_tag = ''.$alt.''; return $img_tag; } // // Parse the contents of [list] bbcode // function handle_list_tag($content, $type = '*') { global $re_list; if (strlen($type) != 1) $type = '*'; if (strpos($content,'[list') !== false) { $content = preg_replace_callback($re_list, create_function('$matches', 'return handle_list_tag($matches[2], $matches[1]);'), $content); } $content = preg_replace('#\s*\[\*\](.*?)\[/\*\]\s*#s', '
  • $1

  • ', pun_trim($content)); if ($type == '*') $content = ''; else if ($type == 'a') $content = '
      '.$content.'
    '; else $content = '
      '.$content.'
    '; return '

    '.$content.'

    '; } // // Convert BBCodes to their HTML equivalent // function do_bbcode($text, $is_signature = false) { global $lang_common, $pun_user, $pun_config, $re_list; if (strpos($text, '[quote') !== false) { $text = preg_replace('%\[quote\]\s*%', '

    ', $text); $text = preg_replace_callback('%\[quote=("|&\#039;|"|\'|)([^\r\n]*?)\\1\]%s', create_function('$matches', 'global $lang_common; return "

    ".str_replace(array(\'[\', \'\\"\'), array(\'[\', \'"\'), $matches[2])." ".$lang_common[\'wrote\']."

    ";'), $text); $text = preg_replace('%\s*\[\/quote\]%S', '

    ', $text); } if (!$is_signature) { $pattern_callback[] = $re_list; $replace_callback[] = 'handle_list_tag($matches[2], $matches[1])'; } $pattern[] = '%\[b\](.*?)\[/b\]%ms'; $pattern[] = '%\[i\](.*?)\[/i\]%ms'; $pattern[] = '%\[u\](.*?)\[/u\]%ms'; $pattern[] = '%\[s\](.*?)\[/s\]%ms'; $pattern[] = '%\[del\](.*?)\[/del\]%ms'; $pattern[] = '%\[ins\](.*?)\[/ins\]%ms'; $pattern[] = '%\[em\](.*?)\[/em\]%ms'; $pattern[] = '%\[colou?r=([a-zA-Z]{3,20}|\#[0-9a-fA-F]{6}|\#[0-9a-fA-F]{3})](.*?)\[/colou?r\]%ms'; $pattern[] = '%\[h\](.*?)\[/h\]%ms'; $replace[] = '$1'; $replace[] = '$1'; $replace[] = '$1'; $replace[] = '$1'; $replace[] = '$1'; $replace[] = '$1'; $replace[] = '$1'; $replace[] = '$2'; $replace[] = '

    $1

    '; if (($is_signature && $pun_config['p_sig_img_tag'] == '1') || (!$is_signature && $pun_config['p_message_img_tag'] == '1')) { $pattern_callback[] = '%\[img\]((ht|f)tps?://)([^\s<"]*?)\[/img\]%'; $pattern_callback[] = '%\[img=([^\[]*?)\]((ht|f)tps?://)([^\s<"]*?)\[/img\]%'; if ($is_signature) { $replace_callback[] = 'handle_img_tag($matches[1].$matches[3], true)'; $replace_callback[] = 'handle_img_tag($matches[2].$matches[4], true, $matches[1])'; } else { $replace_callback[] = 'handle_img_tag($matches[1].$matches[3], false)'; $replace_callback[] = 'handle_img_tag($matches[2].$matches[4], false, $matches[1])'; } } $pattern_callback[] = '%\[url\]([^\[]*?)\[/url\]%'; $pattern_callback[] = '%\[url=([^\[]+?)\](.*?)\[/url\]%'; $pattern[] = '%\[email\]([^\[]*?)\[/email\]%'; $pattern[] = '%\[email=([^\[]+?)\](.*?)\[/email\]%'; $pattern_callback[] = '%\[topic\]([1-9]\d*)\[/topic\]%'; $pattern_callback[] = '%\[topic=([1-9]\d*)\](.*?)\[/topic\]%'; $pattern_callback[] = '%\[post\]([1-9]\d*)\[/post\]%'; $pattern_callback[] = '%\[post=([1-9]\d*)\](.*?)\[/post\]%'; $pattern_callback[] = '%\[forum\]([1-9]\d*)\[/forum\]%'; $pattern_callback[] = '%\[forum=([1-9]\d*)\](.*?)\[/forum\]%'; $pattern_callback[] = '%\[user\]([1-9]\d*)\[/user\]%'; $pattern_callback[] = '%\[user=([1-9]\d*)\](.*?)\[/user\]%'; $replace_callback[] = 'handle_url_tag($matches[1])'; $replace_callback[] = 'handle_url_tag($matches[1], $matches[2])'; $replace[] = '$1'; $replace[] = '$2'; $replace_callback[] = 'handle_url_tag(\''.get_base_url(true).'/viewtopic.php?id=\'.$matches[1])'; $replace_callback[] = 'handle_url_tag(\''.get_base_url(true).'/viewtopic.php?id=\'.$matches[1], $matches[2])'; $replace_callback[] = 'handle_url_tag(\''.get_base_url(true).'/viewtopic.php?pid=\'.$matches[1].\'#p\'.$matches[1])'; $replace_callback[] = 'handle_url_tag(\''.get_base_url(true).'/viewtopic.php?pid=\'.$matches[1].\'#p\'.$matches[1], $matches[2])'; $replace_callback[] = 'handle_url_tag(\''.get_base_url(true).'/viewforum.php?id=\'.$matches[1])'; $replace_callback[] = 'handle_url_tag(\''.get_base_url(true).'/viewforum.php?id=\'.$matches[1], $matches[2])'; $replace_callback[] = 'handle_url_tag(\''.get_base_url(true).'/profile.php?id=\'.$matches[1])'; $replace_callback[] = 'handle_url_tag(\''.get_base_url(true).'/profile.php?id=\'.$matches[1], $matches[2])'; // This thing takes a while! :) $text = preg_replace($pattern, $replace, $text); $count = count($pattern_callback); for($i = 0 ; $i < $count ; $i++) { $text = preg_replace_callback($pattern_callback[$i], create_function('$matches', 'return '.$replace_callback[$i].';'), $text); } return $text; } // // Make hyperlinks clickable // function do_clickable($text) { $text = ' '.$text; $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); $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); return substr($text, 1); } // // Return an array key, if it exists, otherwise return an empty string // function forum_array_key($arr, $key) { return isset($arr[$key]) ? $arr[$key] : ''; } // // Convert a series of smilies to images // function do_smilies($text) { global $smilies; $text = ' '.$text.' '; foreach ($smilies as $smiley_text => $smiley_img) { if (strpos($text, $smiley_text) !== false) $text = ucp_preg_replace('%(?<=[>\s])'.preg_quote($smiley_text, '%').'(?=[^\p{L}\p{N}])%um', ''.substr($smiley_img, 0, strrpos($smiley_img, '.')).'', $text); } return substr($text, 1, -1); } // // Parse message text // function parse_message($text, $hide_smilies) { global $pun_config, $lang_common, $pun_user; if ($pun_config['o_censoring'] == '1') $text = censor_words($text); // Convert applicable characters to HTML entities $text = pun_htmlspecialchars($text); // If the message contains a code tag we have to split it up (text within [code][/code] shouldn't be touched) if (strpos($text, '[code]') !== false && strpos($text, '[/code]') !== false) list($inside, $text) = extract_blocks($text, '[code]', '[/code]'); if ($pun_config['p_message_bbcode'] == '1' && strpos($text, '[') !== false && strpos($text, ']') !== false) $text = do_bbcode($text); if ($pun_config['o_smilies'] == '1' && $pun_user['show_smilies'] == '1' && $hide_smilies == '0') $text = do_smilies($text); // Deal with newlines, tabs and multiple spaces $pattern = array("\n", "\t", ' ', ' '); $replace = array('
    ', '    ', '  ', '  '); $text = str_replace($pattern, $replace, $text); // If we split up the message before we have to concatenate it together again (code tags) if (isset($inside)) { $parts = explode("\1", $text); $text = ''; foreach ($parts as $i => $part) { $text .= $part; if (isset($inside[$i])) { $num_lines = (substr_count($inside[$i], "\n")); $text .= '

    28) ? ' class="vscroll"' : '').'>'.pun_trim($inside[$i], "\n\r").'

    '; } } } return clean_paragraphs($text); } // // Clean up paragraphs and line breaks // function clean_paragraphs($text) { // Add paragraph tag around post, but make sure there are no empty paragraphs $text = '

    '.$text.'

    '; // Replace any breaks next to paragraphs so our replace below catches them $text = preg_replace('%()(?:\s*?
    ){1,2}%i', '$1', $text); $text = preg_replace('%(?:
    \s*?){1,2}()%i', '$1', $text); // Remove any empty paragraph tags (inserted via quotes/lists/code/etc) which should be stripped $text = str_replace('

    ', '', $text); $text = preg_replace('%
    \s*?
    %i', '

    ', $text); $text = str_replace('


    ', '

    ', $text); $text = str_replace('

    ', '


    ', $text); $text = str_replace('

    ', '

    ', $text); return $text; } // // Parse signature text // function parse_signature($text) { global $pun_config, $lang_common, $pun_user; if ($pun_config['o_censoring'] == '1') $text = censor_words($text); // Convert applicable characters to HTML entities $text = pun_htmlspecialchars($text); if ($pun_config['p_sig_bbcode'] == '1' && strpos($text, '[') !== false && strpos($text, ']') !== false) $text = do_bbcode($text, true); if ($pun_config['o_smilies_sig'] == '1' && $pun_user['show_smilies'] == '1') $text = do_smilies($text); // Deal with newlines, tabs and multiple spaces $pattern = array("\n", "\t", ' ', ' '); $replace = array('
    ', '    ', '  ', '  '); $text = str_replace($pattern, $replace, $text); return clean_paragraphs($text); }