[ Index ] |
PHP Cross Reference of MyBB |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * MyBB 1.6 4 * Copyright 2010 MyBB Group, All Rights Reserved 5 * 6 * Website: http://mybb.com 7 * License: http://mybb.com/about/license 8 * 9 * $Id: functions_posting.php 5623 2011-10-01 02:46:09Z ralgith $ 10 */ 11 12 /** 13 * Selectively removes quote tags from a message, depending on its nested depth. This is to be used with reply with quote functions. 14 * For malformed quote tag structures, will try to simulate how MyBB's parser handles the issue, but is slightly inaccurate. 15 * Examples, with a cutoff depth of 2: 16 * #1. INPUT: [quote]a[quote=me]b[quote]c[/quote][/quote][/quote] 17 * OUTPUT: [quote]a[quote=me]b[/quote][/quote] 18 * #2. INPUT: [quote=a][quote=b][quote=c][quote=d][/quote][quote=e][/quote][/quote][quote=f][/quote][/quote] 19 * OUTPUT: [quote=a][quote=b][/quote][quote=f][/quote][/quote] 20 * 21 * @param string the message from which quotes are to be removed 22 * @param integer nested depth at which quotes should be removed; if none supplied, will use MyBB's default; must be at least 0 23 * @return string the original message passed in $text, but with quote tags selectively removed 24 */ 25 function remove_message_quotes(&$text, $rmdepth=null) 26 { 27 if(!$text) 28 { 29 return $text; 30 } 31 if(!isset($rmdepth)) 32 { 33 global $mybb; 34 $rmdepth = $mybb->settings['maxquotedepth']; 35 } 36 $rmdepth = intval($rmdepth); 37 38 // find all tokens 39 // note, at various places, we use the prefix "s" to denote "start" (ie [quote]) and "e" to denote "end" (ie [/quote]) 40 preg_match_all("#\[quote(=(?:"|\"|')?.*?(?:"|\"|')?)?\]#si", $text, $smatches, PREG_OFFSET_CAPTURE | PREG_PATTERN_ORDER); 41 preg_match_all("#\[/quote\]#i", $text, $ematches, PREG_OFFSET_CAPTURE | PREG_PATTERN_ORDER); 42 43 if(empty($smatches) || empty($ematches)) 44 { 45 return $text; 46 } 47 48 // make things easier by only keeping offsets 49 $soffsets = $eoffsets = array(); 50 foreach($smatches[0] as $id => $match) 51 { 52 $soffsets[] = $match[1]; 53 } 54 // whilst we loop, also remove unnecessary end tokens at the start of string 55 $first_token = $soffsets[0]; 56 foreach($ematches[0] as $id => $match) 57 { 58 if($match[1] > $first_token) 59 { 60 $eoffsets[] = $match[1]; 61 } 62 } 63 unset($smatches, $ematches); 64 65 66 // elmininate malformed quotes by parsing like the parser does (preg_replace in a while loop) 67 // NOTE: this is slightly inaccurate because the parser considers [quote] and [quote=...] to be different things 68 $good_offsets = array(); 69 while(!empty($soffsets) && !empty($eoffsets)) // don't rely on this condition - an end offset before the start offset will cause this to loop indefinitely 70 { 71 $last_offset = 0; 72 foreach($soffsets as $sk => &$soffset) 73 { 74 if($soffset >= $last_offset) 75 { 76 // search for corresponding eoffset 77 foreach($eoffsets as $ek => &$eoffset) // use foreach instead of for to get around indexing issues with unset 78 { 79 if($eoffset > $soffset) 80 { 81 // we've found a pair 82 $good_offsets[$soffset] = 1; 83 $good_offsets[$eoffset] = -1; 84 $last_offset = $eoffset; 85 86 unset($soffsets[$sk], $eoffsets[$ek]); 87 break; 88 } 89 } 90 } 91 } 92 93 // remove any end offsets occurring before start offsets 94 $first_start = reset($soffsets); 95 foreach($eoffsets as $ek => &$eoffset) 96 { 97 if($eoffset < $first_start) 98 { 99 unset($eoffsets[$ek]); 100 } 101 else 102 { 103 break; 104 } 105 } 106 // we don't need to remove start offsets after the last end offset, because the loop will deplete something before that 107 } 108 109 110 if(empty($good_offsets)) 111 { 112 return $text; 113 } 114 ksort($good_offsets); 115 116 117 // we now have a list of all the ordered tokens, ready to go through 118 $depth = 0; 119 $remove_regions = array(); 120 $tmp_start = 0; 121 foreach($good_offsets as $offset => $dincr) 122 { 123 if($depth == $rmdepth && $dincr == 1) 124 { 125 $tmp_start = $offset; 126 } 127 $depth += $dincr; 128 if($depth == $rmdepth && $dincr == -1) 129 { 130 $remove_regions[] = array($tmp_start, $offset); 131 } 132 } 133 134 if(empty($remove_regions)) 135 { 136 return $text; 137 } 138 139 // finally, remove the quotes from the string 140 $newtext = ''; 141 $cpy_start = 0; 142 foreach($remove_regions as &$region) 143 { 144 $newtext .= substr($text, $cpy_start, $region[0]-$cpy_start); 145 $cpy_start = $region[1]+8; // 8 = strlen('[/quote]') 146 // clean up newlines 147 $next_char = $text{$region[1]+8}; 148 if($next_char == "\r" || $next_char == "\n") 149 { 150 ++$cpy_start; 151 if($next_char == "\r" && $text{$region[1]+9} == "\n") 152 { 153 ++$cpy_start; 154 } 155 } 156 } 157 // append remaining end text 158 if(strlen($text) != $cpy_start) 159 { 160 $newtext .= substr($text, $cpy_start); 161 } 162 163 164 // we're done 165 return $newtext; 166 } 167 168 169 /** 170 * Performs cleanup of a quoted message, such as replacing /me commands, before presenting quoted post to the user. 171 * 172 * @param array quoted post info, taken from the DB (requires the 'message', 'username', 'pid' and 'dateline' entries to be set; will use 'userusername' if present) 173 * @param boolean whether to call remove_message_quotes() on the quoted message 174 * @return string the cleaned up message, wrapped in a quote tag 175 */ 176 177 function parse_quoted_message(&$quoted_post, $remove_message_quotes=true) 178 { 179 global $parser, $lang, $plugins; 180 if(!isset($parser)) 181 { 182 require_once MYBB_ROOT."inc/class_parser.php"; 183 $parser = new postParser; 184 } 185 186 // Swap username over if we have a registered user 187 if($quoted_post['userusername']) 188 { 189 $quoted_post['username'] = $quoted_post['userusername']; 190 } 191 // Clean up the message 192 $quoted_post['message'] = preg_replace(array( 193 '#(^|\r|\n)/me ([^\r\n<]*)#i', 194 '#(^|\r|\n)/slap ([^\r\n<]*)#i', 195 '#\[attachment=([0-9]+?)\]#i' 196 ), array( 197 "\\1* {$quoted_post['username']} \\2", 198 "\\1* {$quoted_post['username']} {$lang->slaps} \\2 {$lang->with_trout}", 199 "", 200 ), $quoted_post['message']); 201 $quoted_post['message'] = $parser->parse_badwords($quoted_post['message']); 202 203 if($remove_message_quotes) 204 { 205 global $mybb; 206 $max_quote_depth = intval($mybb->settings['maxquotedepth']); 207 if($max_quote_depth) 208 { 209 $quoted_post['message'] = remove_message_quotes($quoted_post['message'], $max_quote_depth-1); // we're wrapping the message in a [quote] tag, so take away one quote depth level 210 } 211 } 212 213 $quoted_post = $plugins->run_hooks("parse_quoted_message", $quoted_post); 214 215 return "[quote='{$quoted_post['username']}' pid='{$quoted_post['pid']}' dateline='{$quoted_post['dateline']}']\n{$quoted_post['message']}\n[/quote]\n\n"; 216 } 217 218 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Oct 8 19:19:50 2013 | Cross-referenced by PHPXref 0.7.1 |