[ Index ]

PHP Cross Reference of MyBB

title

Body

[close]

/inc/ -> class_parser.php (source)

   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$
  10   */
  11  
  12  /*
  13  options = array(
  14      allow_html
  15      allow_smilies
  16      allow_mycode
  17      nl2br
  18      filter_badwords
  19      me_username
  20      shorten_urls
  21      highlight
  22  )
  23  */
  24  
  25  class postParser
  26  {
  27      /**
  28       * Internal cache of MyCode.
  29       *
  30       * @access public
  31       * @var mixed
  32       */
  33      public $mycode_cache = 0;
  34  
  35      /**
  36       * Internal cache of smilies
  37       *
  38       * @access public
  39       * @var mixed
  40       */
  41      public $smilies_cache = 0;
  42  
  43      /**
  44       * Internal cache of badwords filters
  45       *
  46       * @access public
  47       * @var mixed
  48       */
  49      public $badwords_cache = 0;
  50  
  51      /**
  52       * Base URL for smilies
  53       *
  54       * @access public
  55       * @var string
  56       */
  57      public $base_url;
  58      
  59      /**
  60       * Parsed Highlights cache
  61       *
  62       * @access public
  63       * @var array
  64       */
  65      public $highlight_cache = array();
  66      
  67      /**
  68       * Options for this parsed message (Private - set by parse_message argument)
  69       *
  70       * @access public
  71       * @var array
  72       */
  73      public $options;
  74  
  75      /**
  76       * Parses a message with the specified options.
  77       *
  78       * @param string The message to be parsed.
  79       * @param array Array of yes/no options - allow_html,filter_badwords,allow_mycode,allow_smilies,nl2br,me_username.
  80       * @return string The parsed message.
  81       */
  82  	function parse_message($message, $options=array())
  83      {
  84          global $plugins, $mybb;
  85  
  86          // Set base URL for parsing smilies
  87          $this->base_url = $mybb->settings['bburl'];
  88  
  89          if($this->base_url != "")
  90          {
  91              if(my_substr($this->base_url, my_strlen($this->base_url) -1) != "/")
  92              {
  93                  $this->base_url = $this->base_url."/";
  94              }
  95          }
  96          
  97          // Set the options        
  98          $this->options = $options;
  99  
 100          $message = $plugins->run_hooks("parse_message_start", $message);
 101  
 102          // Get rid of cartridge returns for they are the workings of the devil
 103          $message = str_replace("\r", "", $message);
 104          
 105          // Filter bad words if requested.
 106          if($this->options['filter_badwords'])
 107          {
 108              $message = $this->parse_badwords($message);
 109          }
 110  
 111          if($this->options['allow_html'] != 1)
 112          {
 113              $message = $this->parse_html($message);
 114          }
 115          else
 116          {        
 117              while(preg_match("#<s(cript|tyle)(.*)>(.*)</s(cript|tyle)(.*)>#is", $message))
 118              {
 119                  $message = preg_replace("#<s(cript|tyle)(.*)>(.*)</s(cript|tyle)(.*)>#is", "&lt;s$1$2&gt;$3&lt;/s$4$5&gt;", $message);
 120              }
 121  
 122              $find = array('<?php', '<!--', '-->', '?>', "<br />\n", "<br>\n");
 123              $replace = array('&lt;?php', '&lt;!--', '--&gt;', '?&gt;', "\n", "\n");
 124              $message = str_replace($find, $replace, $message);
 125          }
 126          
 127          // If MyCode needs to be replaced, first filter out [code] and [php] tags.
 128          if($this->options['allow_mycode'])
 129          {
 130              preg_match_all("#\[(code|php)\](.*?)\[/\\1\](\r\n?|\n?)#si", $message, $code_matches, PREG_SET_ORDER);
 131              $message = preg_replace("#\[(code|php)\](.*?)\[/\\1\](\r\n?|\n?)#si", "<mybb-code>\n", $message);
 132          }
 133  
 134          // Always fix bad Javascript in the message.
 135          $message = $this->fix_javascript($message);
 136          
 137          // Replace "me" code and slaps if we have a username
 138          if($this->options['me_username'])
 139          {
 140              global $lang;
 141              
 142              $message = preg_replace('#(>|^|\r|\n)/me ([^\r\n<]*)#i', "\\1<span style=\"color: red;\">* {$this->options['me_username']} \\2</span>", $message);
 143              $message = preg_replace('#(>|^|\r|\n)/slap ([^\r\n<]*)#i', "\\1<span style=\"color: red;\">* {$this->options['me_username']} {$lang->slaps} \\2 {$lang->with_trout}</span>", $message);
 144          }
 145          
 146          // If we can, parse smilies
 147          if($this->options['allow_smilies'])
 148          {
 149              $message = $this->parse_smilies($message, $this->options['allow_html']);
 150          }
 151  
 152          // Replace MyCode if requested.
 153          if($this->options['allow_mycode'])
 154          {
 155              $message = $this->parse_mycode($message, $this->options);
 156          }
 157          
 158          // Parse Highlights
 159          if(!empty($this->options['highlight']))
 160          {
 161              $message = $this->highlight_message($message, $this->options['highlight']);
 162          }
 163  
 164          // Run plugin hooks
 165          $message = $plugins->run_hooks("parse_message", $message);
 166          
 167          if($this->options['allow_mycode'])
 168          {
 169              // Now that we're done, if we split up any code tags, parse them and glue it all back together
 170              if(count($code_matches) > 0)
 171              {
 172                  foreach($code_matches as $text)
 173                  {
 174                      // Fix up HTML inside the code tags so it is clean
 175                      if($options['allow_html'] != 0)
 176                      {
 177                          $text[2] = $this->parse_html($text[2]);
 178                      }
 179  
 180                      if(my_strtolower($text[1]) == "code")
 181                      {
 182                          $code = $this->mycode_parse_code($text[2]);
 183                      }
 184                      elseif(my_strtolower($text[1]) == "php")
 185                      {
 186                          $code = $this->mycode_parse_php($text[2]);
 187                      }
 188                      $message = preg_replace("#\<mybb-code>\n?#", $code, $message, 1);
 189                  }
 190              }
 191          }
 192  
 193          // Replace meta and base tags in our post - these are > dangerous <
 194          if($this->options['allow_html'])
 195          {
 196              $message = preg_replace_callback("#<((m[^a])|(b[^diloru>])|(s[^aemptu>]))(\s*[^>]*)>#si", create_function(
 197                  '$matches',
 198                  'return htmlspecialchars_uni($matches[0]);'
 199              ), $message);
 200          }
 201  
 202          if(!isset($options['nl2br']) || $options['nl2br'] != 0)
 203          {
 204              $message = nl2br($message);
 205              // Fix up new lines and block level elements
 206              $message = preg_replace("#(</?(?:html|head|body|div|p|form|table|thead|tbody|tfoot|tr|td|th|ul|ol|li|div|p|blockquote|cite|hr)[^>]*>)\s*<br />#i", "$1", $message);
 207              $message = preg_replace("#(&nbsp;)+(</?(?:html|head|body|div|p|form|table|thead|tbody|tfoot|tr|td|th|ul|ol|li|div|p|blockquote|cite|hr)[^>]*>)#i", "$2", $message);
 208          }
 209  
 210          $message = my_wordwrap($message);
 211      
 212          $message = $plugins->run_hooks("parse_message_end", $message);
 213                  
 214          return $message;
 215      }
 216  
 217      /**
 218       * Converts HTML in a message to their specific entities whilst allowing unicode characters.
 219       *
 220       * @param string The message to be parsed.
 221       * @return string The formatted message.
 222       */
 223  	function parse_html($message)
 224      {
 225          $message = preg_replace("#&(?!\#[0-9]+;)#si", "&amp;", $message); // fix & but allow unicode
 226          $message = str_replace("<","&lt;",$message);
 227          $message = str_replace(">","&gt;",$message);
 228          return $message;
 229      }
 230  
 231      /**
 232       * Generates a cache of MyCode, both standard and custom.
 233       *
 234       * @access private
 235       */
 236  	private function cache_mycode()
 237      {
 238          global $cache, $lang;
 239          $this->mycode_cache = array();
 240  
 241          $standard_mycode = $callback_mycode = array();
 242  
 243          $standard_mycode['b']['regex'] = "#\[b\](.*?)\[/b\]#si";
 244          $standard_mycode['b']['replacement'] = "<span style=\"font-weight: bold;\">$1</span>";
 245  
 246          $standard_mycode['u']['regex'] = "#\[u\](.*?)\[/u\]#si";
 247          $standard_mycode['u']['replacement'] = "<span style=\"text-decoration: underline;\">$1</span>";
 248  
 249          $standard_mycode['i']['regex'] = "#\[i\](.*?)\[/i\]#si";
 250          $standard_mycode['i']['replacement'] = "<span style=\"font-style: italic;\">$1</span>";
 251  
 252          $standard_mycode['s']['regex'] = "#\[s\](.*?)\[/s\]#si";
 253          $standard_mycode['s']['replacement'] = "<del>$1</del>";
 254  
 255          $standard_mycode['copy']['regex'] = "#\(c\)#i";
 256          $standard_mycode['copy']['replacement'] = "&copy;";
 257  
 258          $standard_mycode['tm']['regex'] = "#\(tm\)#i";
 259          $standard_mycode['tm']['replacement'] = "&#153;";
 260  
 261          $standard_mycode['reg']['regex'] = "#\(r\)#i";
 262          $standard_mycode['reg']['replacement'] = "&reg;";
 263  
 264          $callback_mycode['url_simple']['regex'] = "#\[url\]([a-z]+?://)([^\r\n\"<]+?)\[/url\]#si";
 265          $callback_mycode['url_simple']['replacement'] = array($this, 'mycode_parse_url_callback1');
 266  
 267          $callback_mycode['url_simple2']['regex'] = "#\[url\]([^\r\n\"<]+?)\[/url\]#i";
 268          $callback_mycode['url_simple2']['replacement'] = array($this, 'mycode_parse_url_callback2');
 269  
 270          $callback_mycode['url_complex']['regex'] = "#\[url=([a-z]+?://)([^\r\n\"<]+?)\](.+?)\[/url\]#si";
 271          $callback_mycode['url_complex']['replacement'] = array($this, 'mycode_parse_url_callback1');
 272  
 273          $callback_mycode['url_complex2']['regex'] = "#\[url=([^\r\n\"<&\(\)]+?)\](.+?)\[/url\]#si";
 274          $callback_mycode['url_complex2']['replacement'] = array($this, 'mycode_parse_url_callback2');
 275  
 276          $callback_mycode['email_simple']['regex'] = "#\[email\](.*?)\[/email\]#i";
 277          $callback_mycode['email_simple']['replacement'] = array($this, 'mycode_parse_email_callback');
 278  
 279          $callback_mycode['email_complex']['regex'] = "#\[email=(.*?)\](.*?)\[/email\]#i";
 280          $callback_mycode['email_complex']['replacement'] = array($this, 'mycode_parse_email_callback');
 281          
 282          $standard_mycode['hr']['regex'] = "#\[hr\]#si";
 283          $standard_mycode['hr']['replacement'] = "<hr />";
 284  
 285          $nestable_mycode['color']['regex'] = "#\[color=([a-zA-Z]*|\#?[0-9a-fA-F]{6})](.*?)\[/color\]#si";
 286          $nestable_mycode['color']['replacement'] = "<span style=\"color: $1;\">$2</span>";
 287  
 288          $nestable_mycode['size']['regex'] = "#\[size=(xx-small|x-small|small|medium|large|x-large|xx-large)\](.*?)\[/size\]#si";
 289          $nestable_mycode['size']['replacement'] = "<span style=\"font-size: $1;\">$2</span>";
 290  
 291          $callback_mycode['size_int']['regex'] = "#\[size=([0-9\+\-]+?)\](.*?)\[/size\]#si";
 292          $callback_mycode['size_int']['replacement'] = array($this, 'mycode_handle_size_callback');
 293  
 294          $nestable_mycode['font']['regex'] = "#\[font=([a-z ]+?)\](.+?)\[/font\]#si";
 295          $nestable_mycode['font']['replacement'] = "<span style=\"font-family: $1;\">$2</span>";
 296  
 297          $nestable_mycode['align']['regex'] = "#\[align=(left|center|right|justify)\](.*?)\[/align\]#si";
 298          $nestable_mycode['align']['replacement'] = "<div style=\"text-align: $1;\">$2</div>";
 299  
 300          $custom_mycode = $cache->read("mycode");
 301  
 302          // If there is custom MyCode, load it.
 303          if(is_array($custom_mycode))
 304          {
 305              foreach($custom_mycode as $key => $mycode)
 306              {
 307                  $mycode['regex'] = str_replace("\x0", "", $mycode['regex']);
 308                  $custom_mycode[$key]['regex'] = "#".$mycode['regex']."#si";
 309              }
 310              $mycode = array_merge($standard_mycode, $custom_mycode);
 311          }
 312          else
 313          {
 314              $mycode = $standard_mycode;
 315          }
 316  
 317          // Assign the MyCode to the cache.
 318          foreach($mycode as $code)
 319          {
 320              $this->mycode_cache['standard']['find'][] = $code['regex'];
 321              $this->mycode_cache['standard']['replacement'][] = $code['replacement'];
 322          }
 323          
 324          // Assign the nestable MyCode to the cache.
 325          foreach($nestable_mycode as $code)
 326          {
 327              $this->mycode_cache['nestable'][] = array('find' => $code['regex'], 'replacement' => $code['replacement']);
 328          }
 329  
 330          // Assign the nestable MyCode to the cache.
 331          foreach($callback_mycode as $code)
 332          {
 333              $this->mycode_cache['callback'][] = array('find' => $code['regex'], 'replacement' => $code['replacement']);
 334          }
 335      }
 336  
 337      /**
 338       * Parses MyCode tags in a specific message with the specified options.
 339       *
 340       * @param string The message to be parsed.
 341       * @param array Array of options in yes/no format. Options are allow_imgcode.
 342       * @return string The parsed message.
 343       */
 344  	function parse_mycode($message, $options=array())
 345      {
 346          global $lang;
 347  
 348          // Cache the MyCode globally if needed.
 349          if($this->mycode_cache == 0)
 350          {
 351              $this->cache_mycode();
 352          }
 353          
 354          // Parse quotes first
 355          $message = $this->mycode_parse_quotes($message);
 356          
 357          $message = $this->mycode_auto_url($message);
 358  
 359          $message = str_replace('$', '&#36;', $message);
 360          
 361          // Replace the rest
 362          $message = preg_replace($this->mycode_cache['standard']['find'], $this->mycode_cache['standard']['replacement'], $message);
 363          foreach($this->mycode_cache['callback'] as $replace)
 364          {
 365              $message = preg_replace_callback($replace['find'], $replace['replacement'], $message);
 366          }
 367          
 368          // Replace the nestable mycode's
 369          foreach($this->mycode_cache['nestable'] as $mycode)
 370          {
 371              while(preg_match($mycode['find'], $message))
 372              {
 373                  $message = preg_replace($mycode['find'], $mycode['replacement'], $message);
 374              }
 375          }
 376  
 377          // Special code requiring special attention
 378          while(preg_match("#\[list\](.*?)\[/list\]#si", $message))
 379          {
 380              $message = preg_replace_callback("#\s?\[list\](.*?)\[/list\](\r\n?|\n?)#si", array($this, 'mycode_parse_list_callback'), $message);
 381          }
 382  
 383          // Replace lists.
 384          while(preg_match("#\[list=(a|A|i|I|1)\](.*?)\[/list\](\r\n?|\n?)#si", $message))
 385          {
 386              $message = preg_replace_callback("#\s?\[list=(a|A|i|I|1)\](.*?)\[/list\]#si", array($this, 'mycode_parse_list_callback_type'), $message);
 387          }
 388  
 389          // Convert images when allowed.
 390          if($options['allow_imgcode'] != 0)
 391          {
 392              $message = preg_replace_callback("#\[img\](\r\n?|\n?)(https?://([^<>\"']+?))\[/img\]#is", array($this, 'mycode_parse_img_callback1'), $message);
 393              $message = preg_replace_callback("#\[img=([0-9]{1,3})x([0-9]{1,3})\](\r\n?|\n?)(https?://([^<>\"']+?))\[/img\]#is", array($this, 'mycode_parse_img_callback2'), $message);
 394              $message = preg_replace_callback("#\[img align=([a-z]+)\](\r\n?|\n?)(https?://([^<>\"']+?))\[/img\]#is", array($this, 'mycode_parse_img_callback3'), $message);
 395              $message = preg_replace_callback("#\[img=([0-9]{1,3})x([0-9]{1,3}) align=([a-z]+)\](\r\n?|\n?)(https?://([^<>\"']+?))\[/img\]#is", array($this, 'mycode_parse_img_callback4'), $message);
 396          }
 397          
 398          // Convert videos when allow.
 399          if($options['allow_videocode'] != 0)
 400          {
 401              $message = preg_replace_callback("#\[video=(.*?)\](.*?)\[/video\]#i", array($this, 'mycode_parse_video_callback'), $message);
 402          }
 403  
 404          return $message;
 405      }
 406  
 407      /**
 408       * Generates a cache of smilies
 409       *
 410       * @access private
 411       */
 412  	private function cache_smilies()
 413      {
 414          global $cache, $mybb;
 415          $this->smilies_cache = array();
 416  
 417          $smilies = $cache->read("smilies");
 418          if(is_array($smilies))
 419          {
 420              foreach($smilies as $sid => $smilie)
 421              {
 422                  if(defined("IN_ARCHIVE") && substr($smilie['image'], 0, 4) != "http")
 423                  {
 424                      // We're in the archive and not using an outside image, add in our address
 425                      $smilie['image'] = $mybb->settings['bburl']."/".$smilie['image'];
 426                  }
 427  
 428                  $this->smilies_cache[$smilie['find']] = "<img src=\"{$smilie['image']}\" style=\"vertical-align: middle;\" border=\"0\" alt=\"{$smilie['name']}\" title=\"{$smilie['name']}\" />";
 429              }
 430          }
 431      }
 432  
 433      /**
 434       * Parses smilie code in the specified message.
 435       *
 436       * @param string The message being parsed.
 437       * @param string Base URL for the image tags created by smilies.
 438       * @param string Yes/No if HTML is allowed in the post
 439       * @return string The parsed message.
 440       */
 441  	function parse_smilies($message, $allow_html=0)
 442      {
 443          if($this->smilies_cache == 0)
 444          {
 445              $this->cache_smilies();
 446          }
 447          
 448          $message = ' ' . $message . ' ';
 449          
 450          // First we take out any of the tags we don't want parsed between (url= etc)
 451          preg_match_all("#\[(url(=[^\]]*)?\]|quote=([^\]]*)?\])#i", $message, $bad_matches, PREG_PATTERN_ORDER);
 452          $message = preg_replace("#\[(url(=[^\]]*)?\]|quote=([^\]]*)?\])#si", "<mybb-bad-sm>", $message);
 453          
 454          // Impose a hard limit of 500 smilies per message as to not overload the parser
 455          $remaining = 500;
 456  
 457          if(is_array($this->smilies_cache))
 458          {
 459              foreach($this->smilies_cache as $find => $replace)
 460              {
 461                  $orig_message = $message;
 462                  $find = $this->parse_html($find);
 463                  $find = preg_quote($find, "#");
 464  
 465                  $replace = strip_tags($replace, "<img>");
 466                  
 467                  // Fix issues for smileys starting with a ";"
 468                  $orig_find = $find;
 469                  if(substr($find, 0, 1) == ";")
 470                  {
 471                      $find = "(?<!&gt|&lt|&amp)".$find;
 472                  }
 473                  
 474                  $message = @preg_replace("#(?<=[^\"])".$find."(?=.\W|\"|\W.|\W$)#si", $replace, $message, $remaining, $replacements);
 475                  
 476                  if($message == null)
 477                  {
 478                      $message = preg_replace("#(?<=[^&;\"])".$orig_find."(?=.\W|\"|\W.|\W$)#si", $replace, $orig_message, $remaining);
 479                  }
 480                  
 481                  $remaining -= $replacements;
 482                  if($remaining <= 0)
 483                  {
 484                      break; // Reached the limit
 485                  }
 486              }
 487              unset($orig_message, $orig_find);
 488          }
 489  
 490          // If we matched any tags previously, swap them back in
 491          if(count($bad_matches[0]) > 0)
 492          {
 493              foreach($bad_matches[0] as $match)
 494              {
 495                  $match = str_replace('$', '\$', $match);
 496                  $message = preg_replace("#<mybb-bad-sm>#", $match, $message, 1);
 497              }
 498          }
 499  
 500          return trim($message);
 501      }
 502  
 503      /**
 504       * Generates a cache of badwords filters.
 505       *
 506       * @access private
 507       */
 508  	private function cache_badwords()
 509      {
 510          global $cache;
 511          $this->badwords_cache = array();
 512          $this->badwords_cache = $cache->read("badwords");
 513      }
 514  
 515      /**
 516       * Parses a list of filtered/badwords in the specified message.
 517       *
 518       * @param string The message to be parsed.
 519       * @param array Array of parser options in yes/no format.
 520       * @return string The parsed message.
 521       */
 522  	function parse_badwords($message, $options=array())
 523      {
 524          if($this->badwords_cache == 0)
 525          {
 526              $this->cache_badwords();
 527          }
 528          if(is_array($this->badwords_cache))
 529          {
 530              reset($this->badwords_cache);
 531              foreach($this->badwords_cache as $bid => $badword)
 532              {
 533                  if(!$badword['replacement'])
 534                  {
 535                      $badword['replacement'] = "*****";
 536                  }
 537                  
 538                  // Take into account the position offset for our last replacement.
 539                  $index = substr_count($badword['badword'], '*')+2;
 540                  $badword['badword'] = str_replace('\*', '([a-zA-Z0-9_]{1})', preg_quote($badword['badword'], "#"));
 541                  
 542                  // Ensure we run the replacement enough times but not recursively (i.e. not while(preg_match..))
 543                  $count = preg_match_all("#(^|\W)".$badword['badword']."(\W|$)#i", $message, $matches);
 544                  for($i=0; $i < $count; ++$i)
 545                  {
 546                      $message = preg_replace("#(^|\W)".$badword['badword']."(\W|$)#i", "\\1".$badword['replacement'].'\\'.$index, $message);
 547                  }
 548              }
 549          }
 550          if(isset($options['strip_tags']) && $options['strip_tags'] == 1)
 551          {
 552              $message = strip_tags($message);
 553          }
 554          return $message;
 555      }
 556  
 557      /**
 558       * Attempts to move any javascript references in the specified message.
 559       *
 560       * @param string The message to be parsed.
 561       * @return string The parsed message.
 562       */
 563  	function fix_javascript($message)
 564      {
 565          $js_array = array(
 566              "#(&\#(0*)106;?|&\#(0*)74;?|&\#x(0*)4a;?|&\#x(0*)6a;?|j)((&\#(0*)97;?|&\#(0*)65;?|a)(&\#(0*)118;?|&\#(0*)86;?|v)(&\#(0*)97;?|&\#(0*)65;?|a)(\s)?(&\#(0*)115;?|&\#(0*)83;?|s)(&\#(0*)99;?|&\#(0*)67;?|c)(&\#(0*)114;?|&\#(0*)82;?|r)(&\#(0*)105;?|&\#(0*)73;?|i)(&\#112;?|&\#(0*)80;?|p)(&\#(0*)116;?|&\#(0*)84;?|t)(&\#(0*)58;?|\:))#i",
 567              "#(o)(nmouseover\s?=)#i",
 568              "#(o)(nmouseout\s?=)#i",
 569              "#(o)(nmousedown\s?=)#i",
 570              "#(o)(nmousemove\s?=)#i",
 571              "#(o)(nmouseup\s?=)#i",
 572              "#(o)(nclick\s?=)#i",
 573              "#(o)(ndblclick\s?=)#i",
 574              "#(o)(nload\s?=)#i",
 575              "#(o)(nsubmit\s?=)#i",
 576              "#(o)(nblur\s?=)#i",
 577              "#(o)(nchange\s?=)#i",
 578              "#(o)(nfocus\s?=)#i",
 579              "#(o)(nselect\s?=)#i",
 580              "#(o)(nunload\s?=)#i",
 581              "#(o)(nkeypress\s?=)#i",
 582              "#(o)(nerror\s?=)#i",
 583              "#(o)(nreset\s?=)#i",
 584              "#(o)(nabort\s?=)#i"
 585          );
 586          
 587          $message = preg_replace($js_array, "$1<strong></strong>$2$4", $message);
 588  
 589          return $message;
 590      }
 591      
 592      /**
 593      * Handles fontsize.
 594      *
 595      * @param string The original size.
 596      * @param string The text within a size tag.
 597      * @return string The parsed text.
 598      */
 599  	function mycode_handle_size($size, $text)
 600      {
 601          $size = intval($size)+10;
 602  
 603          if($size > 50)
 604          {
 605              $size = 50;
 606          }
 607  
 608          $text = "<span style=\"font-size: {$size}pt;\">".str_replace("\'", "'", $text)."</span>";
 609  
 610          return $text;
 611      }
 612  
 613      /**
 614      * Handles fontsize.
 615      *
 616      * @param array Matches.
 617      * @return string The parsed text.
 618      */
 619  	function mycode_handle_size_callback($matches)
 620      {
 621          return $this->mycode_handle_size($matches[1], $matches[2]);
 622      }
 623  
 624      /**
 625      * Parses quote MyCode.
 626      *
 627      * @param string The message to be parsed
 628      * @param boolean Are we formatting as text?
 629      * @return string The parsed message.
 630      */
 631  	function mycode_parse_quotes($message, $text_only=false)
 632      {
 633          global $lang, $templates, $theme, $mybb;
 634  
 635          // Assign pattern and replace values.
 636          $pattern = "#\[quote\](.*?)\[\/quote\](\r\n?|\n?)#si";
 637          $pattern_callback = "#\[quote=([\"']|&quot;|)(.*?)(?:\\1)(.*?)(?:[\"']|&quot;)?\](.*?)\[/quote\](\r\n?|\n?)#si";
 638  
 639          if($text_only == false)
 640          {
 641              $replace = "<blockquote><cite>$lang->quote</cite>$1</blockquote>\n";
 642              $replace_callback = array($this, 'mycode_parse_post_quotes_callback1');
 643          }
 644          else
 645          {
 646              $replace = "\n{$lang->quote}\n--\n$1\n--\n";
 647              $replace_callback = array($this, 'mycode_parse_post_quotes_callback2');
 648          }
 649  
 650          do
 651          {
 652              // preg_replace has erased the message? Restore it...
 653              $previous_message = $message;
 654              $message = preg_replace($pattern, $replace, $message, -1, $count);
 655              $message = preg_replace_callback($pattern_callback, $replace_callback, $message, -1, $count_callback);
 656              if(!$message)
 657              {
 658                  $message = $previous_message;
 659                  break;
 660              }
 661          } while($count || $count_callback);
 662  
 663          if($text_only == false)
 664          {
 665              $find = array(
 666                  "#(\r\n*|\n*)<\/cite>(\r\n*|\n*)#",
 667                  "#(\r\n*|\n*)<\/blockquote>#"
 668              );
 669  
 670              $replace = array(
 671                  "</cite><br />",
 672                  "</blockquote>"
 673              );
 674              $message = preg_replace($find, $replace, $message);
 675          }
 676          return $message;
 677      }
 678      
 679      /**
 680      * Parses quotes with post id and/or dateline.
 681      *
 682      * @param string The message to be parsed
 683      * @param string The username to be parsed
 684      * @param boolean Are we formatting as text?
 685      * @return string The parsed message.
 686      */
 687  	function mycode_parse_post_quotes($message, $username, $text_only=false)
 688      {
 689          global $lang, $templates, $theme, $mybb;
 690  
 691          $linkback = $date = "";
 692  
 693          $message = trim($message);
 694          $message = preg_replace("#(^<br(\s?)(\/?)>|<br(\s?)(\/?)>$)#i", "", $message);
 695  
 696          if(!$message) return '';
 697  
 698          $message = str_replace('\"', '"', $message);
 699          $username = str_replace('\"', '"', $username)."'";
 700          $delete_quote = true;
 701  
 702          preg_match("#pid=(?:&quot;|\"|')?([0-9]+)[\"']?(?:&quot;|\"|')?#i", $username, $match);
 703          if(intval($match[1]))
 704          {
 705              $pid = intval($match[1]);
 706              $url = $mybb->settings['bburl']."/".get_post_link($pid)."#pid$pid";
 707              if(defined("IN_ARCHIVE"))
 708              {
 709                  $linkback = " <a href=\"{$url}\">[ -> ]</a>";
 710              }
 711              else
 712              {
 713                  eval("\$linkback = \" ".$templates->get("postbit_gotopost", 1, 0)."\";");
 714              }
 715              
 716              $username = preg_replace("#(?:&quot;|\"|')? pid=(?:&quot;|\"|')?[0-9]+[\"']?(?:&quot;|\"|')?#i", '', $username);
 717              $delete_quote = false;
 718          }
 719  
 720          unset($match);
 721          preg_match("#dateline=(?:&quot;|\"|')?([0-9]+)(?:&quot;|\"|')?#i", $username, $match);
 722          if(intval($match[1]))
 723          {
 724              if($match[1] < TIME_NOW)
 725              {
 726                  $postdate = my_date($mybb->settings['dateformat'], intval($match[1]));
 727                  $posttime = my_date($mybb->settings['timeformat'], intval($match[1]));
 728                  $date = " ({$postdate} {$posttime})";
 729              }
 730              $username = preg_replace("#(?:&quot;|\"|')? dateline=(?:&quot;|\"|')?[0-9]+(?:&quot;|\"|')?#i", '', $username);
 731              $delete_quote = false;
 732          }
 733  
 734          if($delete_quote)
 735          {
 736              $username = my_substr($username, 0, my_strlen($username)-1);
 737          }
 738  
 739          if($text_only)
 740          {
 741              return "\n".htmlspecialchars_uni($username)." $lang->wrote{$date}\n--\n{$message}\n--\n";
 742          }
 743          else
 744          {
 745              $span = "";
 746              if(!$delete_quote)
 747              {
 748                  $span = "<span>{$date}</span>";
 749              }
 750              
 751              return "<blockquote><cite>{$span}".htmlspecialchars_uni($username)." $lang->wrote{$linkback}</cite>{$message}</blockquote>\n";
 752          }
 753      }
 754  
 755      /**
 756      * Parses quotes with post id and/or dateline.
 757      *
 758      * @param array Matches.
 759      * @return string The parsed message.
 760      */
 761  	function mycode_parse_post_quotes_callback1($matches)
 762      {
 763          return $this->mycode_parse_post_quotes($matches[4],$matches[2].$matches[3]);
 764      }
 765  
 766      /**
 767      * Parses quotes with post id and/or dateline.
 768      *
 769      * @param array Matches.
 770      * @return string The parsed message.
 771      */
 772  	function mycode_parse_post_quotes_callback2($matches)
 773      {
 774          return $this->mycode_parse_post_quotes($matches[4],$matches[2].$matches[3], true);
 775      }
 776  
 777      /**
 778      * Parses code MyCode.
 779      *
 780      * @param string The message to be parsed
 781      * @param boolean Are we formatting as text?
 782      * @return string The parsed message.
 783      */
 784  	function mycode_parse_code($code, $text_only=false)
 785      {
 786          global $lang;
 787  
 788          if($text_only == true)
 789          {
 790              return "\n{$lang->code}\n--\n{$code}\n--\n";
 791          }
 792  
 793          // Clean the string before parsing.
 794          $code = preg_replace('#^(\t*)(\n|\r|\0|\x0B| )*#', '\\1', $code);
 795          $code = rtrim($code);
 796          $original = preg_replace('#^\t*#', '', $code);
 797  
 798          if(empty($original))
 799          {
 800              return;
 801          }
 802  
 803          $code = str_replace('$', '&#36;', $code);
 804          $code = preg_replace('#\$([0-9])#', '\\\$\\1', $code);
 805          $code = str_replace('\\', '&#92;', $code);
 806          $code = str_replace("\t", '&nbsp;&nbsp;&nbsp;&nbsp;', $code);
 807          $code = str_replace("  ", '&nbsp;&nbsp;', $code);
 808  
 809          return "<div class=\"codeblock\">\n<div class=\"title\">".$lang->code."\n</div><div class=\"body\" dir=\"ltr\"><code>".$code."</code></div></div>\n";
 810      }
 811  
 812      /**
 813      * Parses code MyCode.
 814      *
 815      * @param array Matches.
 816      * @return string The parsed message.
 817      */
 818  	function mycode_parse_code_callback($matches)
 819      {
 820          return $this->mycode_parse_code($matches[1], true);
 821      }
 822  
 823      /**
 824      * Parses PHP code MyCode.
 825      *
 826      * @param string The message to be parsed
 827      * @param boolean Whether or not it should return it as pre-wrapped in a div or not.
 828      * @param boolean Are we formatting as text?
 829      * @return string The parsed message.
 830      */
 831  	function mycode_parse_php($str, $bare_return = false, $text_only = false)
 832      {
 833          global $lang;
 834  
 835          if($text_only == true)
 836          {
 837              return "\n{$lang->php_code}\n--\n$str\n--\n";
 838          }
 839  
 840          // Clean the string before parsing except tab spaces.
 841          $str = preg_replace('#^(\t*)(\n|\r|\0|\x0B| )*#', '\\1', $str);
 842          $str = rtrim($str);
 843  
 844          $original = preg_replace('#^\t*#', '', $str);
 845  
 846          if(empty($original))
 847          {
 848              return;
 849          }
 850  
 851          $str = str_replace('&amp;', '&', $str);
 852          $str = str_replace('&lt;', '<', $str);
 853          $str = str_replace('&gt;', '>', $str);
 854  
 855          // See if open and close tags are provided.
 856          $added_open_tag = false;
 857          if(!preg_match("#^\s*<\?#si", $str))
 858          {
 859              $added_open_tag = true;
 860              $str = "<?php \n".$str;
 861          }
 862  
 863          $added_end_tag = false;
 864          if(!preg_match("#\?>\s*$#si", $str))
 865          {
 866              $added_end_tag = true;
 867              $str = $str." \n?>";
 868          }
 869  
 870          $code = @highlight_string($str, true);
 871  
 872          // Do the actual replacing.
 873          $code = preg_replace('#<code>\s*<span style="color: \#000000">\s*#i', "<code>", $code);
 874          $code = preg_replace("#</span>\s*</code>#", "</code>", $code);
 875          $code = preg_replace("#</span>(\r\n?|\n?)</code>#", "</span></code>", $code);
 876          $code = str_replace("\\", '&#092;', $code);
 877          $code = str_replace('$', '&#36;', $code);
 878          $code = preg_replace("#&amp;\#([0-9]+);#si", "&#$1;", $code);
 879  
 880          if($added_open_tag)
 881          {
 882              $code = preg_replace("#<code><span style=\"color: \#([A-Z0-9]{6})\">&lt;\?php( |&nbsp;)(<br />?)#", "<code><span style=\"color: #$1\">", $code);
 883          }
 884  
 885          if($added_end_tag)
 886          {
 887              $code = str_replace("?&gt;</span></code>", "</span></code>", $code);
 888              // Wait a minute. It fails highlighting? Stupid highlighter.
 889              $code = str_replace("?&gt;</code>", "</code>", $code);
 890          }
 891  
 892          $code = preg_replace("#<span style=\"color: \#([A-Z0-9]{6})\"></span>#", "", $code);
 893          $code = str_replace("<code>", "<div dir=\"ltr\"><code>", $code);
 894          $code = str_replace("</code>", "</code></div>", $code);
 895          $code = preg_replace("# *$#", "", $code);
 896  
 897          if($bare_return)
 898          {
 899              return $code;
 900          }
 901  
 902          // Send back the code all nice and pretty
 903          return "<div class=\"codeblock phpcodeblock\"><div class=\"title\">$lang->php_code\n</div><div class=\"body\">".$code."</div></div>\n";
 904      }
 905  
 906      /**
 907      * Parses PHP code MyCode.
 908      *
 909      * @param array Matches.
 910      * @return string The parsed message.
 911      */
 912  	function mycode_parse_php_callback($matches)
 913      {
 914          return $this->mycode_parse_php($matches[1], false, true);
 915      }
 916  
 917      /**
 918      * Parses URL MyCode.
 919      *
 920      * @param string The URL to link to.
 921      * @param string The name of the link.
 922      * @return string The built-up link.
 923      */
 924  	function mycode_parse_url($url, $name="")
 925      {
 926          if(!preg_match("#^[a-z0-9]+://#i", $url))
 927          {
 928              $url = "http://".$url;
 929          }
 930          $fullurl = $url;
 931  
 932          $url = str_replace('&amp;', '&', $url);
 933          $name = str_replace('&amp;', '&', $name);
 934          
 935          if(!$name)
 936          {
 937              $name = $url;
 938          }
 939          
 940          $name = str_replace("\'", "'", $name);
 941          $url = str_replace("\'", "'", $url);
 942          $fullurl = str_replace("\'", "'", $fullurl);
 943          
 944          if($name == $url && (!isset($this->options['shorten_urls']) || $this->options['shorten_urls'] != 0))
 945          {
 946              if(my_strlen($url) > 55)
 947              {
 948                  $name = my_substr($url, 0, 40)."...".my_substr($url, -10);
 949              }
 950          }
 951  
 952          $nofollow = '';
 953          if(isset($this->options['nofollow_on']))
 954          {
 955              $nofollow = " rel=\"nofollow\"";
 956          }
 957  
 958          // Fix some entities in URLs
 959          $entities = array('$' => '%24', '&#36;' => '%24', '^' => '%5E', '`' => '%60', '[' => '%5B', ']' => '%5D', '{' => '%7B', '}' => '%7D', '"' => '%22', '<' => '%3C', '>' => '%3E', ' ' => '%20');
 960          $fullurl = str_replace(array_keys($entities), array_values($entities), $fullurl);
 961  
 962          $name = preg_replace("#&amp;\#([0-9]+);#si", "&#$1;", $name); // Fix & but allow unicode
 963          $link = "<a href=\"$fullurl\" target=\"_blank\"{$nofollow}>$name</a>";
 964          return $link;
 965      }
 966  
 967      /**
 968      * Parses URL MyCode.
 969      *
 970      * @param array Matches.
 971      * @return string The built-up link.
 972      */
 973  	function mycode_parse_url_callback1($matches)
 974      {
 975          if(!isset($matches[3]))
 976          {
 977              $matches[3] = '';
 978          }
 979          return $this->mycode_parse_url($matches[1].$matches[2], $matches[3]);
 980      }
 981  
 982      /**
 983      * Parses URL MyCode.
 984      *
 985      * @param array Matches.
 986      * @return string The built-up link.
 987      */
 988  	function mycode_parse_url_callback2($matches)
 989      {
 990          if(!isset($matches[2]))
 991          {
 992              $matches[2] = '';
 993          }
 994          return $this->mycode_parse_url($matches[1], $matches[2]);
 995      }
 996  
 997      /**
 998       * Parses IMG MyCode.
 999       *
1000       * @param string The URL to the image
1001       * @param array Optional array of dimensions
1002       */
1003  	function mycode_parse_img($url, $dimensions=array(), $align='')
1004      {
1005          global $lang;
1006          $url = trim($url);
1007          $url = str_replace("\n", "", $url);
1008          $url = str_replace("\r", "", $url);
1009          if($align == "right")
1010          {
1011              $css_align = " style=\"float: right;\"";
1012          }
1013          else if($align == "left")
1014          {
1015              $css_align = " style=\"float: left;\"";
1016          }
1017          $alt = htmlspecialchars_uni(basename($url));
1018          if(my_strlen($alt) > 55)
1019          {
1020              $alt = my_substr($alt, 0, 40)."...".my_substr($alt, -10);
1021          }
1022          $alt = $lang->sprintf($lang->posted_image, $alt);
1023          if($dimensions[0] > 0 && $dimensions[1] > 0)
1024          {
1025              return "<img src=\"{$url}\" width=\"{$dimensions[0]}\" height=\"{$dimensions[1]}\" border=\"0\" alt=\"{$alt}\"{$css_align} />";
1026          }
1027          else
1028          {
1029              return "<img src=\"{$url}\" border=\"0\" alt=\"{$alt}\"{$css_align} />";            
1030          }
1031      }
1032  
1033      /**
1034       * Parses IMG MyCode.
1035       *
1036       * @param array Matches.
1037       * @return string Image code.
1038       */
1039  	function mycode_parse_img_callback1($matches)
1040      {
1041          return $this->mycode_parse_img($matches[2])."\n";
1042      }
1043  
1044      /**
1045       * Parses IMG MyCode.
1046       *
1047       * @param array Matches.
1048       * @return string Image code.
1049       */
1050  	function mycode_parse_img_callback2($matches)
1051      {
1052          return $this->mycode_parse_img($matches[4], array($matches[1], $matches[2]));
1053      }
1054  
1055      /**
1056       * Parses IMG MyCode.
1057       *
1058       * @param array Matches.
1059       * @return string Image code.
1060       */
1061  	function mycode_parse_img_callback3($matches)
1062      {
1063          return $this->mycode_parse_img($matches[3], array(), $matches[1]);
1064      }
1065  
1066      /**
1067       * Parses IMG MyCode.
1068       *
1069       * @param array Matches.
1070       * @return string Image code.
1071       */
1072  	function mycode_parse_img_callback4($matches)
1073      {
1074          return $this->mycode_parse_img($matches[5], array($matches[1], $matches[2]), $matches[3]);
1075      }
1076  
1077      /**
1078      * Parses email MyCode.
1079      *
1080      * @param string The email address to link to.
1081      * @param string The name for the link.
1082      * @return string The built-up email link.
1083      */
1084  	function mycode_parse_email($email, $name="")
1085      {
1086          $name = str_replace("\\'", "'", $name);
1087          $email = str_replace("\\'", "'", $email);
1088          if(!$name)
1089          {
1090              $name = $email;
1091          }
1092          if(preg_match("/^([a-zA-Z0-9-_\+\.]+?)@[a-zA-Z0-9-]+\.[a-zA-Z0-9\.-]+$/si", $email))
1093          {
1094              return "<a href=\"mailto:$email\">".$name."</a>";
1095          }
1096          else
1097          {
1098              return $email;
1099          }
1100      }
1101  
1102      /**
1103      * Parses email MyCode.
1104      *
1105      * @param array Matches
1106      * @return string The built-up email link.
1107      */
1108  	function mycode_parse_email_callback($matches)
1109      {
1110          if(!isset($matches[2]))
1111          {
1112              $matches[2] = '';
1113          }
1114          return $this->mycode_parse_email($matches[1], $matches[2]);
1115      }
1116  
1117      /**
1118      * Parses video MyCode.
1119      *
1120      * @param string The video provider.
1121      * @param string The video to link to.
1122      * @return string The built-up video code.
1123      */
1124  	function mycode_parse_video($video, $url)
1125      {
1126          global $templates;
1127          
1128          if(empty($video) || empty($url))
1129          {
1130              return "[video={$video}]{$url}[/video]";
1131          }
1132          
1133          $parsed_url = @parse_url(urldecode($url));
1134          if($parsed_url == false)
1135          {
1136              return "[video={$video}]{$url}[/video]";
1137          }
1138          
1139          $fragments = array();
1140          if($parsed_url['fragment'])
1141          {
1142              $fragments = explode("&", $parsed_url['fragment']);
1143          }
1144          
1145          $queries = explode("&", $parsed_url['query']);
1146          
1147          $input = array();
1148          foreach($queries as $query)
1149          {
1150              list($key, $value) = explode("=", $query);
1151              $key = str_replace("amp;", "", $key);
1152              $input[$key] = $value;
1153          }
1154          
1155          $path = explode('/', $parsed_url['path']);
1156          
1157          switch($video)
1158          {
1159              case "dailymotion":
1160                  list($id, ) = split("_", $path[2], 1); // http://www.dailymotion.com/video/fds123_title-goes-here
1161                  break;
1162              case "metacafe":
1163                  $id = $path[2]; // http://www.metacafe.com/watch/fds123/title_goes_here/
1164                  $title = htmlspecialchars_uni($path[3]);
1165                  break;
1166              case "myspacetv":
1167                  $id = $path[4]; // http://www.myspace.com/video/fds/fds/123
1168                  break;
1169              case "yahoo":
1170                  $id = $path[1]; // http://xy.screen.yahoo.com/fds-123.html
1171                  // Support for localized portals
1172                  $domain = explode('.', $parsed_url['host']);
1173                  if($domain[0] != 'screen')
1174                  {
1175                      $local = $domain[0].'.';
1176                  }
1177                  else
1178                  {
1179                      $local = '';
1180                  }
1181                  break;
1182              case "vimeo":
1183                  $id = $path[1]; // http://vimeo.com/fds123
1184                  break;
1185              case "youtube":
1186                  if($fragments[0])
1187                  {
1188                      $id = str_replace('!v=', '', $fragments[0]); // http://www.youtube.com/watch#!v=fds123
1189                  }
1190                  elseif($input['v'])
1191                  {
1192                      $id = $input['v']; // http://www.youtube.com/watch?v=fds123
1193                  }
1194                  else
1195                  {
1196                      $id = $path[1]; // http://www.youtu.be/fds123
1197                  }
1198                  break;
1199              default:
1200                  return "[video={$video}]{$url}[/video]";
1201          }
1202  
1203          if(empty($id))
1204          {
1205              return "[video={$video}]{$url}[/video]";
1206          }
1207          
1208          $id = htmlspecialchars_uni($id);
1209          
1210          eval("\$video_code = \"".$templates->get("video_{$video}_embed")."\";");
1211          
1212          return $video_code;
1213      }
1214  
1215      /**
1216      * Parses video MyCode.
1217      *
1218      * @param array Matches.
1219      * @return string The built-up video code.
1220      */
1221  	function mycode_parse_video_callback($matches)
1222      {
1223          return $this->mycode_parse_video($matches[1], $matches[2]);
1224      }
1225  
1226      /**
1227      * Parses URLs automatically.
1228      *
1229      * @param string The message to be parsed
1230      * @return string The parsed message.
1231      */
1232  	function mycode_auto_url($message)
1233      {    
1234          $message = " ".$message;
1235          $message = preg_replace("#([\>\s\(\)])(http|https|ftp|news){1}://([^\/\"\s\<\[\.]+\.([^\/\"\s\<\[\.]+\.)*[\w]+(:[0-9]+)?(/[^\"\s<\[]*)?)#i", "$1[url]$2://$3[/url]", $message);
1236          $message = preg_replace("#([\>\s\(\)])(www|ftp)\.(([^\/\"\s\<\[\.]+\.)*[\w]+(:[0-9]+)?(/[^\"\s<\[]*)?)#i", "$1[url]$2.$3[/url]", $message);
1237          $message = my_substr($message, 1);
1238          
1239          return $message;
1240      }
1241  
1242      /**
1243      * Parses list MyCode.
1244      *
1245      * @param string The message to be parsed
1246      * @param string The list type
1247      * @return string The parsed message.
1248      */
1249  	function mycode_parse_list($message, $type="")
1250      {
1251          $message = str_replace('\"', '"', $message);
1252          $message = preg_replace("#\s*\[\*\]\s*#", "</li>\n<li>", $message);
1253          $message .= "</li>";
1254  
1255          if($type)
1256          {
1257              $list = "\n<ol type=\"$type\">$message</ol>\n";
1258          }
1259          else
1260          {
1261              $list = "<ul>$message</ul>\n";
1262          }
1263          $list = preg_replace("#<(ol type=\"$type\"|ul)>\s*</li>#", "<$1>", $list);
1264          return $list;
1265      }
1266  
1267      /**
1268      * Parses list MyCode.
1269      *
1270      * @param array Matches
1271      * @return string The parsed message.
1272      */
1273  	function mycode_parse_list_callback($matches)
1274      {
1275          return $this->mycode_parse_list($matches[1])."\n";
1276      }
1277  
1278      /**
1279      * Parses list MyCode.
1280      *
1281      * @param array Matches
1282      * @return string The parsed message.
1283      */
1284  	function mycode_parse_list_callback_type($matches)
1285      {
1286          return $this->mycode_parse_list($matches[2], $matches[1])."\n";
1287      }
1288  
1289      /**
1290       * Strips smilies from a string
1291        *
1292       * @param string The message for smilies to be stripped from
1293       * @return string The message with smilies stripped
1294       */
1295  	function strip_smilies($message)
1296      {
1297          if($this->smilies_cache == 0)
1298          {
1299              $this->cache_smilies();
1300          }
1301          if(is_array($this->smilies_cache))
1302          {
1303              $message = str_replace($this->smilies_cache, array_keys($this->smilies_cache), $message);
1304          }
1305          return $message;
1306      }
1307      
1308      /**
1309       * Highlights a string
1310        *
1311       * @param string The message to be highligted
1312       * @param string The highlight keywords
1313       * @return string The message with highlight bbcodes
1314       */
1315  	function highlight_message($message, $highlight)
1316      {
1317          if(empty($this->highlight_cache))
1318          {
1319              $this->highlight_cache = build_highlight_array($highlight);
1320          }
1321          
1322          if(is_array($this->highlight_cache) && !empty($this->highlight_cache))
1323          {
1324              $message = preg_replace(array_keys($this->highlight_cache), $this->highlight_cache, $message);
1325          }
1326          
1327          return $message;
1328      }
1329  
1330      /**
1331       * Parses message to plain text equivalents of MyCode.
1332       *
1333       * @param string The message to be parsed
1334       * @return string The parsed message.
1335       */
1336  	function text_parse_message($message, $options=array())
1337      {
1338          global $plugins;
1339          
1340          // Filter bad words if requested.
1341          if($options['filter_badwords'] != 0)
1342          {
1343              $message = $this->parse_badwords($message);
1344          }
1345  
1346          // Parse quotes first
1347          $message = $this->mycode_parse_quotes($message, true);
1348  
1349          $message = preg_replace_callback("#\[php\](.*?)\[/php\](\r\n?|\n?)#is", array($this, 'mycode_parse_php_callback'), $message);
1350          $message = preg_replace_callback("#\[code\](.*?)\[/code\](\r\n?|\n?)#is", array($this, 'mycode_parse_code_callback'), $message);
1351  
1352          $find = array(
1353              "#\[(b|u|i|s|url|email|color|img)\](.*?)\[/\\1\]#is",
1354              "#\[img=([0-9]{1,3})x([0-9]{1,3})\](\r\n?|\n?)(https?://([^<>\"']+?))\[/img\]#is",
1355              "#\[url=([a-z]+?://)([^\r\n\"<]+?)\](.+?)\[/url\]#si",
1356              "#\[url=([^\r\n\"<&\(\)]+?)\](.+?)\[/url\]#si",
1357          );
1358          
1359          $replace = array(
1360              "$2",
1361              "$4",
1362              "$3 ($1$2)",
1363              "$2 ($1)",
1364          );
1365          $message = preg_replace($find, $replace, $message);
1366          
1367          // Replace "me" code and slaps if we have a username
1368          if($options['me_username'])
1369          {
1370              global $lang;
1371              
1372              $message = preg_replace('#(>|^|\r|\n)/me ([^\r\n<]*)#i', "\\1* {$options['me_username']} \\2", $message);
1373              $message = preg_replace('#(>|^|\r|\n)/slap ([^\r\n<]*)#i', "\\1* {$options['me_username']} {$lang->slaps} \\2 {$lang->with_trout}", $message);
1374          }
1375  
1376          // Special code requiring special attention
1377          while(preg_match("#\[list\](.*?)\[/list\]#si", $message))
1378          {
1379              $message = preg_replace_callback("#\s?\[list\](.*?)\[/list\](\r\n?|\n?)#si", array($this, 'mycode_parse_list_callback'), $message);
1380          }
1381  
1382          // Replace lists.
1383          while(preg_match("#\[list=(a|A|i|I|1)\](.*?)\[/list\](\r\n?|\n?)#si", $message))
1384          {
1385              $message = preg_replace_callback("#\s?\[list=(a|A|i|I|1)\](.*?)\[/list\]#si", array($this, 'mycode_parse_list_callback_type'), $message);
1386          }
1387  
1388          // Run plugin hooks
1389          $message = $plugins->run_hooks("text_parse_message", $message);
1390          
1391          return $message;
1392      }
1393  }
1394  ?>


Generated: Tue Oct 8 19:19:50 2013 Cross-referenced by PHPXref 0.7.1