Campustream 1.0
A social network MQP for WPI
|
00001 <? 00002 00008 class bbparser{ 00009 private $isOsimo; 00010 private $simple_bbcodes; 00011 private $fancy_bbcodes; 00012 private $allowedCSS; 00013 00014 public static function bb2html($bb) { 00015 $parser = new bbparser(); 00016 return $parser->parse($bb); 00017 } 00018 00019 public function bbparser(){ 00020 $this->isOsimo = false; 00021 00022 $this->loadDefaults(); 00023 } 00024 00025 private function loadDefaults(){ 00026 $simple_defaults = array( 00027 "b"=>array( 00028 "search"=>"/\[b\](.+?)\[\/b\]/is", 00029 "replace"=>'<strong>$1</strong>' 00030 ), 00031 "i"=>array( 00032 "search"=>"/\[i\](.+?)\[\/i\]/is", 00033 "replace"=>'<i>$1</i>' 00034 ), 00035 "u"=>array( 00036 "search"=>"/\[u\](.+?)\[\/u\]/is", 00037 "replace"=>'<u>$1</u>' 00038 ), 00039 "s"=>array( 00040 'search'=>"/\[s\](.+?)\[\/s\]/is", 00041 'replace'=>'<span style="text-decoration:line-through">$1</span>' 00042 ), 00043 "url"=>array( 00044 "search"=>"/\[url\](.+?)\[\/url\]/is", 00045 "replace"=>'<a target="_blank" href="$1">$1</a>' 00046 ), 00047 "img"=>array( 00048 "search"=>"/\[img\](.+?)\[\/img\]/is", 00049 "replace"=>'<img src="$1" />' 00050 ), 00051 "quote"=>array( 00052 "search"=>"/\[quote\](.+?)\[\/quote\]/is", 00053 "replace"=>'<blockquote><span class="blockquote-title">Quote:</span><br/>$1</blockquote>' 00054 ), 00055 'code'=>array( 00056 'search'=>"/\[code\](.+?)\[\/code\]/is", 00057 'replace'=>'<pre class="code"><code class="plain">$1</code></pre>' 00058 ), 00059 'right'=>array( 00060 'search'=>"/\[right\](.+?)\[\/right\]/is", 00061 'replace'=>'<div style="text-align:right">$1</div>' 00062 ), 00063 'center'=>array( 00064 'search'=>"/\[center\](.+?)\[\/center\]/is", 00065 'replace'=>'<div style="text-align:center">$1</div>' 00066 ), 00067 'left'=>array( 00068 'search'=>"/\[left\](.+?)\[\/left\]/is", 00069 'replace'=>'<div style="text-align:left">$1</div>' 00070 ), 00071 'list'=>array( 00072 'search'=>"/\[list\](.+?)\[\/list\]/is", 00073 'replace'=>'<ul>$1</ul>' 00074 ), 00075 '[*]'=>array( 00076 'search'=>"/\[\*\]([^\n|\r]+)/is", 00077 'replace'=>'<li>$1</li>' 00078 ), 00079 'table'=>array( 00080 'search'=>"/\[table\](.+?)\[\/table\]/is", 00081 'replace'=>'<table>$1</table>' 00082 ), 00083 'row'=>array( 00084 'search'=>"/\[row\](.+?)\[\/row\]/is", 00085 'replace'=>'<tr>$1</tr>' 00086 ), 00087 'cell'=>array( 00088 'search'=>"/\[cell\](.+?)\[\/cell\]/is", 00089 'replace'=>'<td>$1</td>' 00090 ), 00091 'spoiler'=>array( 00092 'search'=>"/\[spoiler\](.+?)\[\/spoiler\]/is", 00093 'replace'=>'<div class="spoiler"><div class="spoiler_header" onclick="$(this).next().slideToggle(\'slow\')">Click to show/hide spoiler.</div><div class="spoiler_content" style="display:none">$1</div></div>' 00094 ), 00095 'hide'=>array( 00096 'search'=>"/\[hide\](.+?)\[\/hide\]/is", 00097 'replace'=>'<span class="inline_spoiler_notify" onclick="if($(this).next().is(\':visible\')){ $(this).next().fadeOut(\'fast\'); } else { $(this).next().fadeIn(\'fast\'); }">Spoiler!</span><span class="inline_spoiler">$1</span>' 00098 ) 00099 ); 00100 00101 $fancy_defaults = array( 00102 'email'=>array( 00103 'search'=>"/\[email=([^\]]+)\](.+?)\[\/email\]/is", 00104 'replace'=>'<a href="$1">$2</a>' 00105 ), 00106 "url"=>array( 00107 "search"=>"/\[url=([^\]]+)\](.+?)\[\/url\]/is", 00108 "replace"=>'<a target="_blank" href="$1">$2</a>' 00109 ), 00110 'size'=>array( 00111 'search'=>"/\[size=\s?([0-9]+)(?:px)?\](.+?)\[\/size\]/is", 00112 'replace'=>'<span style="font-size:$1px">$2</span>' 00113 ), 00114 'font'=>array( 00115 'search'=>"/\[font=([^\]]+)\](.+?)\[\/font\]/is", 00116 'replace'=>'<span style="font-family:$1">$2</span>' 00117 ), 00118 'color'=>array( 00119 'search'=>"/\[color=([^\]]+)\](.+?)\[\/color\]/is", 00120 'replace'=>'<span style="color:$1">$2</span>' 00121 ), 00122 'quote'=>array( 00123 'search'=>"/\[quote=([^\]]+)\](.+?)\[\/quote\]/is", 00124 'replace'=>'<blockquote><span class="blockquote-title">Quote by $1:</span><br/>$2</blockquote>' 00125 ), 00126 'align'=>array( 00127 'search'=>"/\[align=(left|right|center)\](.+?)\[\/align\]/is", 00128 'replace'=>'<div style="text-align: $1">$2</div>' 00129 ), 00130 'spoiler'=>array( 00131 'search'=>"/\[spoiler=([^\]]+)\](.+?)\[\/spoiler\]/is", 00132 'replace'=>'<div class="spoiler"><div class="spoiler_header" onclick="$(this).next().slideToggle(\'slow\')">$1</div><div class="spoiler_content" style="display:none">$2</div></div>' 00133 ), 00134 'hide'=>array( 00135 'search'=>"/\[hide=([^\]]+)\](.+?)\[\/hide\]/is", 00136 'replace'=>'<span class="inline_spoiler_notify" onclick="if($(this).next().is(\':visible\')){ $(this).next().fadeOut(\'fast\'); } else { $(this).next().fadeIn(\'fast\'); }">$1</span><span class="inline_spoiler">$2</span>' 00137 ) 00138 ); 00139 00140 $this->addSimple($simple_defaults); 00141 $this->addFancy($fancy_defaults); 00142 00143 /* Allowed CSS attributes for tables - prevents things like 00144 * using position: absolute to cover the page contents. */ 00145 $this->allowedCSS = array( 00146 'width', 00147 'height', 00148 'background-color', 00149 'color', 00150 'border', 00151 'border-color', 00152 'border-style', 00153 'border-width', 00154 'border-collapse', 00155 'padding', 00156 'vertical-align', 00157 /* these next 2 aren't CSS but are useful for tables */ 00158 'cellpadding', 00159 'cellspacing', 00160 'align' // not a real CSS property - will allow for easy alignment 00161 ); 00162 } 00163 00164 public function addSimple($tag){ 00165 if(is_array($tag)){ 00166 foreach($tag as $name=>$code){ 00167 $this->simple_bbcodes[$name] = $code; 00168 } 00169 } 00170 else{ //make an assumption... 00171 $this->simple_bbcodes[$tag] = array( 00172 "tag"=>$tag, 00173 "search"=>"/\[$tag\](.+)\[\/$tag\]/i", 00174 "replace"=>'<'.$tag.'>$1</'.$tag.'>' 00175 ); 00176 } 00177 } 00178 00179 public function addFancy($tag){ 00180 if(is_array($tag)){ 00181 foreach($tag as $name=>$code){ 00182 $this->fancy_bbcodes[$name] = $code; 00183 } 00184 } 00185 else{ 00186 return false; 00187 } 00188 } 00189 00190 public function parse($content,&$count=false){ 00191 $search = array(); 00192 $replace = array(); 00193 00194 foreach($this->simple_bbcodes as $code){ 00195 $search[] = $code['search']; 00196 $replace[] = $code['replace']; 00197 } 00198 00199 foreach($this->fancy_bbcodes as $code){ 00200 $search[] = $code['search']; 00201 $replace[] = $code['replace']; 00202 } 00203 00204 if(get_magic_quotes_gpc()){ 00205 $content = stripslashes($content); 00206 } 00207 00208 $content = str_replace(array('<','>'),array('<','>'),$content); 00209 00210 /* nocode tag check - must do this first! */ 00211 $content = preg_replace_callback( 00212 '/\[nocode\](.+?)\[\/nocode\]/is', 00213 create_function( 00214 '$matches', 00215 'return str_replace(array("[","]"),array("[","]"),$matches[1]);' 00216 ), 00217 $content 00218 ); 00219 00220 /* unfortunately we have to do fancy tables separately */ 00221 $content = preg_replace_callback( 00222 "/\[(table)=([^\]]+)\](.+?)\[\/table\]/is", 00223 array($this,'parseTable'), 00224 $content 00225 ); 00226 $content = preg_replace_callback( 00227 "/\[(row)=([^\]]+)\](.+?)\[\/row\]/is", 00228 array($this,'parseTable'), 00229 $content 00230 ); 00231 $content = preg_replace_callback( 00232 "/\[(cell)=([^\]]+)\](.+?)\[\/cell\]/is", 00233 array($this,'parseTable'), 00234 $content 00235 ); 00236 00237 foreach($search as $pattern){ 00238 while(preg_match($pattern,$content)){ 00239 $content = preg_replace($search,$replace,$content,-1,$count); 00240 } 00241 } 00242 00243 /* Handle smilies, will probably change later */ 00244 if($this->isOsimo){ 00245 $content = $this->processSmilies($content); 00246 } 00247 00248 return nl2br($content); 00249 } 00250 00251 private function parseTable($matches){ 00252 $return_css = ''; 00253 $return_attr = ''; 00254 $css = explode(';',$matches[2]); 00255 if(count($css)>0){ 00256 foreach($css as $prop){ 00257 $data = explode(':',$prop); 00258 $css_name = strtolower($data[0]); 00259 if(in_array($css_name,$this->allowedCSS)){ 00260 if($matches[1]=='table'){ 00261 if($css_name == 'cellpadding'||$css_name == 'cellspacing'){ 00262 $return_attr .= $css_name.'="'.$data[1].'" '; 00263 continue; 00264 } 00265 00266 if($css_name == 'align'){ 00267 if($data[1] == 'left'){ 00268 $return_css .= 'margin-right: auto;'; 00269 } 00270 elseif($data[1] == 'center'){ 00271 $return_css .= 'margin-right: auto;margin-left: auto;'; 00272 } 00273 elseif($data[1] == 'right'){ 00274 $return_css .= 'margin-left: auto;'; 00275 } 00276 continue; 00277 } 00278 } 00279 00280 $return_css .= $prop; 00281 if(substr($prop,strlen($prop)-1) != ';'){ 00282 $return_css .= ';'; 00283 } 00284 } 00285 } 00286 } 00287 if($matches[1]=='row'){ $ele_name = 'tr'; } 00288 elseif($matches[1]=='cell'){ $ele_name = 'td'; } 00289 else{ $ele_name = 'table'; } 00290 return "<$ele_name $return_attr style=\"$return_css\">{$matches[3]}</$ele_name>"; 00291 } 00292 00293 /* 00294 * This was copied directly from the old BBCode parser... 00295 * this will probably be completely changed in the future 00296 */ 00297 private function processSmilies($post) 00298 { 00299 if(!isset($_SESSION['osimo']['options']['smileySet'])) 00300 { 00301 $query = "SELECT value FROM config WHERE name='current-smilies' LIMIT 1"; 00302 $result = mysql_query($query); 00303 if($result) 00304 { 00305 $_SESSION['osimo']['options']['smileySet'] = reset(mysql_fetch_row($result)); 00306 } 00307 } 00308 00309 /* If smiley BBCode isn't cached, then do so */ 00310 if(!is_array($_SESSION['osimo']['smilies'])) 00311 { 00312 $query = "SELECT code,image FROM smilies WHERE smileySet='".$_SESSION['osimo']['options']['smileySet']."'"; 00313 $result = mysql_query($query); 00314 00315 if($result) 00316 { 00317 $i=0; 00318 while(list($code,$image)=mysql_fetch_row($result)) 00319 { 00320 $_SESSION['osimo']['smilies']['name'][$i] = $image; 00321 $_SESSION['osimo']['smilies']['code'][$i] = $code; 00322 $i++; 00323 } 00324 } 00325 } 00326 00327 if(is_array($_SESSION['osimo']['smilies'])) 00328 { 00329 $j=0; 00330 foreach($_SESSION['osimo']['smilies']['name'] as $smiley) 00331 { 00332 $replace[$j] = "<img src=\"".OSIMOPATH."os-content/smilies/".$_SESSION['osimo']['options']['smileySet']."/$smiley\" />"; 00333 $j++; 00334 } 00335 00336 $post = str_replace($_SESSION['osimo']['smilies']['code'],$replace,$post); 00337 } 00338 00339 return $post; 00340 } 00341 } 00342 ?>