Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

message_parser.php

Zuletzt modifiziert: 09.10.2024, 12:51 - Dateigröße: 51.85 KiB


 0001  <?php
 0002  /**
 0003  *
 0004  * This file is part of the phpBB Forum Software package.
 0005  *
 0006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
 0007  * @license GNU General Public License, version 2 (GPL-2.0)
 0008  *
 0009  * For full copyright and license information, please see
 0010  * the docs/CREDITS.txt file.
 0011  *
 0012  */
 0013   
 0014  /**
 0015  * @ignore
 0016  */
 0017  if (!defined('IN_PHPBB'))
 0018  {
 0019      exit;
 0020  }
 0021   
 0022  if (!class_exists('bbcode'))
 0023  {
 0024      include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
 0025  }
 0026   
 0027  /**
 0028  * BBCODE FIRSTPASS
 0029  * BBCODE first pass class (functions for parsing messages for db storage)
 0030  */
 0031  class bbcode_firstpass extends bbcode
 0032  {
 0033      var $message = '';
 0034      var $warn_msg = array();
 0035      var $parsed_items = array();
 0036   
 0037      /**
 0038      * Parse BBCode
 0039      */
 0040      function parse_bbcode()
 0041      {
 0042          if (!$this->bbcodes)
 0043          {
 0044              $this->bbcode_init();
 0045          }
 0046   
 0047          global $user;
 0048   
 0049          $this->bbcode_bitfield = '';
 0050          $bitfield = new bitfield();
 0051   
 0052          foreach ($this->bbcodes as $bbcode_name => $bbcode_data)
 0053          {
 0054              if (isset($bbcode_data['disabled']) && $bbcode_data['disabled'])
 0055              {
 0056                  foreach ($bbcode_data['regexp'] as $regexp => $replacement)
 0057                  {
 0058                      if (preg_match($regexp, $this->message))
 0059                      {
 0060                          $this->warn_msg[] = sprintf($user->lang['UNAUTHORISED_BBCODE'] , '[' . $bbcode_name . ']');
 0061                          continue;
 0062                      }
 0063                  }
 0064              }
 0065              else
 0066              {
 0067                  foreach ($bbcode_data['regexp'] as $regexp => $replacement)
 0068                  {
 0069                      // The pattern gets compiled and cached by the PCRE extension,
 0070                      // it should not demand recompilation
 0071                      if (preg_match($regexp, $this->message))
 0072                      {
 0073                          $this->message = preg_replace($regexp, $replacement, $this->message);
 0074                          $bitfield->set($bbcode_data['bbcode_id']);
 0075                      }
 0076                  }
 0077              }
 0078          }
 0079   
 0080          $this->bbcode_bitfield = $bitfield->get_base64();
 0081      }
 0082   
 0083      /**
 0084      * Prepare some bbcodes for better parsing
 0085      */
 0086      function prepare_bbcodes()
 0087      {
 0088          // Ok, seems like users instead want the no-parsing of urls, smilies, etc. after and before and within quote tags being tagged as "not a bug".
 0089          // Fine by me ;) Will ease our live... but do not come back and cry at us, we won't hear you.
 0090   
 0091          /* Add newline at the end and in front of each quote block to prevent parsing errors (urls, smilies, etc.)
 0092          if (strpos($this->message, '[quote') !== false && strpos($this->message, '[/quote]') !== false)
 0093          {
 0094              $this->message = str_replace("\r\n", "\n", $this->message);
 0095   
 0096              // We strip newlines and spaces after and before quotes in quotes (trimming) and then add exactly one newline
 0097              $this->message = preg_replace('#\[quote(=&quot;.*?&quot;)?\]\s*(.*?)\s*\[/quote\]#siu', '[quote\1]' . "\n" . '\2' ."\n[/quote]", $this->message);
 0098          }
 0099          */
 0100   
 0101          // Add other checks which needs to be placed before actually parsing anything (be it bbcodes, smilies, urls...)
 0102      }
 0103   
 0104      /**
 0105      * Init bbcode data for later parsing
 0106      */
 0107      function bbcode_init($allow_custom_bbcode = true)
 0108      {
 0109          global $phpbb_dispatcher;
 0110   
 0111          static $rowset;
 0112   
 0113          // This array holds all bbcode data. BBCodes will be processed in this
 0114          // order, so it is important to keep [code] in first position and
 0115          // [quote] in second position.
 0116          // To parse multiline URL we enable dotall option setting only for URL text
 0117          // but not for link itself, thus [url][/url] is not affected.
 0118          $this->bbcodes = array(
 0119              'code'            => array('bbcode_id' => 8,    'regexp' => array('#\[code(?:=([a-z]+))?\](.+\[/code\])#uise' => "\$this->bbcode_code('\$1', '\$2')")),
 0120              'quote'            => array('bbcode_id' => 0,    'regexp' => array('#\[quote(?:=&quot;(.*?)&quot;)?\](.+)\[/quote\]#uise' => "\$this->bbcode_quote('\$0')")),
 0121              'attachment'    => array('bbcode_id' => 12,    'regexp' => array('#\[attachment=([0-9]+)\](.*?)\[/attachment\]#uise' => "\$this->bbcode_attachment('\$1', '\$2')")),
 0122              'b'                => array('bbcode_id' => 1,    'regexp' => array('#\[b\](.*?)\[/b\]#uise' => "\$this->bbcode_strong('\$1')")),
 0123              'i'                => array('bbcode_id' => 2,    'regexp' => array('#\[i\](.*?)\[/i\]#uise' => "\$this->bbcode_italic('\$1')")),
 0124              'url'            => array('bbcode_id' => 3,    'regexp' => array('#\[url(=(.*))?\](?(1)((?s).*(?-s))|(.*))\[/url\]#uiUe' => "\$this->validate_url('\$2', ('\$3') ? '\$3' : '\$4')")),
 0125              'img'            => array('bbcode_id' => 4,    'regexp' => array('#\[img\](.*)\[/img\]#uiUe' => "\$this->bbcode_img('\$1')")),
 0126              'size'            => array('bbcode_id' => 5,    'regexp' => array('#\[size=([\-\+]?\d+)\](.*?)\[/size\]#uise' => "\$this->bbcode_size('\$1', '\$2')")),
 0127              'color'            => array('bbcode_id' => 6,    'regexp' => array('!\[color=(#[0-9a-f]{3}|#[0-9a-f]{6}|[a-z\-]+)\](.*?)\[/color\]!uise' => "\$this->bbcode_color('\$1', '\$2')")),
 0128              'u'                => array('bbcode_id' => 7,    'regexp' => array('#\[u\](.*?)\[/u\]#uise' => "\$this->bbcode_underline('\$1')")),
 0129              'list'            => array('bbcode_id' => 9,    'regexp' => array('#\[list(?:=(?:[a-z0-9]|disc|circle|square))?].*\[/list]#uise' => "\$this->bbcode_parse_list('\$0')")),
 0130              'email'            => array('bbcode_id' => 10,    'regexp' => array('#\[email=?(.*?)?\](.*?)\[/email\]#uise' => "\$this->validate_email('\$1', '\$2')")),
 0131              'flash'            => array('bbcode_id' => 11,    'regexp' => array('#\[flash=([0-9]+),([0-9]+)\](.*?)\[/flash\]#uie' => "\$this->bbcode_flash('\$1', '\$2', '\$3')"))
 0132          );
 0133   
 0134          // Zero the parsed items array
 0135          $this->parsed_items = array();
 0136   
 0137          foreach ($this->bbcodes as $tag => $bbcode_data)
 0138          {
 0139              $this->parsed_items[$tag] = 0;
 0140          }
 0141   
 0142          if (!$allow_custom_bbcode)
 0143          {
 0144              return;
 0145          }
 0146   
 0147          if (!is_array($rowset))
 0148          {
 0149              global $db;
 0150              $rowset = array();
 0151   
 0152              $sql = 'SELECT *
 0153                  FROM ' . BBCODES_TABLE;
 0154              $result = $db->sql_query($sql);
 0155   
 0156              while ($row = $db->sql_fetchrow($result))
 0157              {
 0158                  $rowset[] = $row;
 0159              }
 0160              $db->sql_freeresult($result);
 0161          }
 0162   
 0163          foreach ($rowset as $row)
 0164          {
 0165              $this->bbcodes[$row['bbcode_tag']] = array(
 0166                  'bbcode_id'    => (int) $row['bbcode_id'],
 0167                  'regexp'    => array($row['first_pass_match'] => str_replace('$uid', $this->bbcode_uid, $row['first_pass_replace']))
 0168              );
 0169          }
 0170   
 0171          $bbcodes = $this->bbcodes;
 0172   
 0173          /**
 0174          * Event to modify the bbcode data for later parsing
 0175          *
 0176          * @event core.modify_bbcode_init
 0177          * @var array    bbcodes        Array of bbcode data for use in parsing
 0178          * @var array    rowset        Array of bbcode data from the database
 0179          * @since 3.1.0-a3
 0180          */
 0181          $vars = array('bbcodes', 'rowset');
 0182          extract($phpbb_dispatcher->trigger_event('core.modify_bbcode_init', compact($vars)));
 0183   
 0184          $this->bbcodes = $bbcodes;
 0185      }
 0186   
 0187      /**
 0188      * Making some pre-checks for bbcodes as well as increasing the number of parsed items
 0189      */
 0190      function check_bbcode($bbcode, &$in)
 0191      {
 0192          // when using the /e modifier, preg_replace slashes double-quotes but does not
 0193          // seem to slash anything else
 0194          $in = str_replace("\r\n", "\n", str_replace('\"', '"', $in));
 0195   
 0196          // Trimming here to make sure no empty bbcodes are parsed accidently
 0197          if (trim($in) == '')
 0198          {
 0199              return false;
 0200          }
 0201   
 0202          $this->parsed_items[$bbcode]++;
 0203   
 0204          return true;
 0205      }
 0206   
 0207      /**
 0208      * Transform some characters in valid bbcodes
 0209      */
 0210      function bbcode_specialchars($text)
 0211      {
 0212          $str_from = array('<', '>', '[', ']', '.', ':');
 0213          $str_to = array('&lt;', '&gt;', '&#91;', '&#93;', '&#46;', '&#58;');
 0214   
 0215          return str_replace($str_from, $str_to, $text);
 0216      }
 0217   
 0218      /**
 0219      * Parse size tag
 0220      */
 0221      function bbcode_size($stx, $in)
 0222      {
 0223          global $user, $config;
 0224   
 0225          if (!$this->check_bbcode('size', $in))
 0226          {
 0227              return $in;
 0228          }
 0229   
 0230          if ($config['max_' . $this->mode . '_font_size'] && $config['max_' . $this->mode . '_font_size'] < $stx)
 0231          {
 0232              $this->warn_msg[] = $user->lang('MAX_FONT_SIZE_EXCEEDED', (int) $config['max_' . $this->mode . '_font_size']);
 0233   
 0234              return '[size=' . $stx . ']' . $in . '[/size]';
 0235          }
 0236   
 0237          // Do not allow size=0
 0238          if ($stx <= 0)
 0239          {
 0240              return '[size=' . $stx . ']' . $in . '[/size]';
 0241          }
 0242   
 0243          return '[size=' . $stx . ':' . $this->bbcode_uid . ']' . $in . '[/size:' . $this->bbcode_uid . ']';
 0244      }
 0245   
 0246      /**
 0247      * Parse color tag
 0248      */
 0249      function bbcode_color($stx, $in)
 0250      {
 0251          if (!$this->check_bbcode('color', $in))
 0252          {
 0253              return $in;
 0254          }
 0255   
 0256          return '[color=' . $stx . ':' . $this->bbcode_uid . ']' . $in . '[/color:' . $this->bbcode_uid . ']';
 0257      }
 0258   
 0259      /**
 0260      * Parse u tag
 0261      */
 0262      function bbcode_underline($in)
 0263      {
 0264          if (!$this->check_bbcode('u', $in))
 0265          {
 0266              return $in;
 0267          }
 0268   
 0269          return '[u:' . $this->bbcode_uid . ']' . $in . '[/u:' . $this->bbcode_uid . ']';
 0270      }
 0271   
 0272      /**
 0273      * Parse b tag
 0274      */
 0275      function bbcode_strong($in)
 0276      {
 0277          if (!$this->check_bbcode('b', $in))
 0278          {
 0279              return $in;
 0280          }
 0281   
 0282          return '[b:' . $this->bbcode_uid . ']' . $in . '[/b:' . $this->bbcode_uid . ']';
 0283      }
 0284   
 0285      /**
 0286      * Parse i tag
 0287      */
 0288      function bbcode_italic($in)
 0289      {
 0290          if (!$this->check_bbcode('i', $in))
 0291          {
 0292              return $in;
 0293          }
 0294   
 0295          return '[i:' . $this->bbcode_uid . ']' . $in . '[/i:' . $this->bbcode_uid . ']';
 0296      }
 0297   
 0298      /**
 0299      * Parse img tag
 0300      */
 0301      function bbcode_img($in)
 0302      {
 0303          global $user, $config;
 0304   
 0305          if (!$this->check_bbcode('img', $in))
 0306          {
 0307              return $in;
 0308          }
 0309   
 0310          $in = trim($in);
 0311          $error = false;
 0312   
 0313          $in = str_replace(' ', '%20', $in);
 0314   
 0315          // Checking urls
 0316          if (!preg_match('#^' . get_preg_expression('url') . '$#i', $in) && !preg_match('#^' . get_preg_expression('www_url') . '$#i', $in))
 0317          {
 0318              return '[img]' . $in . '[/img]';
 0319          }
 0320   
 0321          // Try to cope with a common user error... not specifying a protocol but only a subdomain
 0322          if (!preg_match('#^[a-z0-9]+://#i', $in))
 0323          {
 0324              $in = 'http://' . $in;
 0325          }
 0326   
 0327          if ($config['max_' . $this->mode . '_img_height'] || $config['max_' . $this->mode . '_img_width'])
 0328          {
 0329              $stats = @getimagesize(htmlspecialchars_decode($in));
 0330   
 0331              if ($stats === false)
 0332              {
 0333                  $error = true;
 0334                  $this->warn_msg[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
 0335              }
 0336              else
 0337              {
 0338                  if ($config['max_' . $this->mode . '_img_height'] && $config['max_' . $this->mode . '_img_height'] < $stats[1])
 0339                  {
 0340                      $error = true;
 0341                      $this->warn_msg[] = $user->lang('MAX_IMG_HEIGHT_EXCEEDED', (int) $config['max_' . $this->mode . '_img_height']);
 0342                  }
 0343   
 0344                  if ($config['max_' . $this->mode . '_img_width'] && $config['max_' . $this->mode . '_img_width'] < $stats[0])
 0345                  {
 0346                      $error = true;
 0347                      $this->warn_msg[] = $user->lang('MAX_IMG_WIDTH_EXCEEDED', (int) $config['max_' . $this->mode . '_img_width']);
 0348                  }
 0349              }
 0350          }
 0351   
 0352          if ($error || $this->path_in_domain($in))
 0353          {
 0354              return '[img]' . $in . '[/img]';
 0355          }
 0356   
 0357          return '[img:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($in) . '[/img:' . $this->bbcode_uid . ']';
 0358      }
 0359   
 0360      /**
 0361      * Parse flash tag
 0362      */
 0363      function bbcode_flash($width, $height, $in)
 0364      {
 0365          global $user, $config;
 0366   
 0367          if (!$this->check_bbcode('flash', $in))
 0368          {
 0369              return $in;
 0370          }
 0371   
 0372          $in = trim($in);
 0373          $error = false;
 0374   
 0375          // Do not allow 0-sizes generally being entered
 0376          if ($width <= 0 || $height <= 0)
 0377          {
 0378              return '[flash=' . $width . ',' . $height . ']' . $in . '[/flash]';
 0379          }
 0380   
 0381          $in = str_replace(' ', '%20', $in);
 0382   
 0383          // Make sure $in is a URL.
 0384          if (!preg_match('#^' . get_preg_expression('url') . '$#i', $in) &&
 0385              !preg_match('#^' . get_preg_expression('www_url') . '$#i', $in))
 0386          {
 0387              return '[flash=' . $width . ',' . $height . ']' . $in . '[/flash]';
 0388          }
 0389   
 0390          // Apply the same size checks on flash files as on images
 0391          if ($config['max_' . $this->mode . '_img_height'] || $config['max_' . $this->mode . '_img_width'])
 0392          {
 0393              if ($config['max_' . $this->mode . '_img_height'] && $config['max_' . $this->mode . '_img_height'] < $height)
 0394              {
 0395                  $error = true;
 0396                  $this->warn_msg[] = $user->lang('MAX_FLASH_HEIGHT_EXCEEDED', (int) $config['max_' . $this->mode . '_img_height']);
 0397              }
 0398   
 0399              if ($config['max_' . $this->mode . '_img_width'] && $config['max_' . $this->mode . '_img_width'] < $width)
 0400              {
 0401                  $error = true;
 0402                  $this->warn_msg[] = $user->lang('MAX_FLASH_WIDTH_EXCEEDED', (int) $config['max_' . $this->mode . '_img_width']);
 0403              }
 0404          }
 0405   
 0406          if ($error || $this->path_in_domain($in))
 0407          {
 0408              return '[flash=' . $width . ',' . $height . ']' . $in . '[/flash]';
 0409          }
 0410   
 0411          return '[flash=' . $width . ',' . $height . ':' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($in) . '[/flash:' . $this->bbcode_uid . ']';
 0412      }
 0413   
 0414      /**
 0415      * Parse inline attachments [ia]
 0416      */
 0417      function bbcode_attachment($stx, $in)
 0418      {
 0419          if (!$this->check_bbcode('attachment', $in))
 0420          {
 0421              return $in;
 0422          }
 0423   
 0424          return '[attachment=' . $stx . ':' . $this->bbcode_uid . ']<!-- ia' . $stx . ' -->' . trim($in) . '<!-- ia' . $stx . ' -->[/attachment:' . $this->bbcode_uid . ']';
 0425      }
 0426   
 0427      /**
 0428      * Parse code text from code tag
 0429      * @access private
 0430      */
 0431      function bbcode_parse_code($stx, &$code)
 0432      {
 0433          switch (strtolower($stx))
 0434          {
 0435              case 'php':
 0436   
 0437                  $remove_tags = false;
 0438   
 0439                  $str_from = array('&lt;', '&gt;', '&#91;', '&#93;', '&#46;', '&#58;', '&#058;');
 0440                  $str_to = array('<', '>', '[', ']', '.', ':', ':');
 0441                  $code = str_replace($str_from, $str_to, $code);
 0442   
 0443                  if (!preg_match('/\<\?.*?\?\>/is', $code))
 0444                  {
 0445                      $remove_tags = true;
 0446                      $code = "<?php $code ?>";
 0447                  }
 0448   
 0449                  $conf = array('highlight.bg', 'highlight.comment', 'highlight.default', 'highlight.html', 'highlight.keyword', 'highlight.string');
 0450                  foreach ($conf as $ini_var)
 0451                  {
 0452                      @ini_set($ini_var, str_replace('highlight.', 'syntax', $ini_var));
 0453                  }
 0454   
 0455                  // Because highlight_string is specialcharing the text (but we already did this before), we have to reverse this in order to get correct results
 0456                  $code = htmlspecialchars_decode($code);
 0457                  $code = highlight_string($code, true);
 0458   
 0459                  $str_from = array('<span style="color: ', '<font color="syntax', '</font>', '<code>', '</code>','[', ']', '.', ':');
 0460                  $str_to = array('<span class="', '<span class="syntax', '</span>', '', '', '&#91;', '&#93;', '&#46;', '&#58;');
 0461   
 0462                  if ($remove_tags)
 0463                  {
 0464                      $str_from[] = '<span class="syntaxdefault">&lt;?php </span>';
 0465                      $str_to[] = '';
 0466                      $str_from[] = '<span class="syntaxdefault">&lt;?php&nbsp;';
 0467                      $str_to[] = '<span class="syntaxdefault">';
 0468                  }
 0469   
 0470                  $code = str_replace($str_from, $str_to, $code);
 0471                  $code = preg_replace('#^(<span class="[a-z_]+">)\n?(.*?)\n?(</span>)$#is', '$1$2$3', $code);
 0472   
 0473                  if ($remove_tags)
 0474                  {
 0475                      $code = preg_replace('#(<span class="[a-z]+">)?\?&gt;(</span>)#', '$1&nbsp;$2', $code);
 0476                  }
 0477   
 0478                  $code = preg_replace('#^<span class="[a-z]+"><span class="([a-z]+)">(.*)</span></span>#s', '<span class="$1">$2</span>', $code);
 0479                  $code = preg_replace('#(?:\s++|&nbsp;)*+</span>$#u', '</span>', $code);
 0480   
 0481                  // remove newline at the end
 0482                  if (!empty($code) && substr($code, -1) == "\n")
 0483                  {
 0484                      $code = substr($code, 0, -1);
 0485                  }
 0486   
 0487                  return "[code=$stx:" . $this->bbcode_uid . ']' . $code . '[/code:' . $this->bbcode_uid . ']';
 0488              break;
 0489   
 0490              default:
 0491                  return '[code:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($code) . '[/code:' . $this->bbcode_uid . ']';
 0492              break;
 0493          }
 0494      }
 0495   
 0496      /**
 0497      * Parse code tag
 0498      * Expects the argument to start right after the opening [code] tag and to end with [/code]
 0499      */
 0500      function bbcode_code($stx, $in)
 0501      {
 0502          if (!$this->check_bbcode('code', $in))
 0503          {
 0504              return $in;
 0505          }
 0506   
 0507          // We remove the hardcoded elements from the code block here because it is not used in code blocks
 0508          // Having it here saves us one preg_replace per message containing [code] blocks
 0509          // Additionally, magic url parsing should go after parsing bbcodes, but for safety those are stripped out too...
 0510          $htm_match = get_preg_expression('bbcode_htm');
 0511          unset($htm_match[4], $htm_match[5]);
 0512          $htm_replace = array('\1', '\1', '\2', '\1');
 0513   
 0514          $out = $code_block = '';
 0515          $open = 1;
 0516   
 0517          while ($in)
 0518          {
 0519              // Determine position and tag length of next code block
 0520              preg_match('#(.*?)(\[code(?:=([a-z]+))?\])(.+)#is', $in, $buffer);
 0521              $pos = (isset($buffer[1])) ? strlen($buffer[1]) : false;
 0522              $tag_length = (isset($buffer[2])) ? strlen($buffer[2]) : false;
 0523   
 0524              // Determine position of ending code tag
 0525              $pos2 = stripos($in, '[/code]');
 0526   
 0527              // Which is the next block, ending code or code block
 0528              if ($pos !== false && $pos < $pos2)
 0529              {
 0530                  // Open new block
 0531                  if (!$open)
 0532                  {
 0533                      $out .= substr($in, 0, $pos);
 0534                      $in = substr($in, $pos);
 0535                      $stx = (isset($buffer[3])) ? $buffer[3] : '';
 0536                      $code_block = '';
 0537                  }
 0538                  else
 0539                  {
 0540                      // Already opened block, just append to the current block
 0541                      $code_block .= substr($in, 0, $pos) . ((isset($buffer[2])) ? $buffer[2] : '');
 0542                      $in = substr($in, $pos);
 0543                  }
 0544   
 0545                  $in = substr($in, $tag_length);
 0546                  $open++;
 0547              }
 0548              else
 0549              {
 0550                  // Close the block
 0551                  if ($open == 1)
 0552                  {
 0553                      $code_block .= substr($in, 0, $pos2);
 0554                      $code_block = preg_replace($htm_match, $htm_replace, $code_block);
 0555   
 0556                      // Parse this code block
 0557                      $out .= $this->bbcode_parse_code($stx, $code_block);
 0558                      $code_block = '';
 0559                      $open--;
 0560                  }
 0561                  else if ($open)
 0562                  {
 0563                      // Close one open tag... add to the current code block
 0564                      $code_block .= substr($in, 0, $pos2 + 7);
 0565                      $open--;
 0566                  }
 0567                  else
 0568                  {
 0569                      // end code without opening code... will be always outside code block
 0570                      $out .= substr($in, 0, $pos2 + 7);
 0571                  }
 0572   
 0573                  $in = substr($in, $pos2 + 7);
 0574              }
 0575          }
 0576   
 0577          // if now $code_block has contents we need to parse the remaining code while removing the last closing tag to match up.
 0578          if ($code_block)
 0579          {
 0580              $code_block = substr($code_block, 0, -7);
 0581              $code_block = preg_replace($htm_match, $htm_replace, $code_block);
 0582   
 0583              $out .= $this->bbcode_parse_code($stx, $code_block);
 0584          }
 0585   
 0586          return $out;
 0587      }
 0588   
 0589      /**
 0590      * Parse list bbcode
 0591      * Expects the argument to start with a tag
 0592      */
 0593      function bbcode_parse_list($in)
 0594      {
 0595          if (!$this->check_bbcode('list', $in))
 0596          {
 0597              return $in;
 0598          }
 0599   
 0600          // $tok holds characters to stop at. Since the string starts with a '[' we'll get everything up to the first ']' which should be the opening [list] tag
 0601          $tok = ']';
 0602          $out = '[';
 0603   
 0604          // First character is [
 0605          $in = substr($in, 1);
 0606          $list_end_tags = $item_end_tags = array();
 0607   
 0608          do
 0609          {
 0610              $pos = strlen($in);
 0611   
 0612              for ($i = 0, $tok_len = strlen($tok); $i < $tok_len; ++$i)
 0613              {
 0614                  $tmp_pos = strpos($in, $tok[$i]);
 0615   
 0616                  if ($tmp_pos !== false && $tmp_pos < $pos)
 0617                  {
 0618                      $pos = $tmp_pos;
 0619                  }
 0620              }
 0621   
 0622              $buffer = substr($in, 0, $pos);
 0623              $tok = $in[$pos];
 0624   
 0625              $in = substr($in, $pos + 1);
 0626   
 0627              if ($tok == ']')
 0628              {
 0629                  // if $tok is ']' the buffer holds a tag
 0630                  if (strtolower($buffer) == '/list' && sizeof($list_end_tags))
 0631                  {
 0632                      // valid [/list] tag, check nesting so that we don't hit false positives
 0633                      if (sizeof($item_end_tags) && sizeof($item_end_tags) >= sizeof($list_end_tags))
 0634                      {
 0635                          // current li tag has not been closed
 0636                          $out = preg_replace('/\n?\[$/', '[', $out) . array_pop($item_end_tags) . '][';
 0637                      }
 0638   
 0639                      $out .= array_pop($list_end_tags) . ']';
 0640                      $tok = '[';
 0641                  }
 0642                  else if (preg_match('#^list(=[0-9a-z]+)?$#i', $buffer, $m))
 0643                  {
 0644                      // sub-list, add a closing tag
 0645                      if (empty($m[1]) || preg_match('/^=(?:disc|square|circle)$/i', $m[1]))
 0646                      {
 0647                          array_push($list_end_tags, '/list:u:' . $this->bbcode_uid);
 0648                      }
 0649                      else
 0650                      {
 0651                          array_push($list_end_tags, '/list:o:' . $this->bbcode_uid);
 0652                      }
 0653                      $out .= 'list' . substr($buffer, 4) . ':' . $this->bbcode_uid . ']';
 0654                      $tok = '[';
 0655                  }
 0656                  else
 0657                  {
 0658                      if (($buffer == '*' || substr($buffer, -2) == '[*') && sizeof($list_end_tags))
 0659                      {
 0660                          // the buffer holds a bullet tag and we have a [list] tag open
 0661                          if (sizeof($item_end_tags) >= sizeof($list_end_tags))
 0662                          {
 0663                              if (substr($buffer, -2) == '[*')
 0664                              {
 0665                                  $out .= substr($buffer, 0, -2) . '[';
 0666                              }
 0667                              // current li tag has not been closed
 0668                              if (preg_match('/\n\[$/', $out, $m))
 0669                              {
 0670                                  $out = preg_replace('/\n\[$/', '[', $out);
 0671                                  $buffer = array_pop($item_end_tags) . "]\n[*:" . $this->bbcode_uid;
 0672                              }
 0673                              else
 0674                              {
 0675                                  $buffer = array_pop($item_end_tags) . '][*:' . $this->bbcode_uid;
 0676                              }
 0677                          }
 0678                          else
 0679                          {
 0680                              $buffer = '*:' . $this->bbcode_uid;
 0681                          }
 0682   
 0683                          $item_end_tags[] = '/*:m:' . $this->bbcode_uid;
 0684                      }
 0685                      else if ($buffer == '/*')
 0686                      {
 0687                          array_pop($item_end_tags);
 0688                          $buffer = '/*:' . $this->bbcode_uid;
 0689                      }
 0690   
 0691                      $out .= $buffer . $tok;
 0692                      $tok = '[]';
 0693                  }
 0694              }
 0695              else
 0696              {
 0697                  // Not within a tag, just add buffer to the return string
 0698                  $out .= $buffer . $tok;
 0699                  $tok = ($tok == '[') ? ']' : '[]';
 0700              }
 0701          }
 0702          while ($in);
 0703   
 0704          // do we have some tags open? close them now
 0705          if (sizeof($item_end_tags))
 0706          {
 0707              $out .= '[' . implode('][', $item_end_tags) . ']';
 0708          }
 0709          if (sizeof($list_end_tags))
 0710          {
 0711              $out .= '[' . implode('][', $list_end_tags) . ']';
 0712          }
 0713   
 0714          return $out;
 0715      }
 0716   
 0717      /**
 0718      * Parse quote bbcode
 0719      * Expects the argument to start with a tag
 0720      */
 0721      function bbcode_quote($in)
 0722      {
 0723          global $config, $user;
 0724   
 0725          $in = str_replace("\r\n", "\n", str_replace('\"', '"', trim($in)));
 0726   
 0727          if (!$in)
 0728          {
 0729              return '';
 0730          }
 0731   
 0732          // To let the parser not catch tokens within quote_username quotes we encode them before we start this...
 0733          $in = preg_replace('#quote=&quot;(.*?)&quot;\]#ie', "'quote=&quot;' . str_replace(array('[', ']', '\\\"'), array('&#91;', '&#93;', '\"'), '\$1') . '&quot;]'", $in);
 0734   
 0735          $tok = ']';
 0736          $out = '[';
 0737   
 0738          $in = substr($in, 1);
 0739          $close_tags = $error_ary = array();
 0740          $buffer = '';
 0741   
 0742          do
 0743          {
 0744              $pos = strlen($in);
 0745              for ($i = 0, $tok_len = strlen($tok); $i < $tok_len; ++$i)
 0746              {
 0747                  $tmp_pos = strpos($in, $tok[$i]);
 0748                  if ($tmp_pos !== false && $tmp_pos < $pos)
 0749                  {
 0750                      $pos = $tmp_pos;
 0751                  }
 0752              }
 0753   
 0754              $buffer .= substr($in, 0, $pos);
 0755              $tok = $in[$pos];
 0756              $in = substr($in, $pos + 1);
 0757   
 0758              if ($tok == ']')
 0759              {
 0760                  if (strtolower($buffer) == '/quote' && sizeof($close_tags) && substr($out, -1, 1) == '[')
 0761                  {
 0762                      // we have found a closing tag
 0763                      $out .= array_pop($close_tags) . ']';
 0764                      $tok = '[';
 0765                      $buffer = '';
 0766   
 0767                      /* Add space at the end of the closing tag if not happened before to allow following urls/smilies to be parsed correctly
 0768                      * Do not try to think for the user. :/ Do not parse urls/smilies if there is no space - is the same as with other bbcodes too.
 0769                      * Also, we won't have any spaces within $in anyway, only adding up spaces -> #10982
 0770                      if (!$in || $in[0] !== ' ')
 0771                      {
 0772                          $out .= ' ';
 0773                      }*/
 0774                  }
 0775                  else if (preg_match('#^quote(?:=&quot;(.*?)&quot;)?$#is', $buffer, $m) && substr($out, -1, 1) == '[')
 0776                  {
 0777                      $this->parsed_items['quote']++;
 0778   
 0779                      // the buffer holds a valid opening tag
 0780                      if ($config['max_quote_depth'] && sizeof($close_tags) >= $config['max_quote_depth'])
 0781                      {
 0782                          if ($config['max_quote_depth'] == 1)
 0783                          {
 0784                              // Depth 1 - no nesting is allowed
 0785                              $error_ary['quote_depth'] = $user->lang('QUOTE_NO_NESTING');
 0786                          }
 0787                          else
 0788                          {
 0789                              // There are too many nested quotes
 0790                              $error_ary['quote_depth'] = $user->lang('QUOTE_DEPTH_EXCEEDED', (int) $config['max_quote_depth']);
 0791                          }
 0792   
 0793                          $out .= $buffer . $tok;
 0794                          $tok = '[]';
 0795                          $buffer = '';
 0796   
 0797                          continue;
 0798                      }
 0799   
 0800                      array_push($close_tags, '/quote:' . $this->bbcode_uid);
 0801   
 0802                      if (isset($m[1]) && $m[1])
 0803                      {
 0804                          $username = str_replace(array('&#91;', '&#93;'), array('[', ']'), $m[1]);
 0805                          $username = preg_replace('#\[(?!b|i|u|color|url|email|/b|/i|/u|/color|/url|/email)#iU', '&#91;$1', $username);
 0806   
 0807                          $end_tags = array();
 0808                          $error = false;
 0809   
 0810                          preg_match_all('#\[((?:/)?(?:[a-z]+))#i', $username, $tags);
 0811                          foreach ($tags[1] as $tag)
 0812                          {
 0813                              if ($tag[0] != '/')
 0814                              {
 0815                                  $end_tags[] = '/' . $tag;
 0816                              }
 0817                              else
 0818                              {
 0819                                  $end_tag = array_pop($end_tags);
 0820                                  $error = ($end_tag != $tag) ? true : false;
 0821                              }
 0822                          }
 0823   
 0824                          if ($error)
 0825                          {
 0826                              $username = $m[1];
 0827                          }
 0828   
 0829                          $out .= 'quote=&quot;' . $username . '&quot;:' . $this->bbcode_uid . ']';
 0830                      }
 0831                      else
 0832                      {
 0833                          $out .= 'quote:' . $this->bbcode_uid . ']';
 0834                      }
 0835   
 0836                      $tok = '[';
 0837                      $buffer = '';
 0838                  }
 0839                  else if (preg_match('#^quote=&quot;(.*?)#is', $buffer, $m))
 0840                  {
 0841                      // the buffer holds an invalid opening tag
 0842                      $buffer .= ']';
 0843                  }
 0844                  else
 0845                  {
 0846                      $out .= $buffer . $tok;
 0847                      $tok = '[]';
 0848                      $buffer = '';
 0849                  }
 0850              }
 0851              else
 0852              {
 0853  /**
 0854  *                Old quote code working fine, but having errors listed in bug #3572
 0855  *
 0856  *                $out .= $buffer . $tok;
 0857  *                $tok = ($tok == '[') ? ']' : '[]';
 0858  *                $buffer = '';
 0859  */
 0860   
 0861                  $out .= $buffer . $tok;
 0862   
 0863                  if ($tok == '[')
 0864                  {
 0865                      // Search the text for the next tok... if an ending quote comes first, then change tok to []
 0866                      $pos1 = stripos($in, '[/quote');
 0867                      // If the token ] comes first, we change it to ]
 0868                      $pos2 = strpos($in, ']');
 0869                      // If the token [ comes first, we change it to [
 0870                      $pos3 = strpos($in, '[');
 0871   
 0872                      if ($pos1 !== false && ($pos2 === false || $pos1 < $pos2) && ($pos3 === false || $pos1 < $pos3))
 0873                      {
 0874                          $tok = '[]';
 0875                      }
 0876                      else if ($pos3 !== false && ($pos2 === false || $pos3 < $pos2))
 0877                      {
 0878                          $tok = '[';
 0879                      }
 0880                      else
 0881                      {
 0882                          $tok = ']';
 0883                      }
 0884                  }
 0885                  else
 0886                  {
 0887                      $tok = '[]';
 0888                  }
 0889                  $buffer = '';
 0890              }
 0891          }
 0892          while ($in);
 0893   
 0894          $out .= $buffer;
 0895   
 0896          if (sizeof($close_tags))
 0897          {
 0898              $out .= '[' . implode('][', $close_tags) . ']';
 0899          }
 0900   
 0901          foreach ($error_ary as $error_msg)
 0902          {
 0903              $this->warn_msg[] = $error_msg;
 0904          }
 0905   
 0906          return $out;
 0907      }
 0908   
 0909      /**
 0910      * Validate email
 0911      */
 0912      function validate_email($var1, $var2)
 0913      {
 0914          $var1 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var1)));
 0915          $var2 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var2)));
 0916   
 0917          $txt = $var2;
 0918          $email = ($var1) ? $var1 : $var2;
 0919   
 0920          $validated = true;
 0921   
 0922          if (!preg_match('/^' . get_preg_expression('email') . '$/i', $email))
 0923          {
 0924              $validated = false;
 0925          }
 0926   
 0927          if (!$validated)
 0928          {
 0929              return '[email' . (($var1) ? "=$var1" : '') . ']' . $var2 . '[/email]';
 0930          }
 0931   
 0932          $this->parsed_items['email']++;
 0933   
 0934          if ($var1)
 0935          {
 0936              $retval = '[email=' . $this->bbcode_specialchars($email) . ':' . $this->bbcode_uid . ']' . $txt . '[/email:' . $this->bbcode_uid . ']';
 0937          }
 0938          else
 0939          {
 0940              $retval = '[email:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($email) . '[/email:' . $this->bbcode_uid . ']';
 0941          }
 0942   
 0943          return $retval;
 0944      }
 0945   
 0946      /**
 0947      * Validate url
 0948      *
 0949      * @param string $var1 optional url parameter for url bbcode: [url(=$var1)]$var2[/url]
 0950      * @param string $var2 url bbcode content: [url(=$var1)]$var2[/url]
 0951      */
 0952      function validate_url($var1, $var2)
 0953      {
 0954          global $config;
 0955   
 0956          $var1 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var1)));
 0957          $var2 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var2)));
 0958   
 0959          $url = ($var1) ? $var1 : $var2;
 0960   
 0961          if ($var1 && !$var2)
 0962          {
 0963              $var2 = $var1;
 0964          }
 0965   
 0966          if (!$url)
 0967          {
 0968              return '[url' . (($var1) ? '=' . $var1 : '') . ']' . $var2 . '[/url]';
 0969          }
 0970   
 0971          $valid = false;
 0972   
 0973          $url = str_replace(' ', '%20', $url);
 0974   
 0975          // Checking urls
 0976          if (preg_match('#^' . get_preg_expression('url') . '$#i', $url) ||
 0977              preg_match('#^' . get_preg_expression('www_url') . '$#i', $url) ||
 0978              preg_match('#^' . preg_quote(generate_board_url(), '#') . get_preg_expression('relative_url') . '$#i', $url))
 0979          {
 0980              $valid = true;
 0981          }
 0982   
 0983          if ($valid)
 0984          {
 0985              $this->parsed_items['url']++;
 0986   
 0987              // if there is no scheme, then add http schema
 0988              if (!preg_match('#^[a-z][a-z\d+\-.]*:/{2}#i', $url))
 0989              {
 0990                  $url = 'http://' . $url;
 0991              }
 0992   
 0993              // Is this a link to somewhere inside this board? If so then remove the session id from the url
 0994              if (strpos($url, generate_board_url()) !== false && strpos($url, 'sid=') !== false)
 0995              {
 0996                  $url = preg_replace('/(&amp;|\?)sid=[0-9a-f]{32}&amp;/', '\1', $url);
 0997                  $url = preg_replace('/(&amp;|\?)sid=[0-9a-f]{32}$/', '', $url);
 0998                  $url = append_sid($url);
 0999              }
 1000   
 1001              return ($var1) ? '[url=' . $this->bbcode_specialchars($url) . ':' . $this->bbcode_uid . ']' . $var2 . '[/url:' . $this->bbcode_uid . ']' : '[url:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($url) . '[/url:' . $this->bbcode_uid . ']';
 1002          }
 1003   
 1004          return '[url' . (($var1) ? '=' . $var1 : '') . ']' . $var2 . '[/url]';
 1005      }
 1006   
 1007      /**
 1008      * Check if url is pointing to this domain/script_path/php-file
 1009      *
 1010      * @param string $url the url to check
 1011      * @return true if the url is pointing to this domain/script_path/php-file, false if not
 1012      *
 1013      * @access private
 1014      */
 1015      function path_in_domain($url)
 1016      {
 1017          global $config, $phpEx, $user;
 1018   
 1019          if ($config['force_server_vars'])
 1020          {
 1021              $check_path = $config['script_path'];
 1022          }
 1023          else
 1024          {
 1025              $check_path = ($user->page['root_script_path'] != '/') ? substr($user->page['root_script_path'], 0, -1) : '/';
 1026          }
 1027   
 1028          // Is the user trying to link to a php file in this domain and script path?
 1029          if (strpos($url, ".{$phpEx}") !== false && strpos($url, $check_path) !== false)
 1030          {
 1031              $server_name = $user->host;
 1032   
 1033              // Forcing server vars is the only way to specify/override the protocol
 1034              if ($config['force_server_vars'] || !$server_name)
 1035              {
 1036                  $server_name = $config['server_name'];
 1037              }
 1038   
 1039              // Check again in correct order...
 1040              $pos_ext = strpos($url, ".{$phpEx}");
 1041              $pos_path = strpos($url, $check_path);
 1042              $pos_domain = strpos($url, $server_name);
 1043   
 1044              if ($pos_domain !== false && $pos_path >= $pos_domain && $pos_ext >= $pos_path)
 1045              {
 1046                  // Ok, actually we allow linking to some files (this may be able to be extended in some way later...)
 1047                  if (strpos($url, '/' . $check_path . '/download/file.' . $phpEx) !== 0)
 1048                  {
 1049                      return false;
 1050                  }
 1051   
 1052                  return true;
 1053              }
 1054          }
 1055   
 1056          return false;
 1057      }
 1058  }
 1059   
 1060  /**
 1061  * Main message parser for posting, pm, etc. takes raw message
 1062  * and parses it for attachments, bbcode and smilies
 1063  */
 1064  class parse_message extends bbcode_firstpass
 1065  {
 1066      var $attachment_data = array();
 1067      var $filename_data = array();
 1068   
 1069      // Helps ironing out user error
 1070      var $message_status = '';
 1071   
 1072      var $allow_img_bbcode = true;
 1073      var $allow_flash_bbcode = true;
 1074      var $allow_quote_bbcode = true;
 1075      var $allow_url_bbcode = true;
 1076   
 1077      var $mode;
 1078   
 1079      /**
 1080      * The plupload object used for dealing with attachments
 1081      * @var \phpbb\plupload\plupload
 1082      */
 1083      protected $plupload;
 1084   
 1085      /**
 1086      * The mimetype guesser object used for attachment mimetypes
 1087      * @var \phpbb\mimetype\guesser
 1088      */
 1089      protected $mimetype_guesser;
 1090   
 1091      /**
 1092      * Init - give message here or manually
 1093      */
 1094      function parse_message($message = '')
 1095      {
 1096          // Init BBCode UID
 1097          $this->bbcode_uid = substr(base_convert(unique_id(), 16, 36), 0, BBCODE_UID_LEN);
 1098          $this->message = $message;
 1099      }
 1100   
 1101      /**
 1102      * Parse Message
 1103      */
 1104      function parse($allow_bbcode, $allow_magic_url, $allow_smilies, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $allow_url_bbcode = true, $update_this_message = true, $mode = 'post')
 1105      {
 1106          global $config, $db, $user;
 1107   
 1108          $this->mode = $mode;
 1109   
 1110          foreach (array('chars', 'smilies', 'urls', 'font_size', 'img_height', 'img_width') as $key)
 1111          {
 1112              if (!isset($config['max_' . $mode . '_' . $key]))
 1113              {
 1114                  $config['max_' . $mode . '_' . $key] = 0;
 1115              }
 1116          }
 1117   
 1118          $this->allow_img_bbcode = $allow_img_bbcode;
 1119          $this->allow_flash_bbcode = $allow_flash_bbcode;
 1120          $this->allow_quote_bbcode = $allow_quote_bbcode;
 1121          $this->allow_url_bbcode = $allow_url_bbcode;
 1122   
 1123          // If false, then $this->message won't be altered, the text will be returned instead.
 1124          if (!$update_this_message)
 1125          {
 1126              $tmp_message = $this->message;
 1127              $return_message = &$this->message;
 1128          }
 1129   
 1130          if ($this->message_status == 'display')
 1131          {
 1132              $this->decode_message();
 1133          }
 1134   
 1135          // Do some general 'cleanup' first before processing message,
 1136          // e.g. remove excessive newlines(?), smilies(?)
 1137          $match = array('#(script|about|applet|activex|chrome):#i');
 1138          $replace = array("\\1&#058;");
 1139          $this->message = preg_replace($match, $replace, trim($this->message));
 1140   
 1141          // Store message length...
 1142          $message_length = ($mode == 'post') ? utf8_strlen($this->message) : utf8_strlen(preg_replace('#\[\/?[a-z\*\+\-]+(=[\S]+)?\]#ius', ' ', $this->message));
 1143   
 1144          // Maximum message length check. 0 disables this check completely.
 1145          if ((int) $config['max_' . $mode . '_chars'] > 0 && $message_length > (int) $config['max_' . $mode . '_chars'])
 1146          {
 1147              $this->warn_msg[] = $user->lang('CHARS_' . strtoupper($mode) . '_CONTAINS', $message_length) . '<br />' . $user->lang('TOO_MANY_CHARS_LIMIT', (int) $config['max_' . $mode . '_chars']);
 1148              return (!$update_this_message) ? $return_message : $this->warn_msg;
 1149          }
 1150   
 1151          // Minimum message length check for post only
 1152          if ($mode === 'post')
 1153          {
 1154              if (!$message_length || $message_length < (int) $config['min_post_chars'])
 1155              {
 1156                  $this->warn_msg[] = (!$message_length) ? $user->lang['TOO_FEW_CHARS'] : ($user->lang('CHARS_POST_CONTAINS', $message_length) . '<br />' . $user->lang('TOO_FEW_CHARS_LIMIT', (int) $config['min_post_chars']));
 1157                  return (!$update_this_message) ? $return_message : $this->warn_msg;
 1158              }
 1159          }
 1160   
 1161          // Prepare BBcode (just prepares some tags for better parsing)
 1162          if ($allow_bbcode && strpos($this->message, '[') !== false)
 1163          {
 1164              $this->bbcode_init();
 1165              $disallow = array('img', 'flash', 'quote', 'url');
 1166              foreach ($disallow as $bool)
 1167              {
 1168                  if (!${'allow_' . $bool . '_bbcode'})
 1169                  {
 1170                      $this->bbcodes[$bool]['disabled'] = true;
 1171                  }
 1172              }
 1173   
 1174              $this->prepare_bbcodes();
 1175          }
 1176   
 1177          // Parse smilies
 1178          if ($allow_smilies)
 1179          {
 1180              $this->smilies($config['max_' . $mode . '_smilies']);
 1181          }
 1182   
 1183          $num_urls = 0;
 1184   
 1185          // Parse BBCode
 1186          if ($allow_bbcode && strpos($this->message, '[') !== false)
 1187          {
 1188              $this->parse_bbcode();
 1189              $num_urls += $this->parsed_items['url'];
 1190          }
 1191   
 1192          // Parse URL's
 1193          if ($allow_magic_url)
 1194          {
 1195              $this->magic_url(generate_board_url());
 1196   
 1197              if ($config['max_' . $mode . '_urls'])
 1198              {
 1199                  $num_urls += preg_match_all('#\<!-- ([lmwe]) --\>.*?\<!-- \1 --\>#', $this->message, $matches);
 1200              }
 1201          }
 1202   
 1203          // Check for out-of-bounds characters that are currently
 1204          // not supported by utf8_bin in MySQL
 1205          if (preg_match_all('/[\x{10000}-\x{10FFFF}]/u', $this->message, $matches))
 1206          {
 1207              $character_list = implode('<br />', $matches[0]);
 1208              $this->warn_msg[] = $user->lang('UNSUPPORTED_CHARACTERS_MESSAGE', $character_list);
 1209              return $update_this_message ? $this->warn_msg : $return_message;
 1210          }
 1211   
 1212          // Check for "empty" message. We do not check here for maximum length, because bbcode, smilies, etc. can add to the length.
 1213          // The maximum length check happened before any parsings.
 1214          if ($mode === 'post' && utf8_clean_string($this->message) === '')
 1215          {
 1216              $this->warn_msg[] = $user->lang['TOO_FEW_CHARS'];
 1217              return (!$update_this_message) ? $return_message : $this->warn_msg;
 1218          }
 1219   
 1220          // Check number of links
 1221          if ($config['max_' . $mode . '_urls'] && $num_urls > $config['max_' . $mode . '_urls'])
 1222          {
 1223              $this->warn_msg[] = sprintf($user->lang['TOO_MANY_URLS'], $config['max_' . $mode . '_urls']);
 1224              return (!$update_this_message) ? $return_message : $this->warn_msg;
 1225          }
 1226   
 1227          if (!$update_this_message)
 1228          {
 1229              unset($this->message);
 1230              $this->message = $tmp_message;
 1231              return $return_message;
 1232          }
 1233   
 1234          $this->message_status = 'parsed';
 1235          return false;
 1236      }
 1237   
 1238      /**
 1239      * Formatting text for display
 1240      */
 1241      function format_display($allow_bbcode, $allow_magic_url, $allow_smilies, $update_this_message = true)
 1242      {
 1243          global $phpbb_dispatcher;
 1244   
 1245          // If false, then the parsed message get returned but internal message not processed.
 1246          if (!$update_this_message)
 1247          {
 1248              $tmp_message = $this->message;
 1249              $return_message = &$this->message;
 1250          }
 1251   
 1252          if ($this->message_status == 'plain')
 1253          {
 1254              // Force updating message - of course.
 1255              $this->parse($allow_bbcode, $allow_magic_url, $allow_smilies, $this->allow_img_bbcode, $this->allow_flash_bbcode, $this->allow_quote_bbcode, $this->allow_url_bbcode, true);
 1256          }
 1257   
 1258          // Replace naughty words such as farty pants
 1259          $this->message = censor_text($this->message);
 1260   
 1261          // Parse BBcode
 1262          if ($allow_bbcode)
 1263          {
 1264              $this->bbcode_cache_init();
 1265   
 1266              // We are giving those parameters to be able to use the bbcode class on its own
 1267              $this->bbcode_second_pass($this->message, $this->bbcode_uid);
 1268          }
 1269   
 1270          $this->message = bbcode_nl2br($this->message);
 1271          $this->message = smiley_text($this->message, !$allow_smilies);
 1272   
 1273          $text = $this->message;
 1274          $uid = $this->bbcode_uid;
 1275   
 1276          /**
 1277          * Event to modify the text after it is parsed
 1278          *
 1279          * @event core.modify_format_display_text_after
 1280          * @var string    text                The message text to parse
 1281          * @var string    uid                    The bbcode uid
 1282          * @var bool        allow_bbcode        Do we allow bbcodes
 1283          * @var bool        allow_magic_url        Do we allow magic urls
 1284          * @var bool        allow_smilies        Do we allow smilies
 1285          * @var bool        update_this_message    Do we update the internal message
 1286          *                                    with the parsed result
 1287          * @since 3.1.0-a3
 1288          */
 1289          $vars = array('text', 'uid', 'allow_bbcode', 'allow_magic_url', 'allow_smilies', 'update_this_message');
 1290          extract($phpbb_dispatcher->trigger_event('core.modify_format_display_text_after', compact($vars)));
 1291   
 1292          $this->message = $text;
 1293          $this->bbcode_uid = $uid;
 1294   
 1295          if (!$update_this_message)
 1296          {
 1297              unset($this->message);
 1298              $this->message = $tmp_message;
 1299              return $return_message;
 1300          }
 1301   
 1302          $this->message_status = 'display';
 1303          return false;
 1304      }
 1305   
 1306      /**
 1307      * Decode message to be placed back into form box
 1308      */
 1309      function decode_message($custom_bbcode_uid = '', $update_this_message = true)
 1310      {
 1311          // If false, then the parsed message get returned but internal message not processed.
 1312          if (!$update_this_message)
 1313          {
 1314              $tmp_message = $this->message;
 1315              $return_message = &$this->message;
 1316          }
 1317   
 1318          ($custom_bbcode_uid) ? decode_message($this->message, $custom_bbcode_uid) : decode_message($this->message, $this->bbcode_uid);
 1319   
 1320          if (!$update_this_message)
 1321          {
 1322              unset($this->message);
 1323              $this->message = $tmp_message;
 1324              return $return_message;
 1325          }
 1326   
 1327          $this->message_status = 'plain';
 1328          return false;
 1329      }
 1330   
 1331      /**
 1332      * Replace magic urls of form http://xxx.xxx., www.xxx. and xxx@xxx.xxx.
 1333      * Cuts down displayed size of link if over 50 chars, turns absolute links
 1334      * into relative versions when the server/script path matches the link
 1335      */
 1336      function magic_url($server_url)
 1337      {
 1338          // We use the global make_clickable function
 1339          $this->message = make_clickable($this->message, $server_url);
 1340      }
 1341   
 1342      /**
 1343      * Parse Smilies
 1344      */
 1345      function smilies($max_smilies = 0)
 1346      {
 1347          global $db, $user;
 1348          static $match;
 1349          static $replace;
 1350   
 1351          // See if the static arrays have already been filled on an earlier invocation
 1352          if (!is_array($match))
 1353          {
 1354              $match = $replace = array();
 1355   
 1356              // NOTE: obtain_* function? chaching the table contents?
 1357   
 1358              // For now setting the ttl to 10 minutes
 1359              switch ($db->get_sql_layer())
 1360              {
 1361                  case 'mssql':
 1362                  case 'mssql_odbc':
 1363                  case 'mssqlnative':
 1364                      $sql = 'SELECT *
 1365                          FROM ' . SMILIES_TABLE . '
 1366                          ORDER BY LEN(code) DESC';
 1367                  break;
 1368   
 1369                  // LENGTH supported by MySQL, IBM DB2, Oracle and Access for sure...
 1370                  default:
 1371                      $sql = 'SELECT *
 1372                          FROM ' . SMILIES_TABLE . '
 1373                          ORDER BY LENGTH(code) DESC';
 1374                  break;
 1375              }
 1376              $result = $db->sql_query($sql, 600);
 1377   
 1378              while ($row = $db->sql_fetchrow($result))
 1379              {
 1380                  if (empty($row['code']))
 1381                  {
 1382                      continue;
 1383                  }
 1384   
 1385                  // (assertion)
 1386                  $match[] = preg_quote($row['code'], '#');
 1387                  $replace[] = '<!-- s' . $row['code'] . ' --><img src="{SMILIES_PATH}/' . $row['smiley_url'] . '" alt="' . $row['code'] . '" title="' . $row['emotion'] . '" /><!-- s' . $row['code'] . ' -->';
 1388              }
 1389              $db->sql_freeresult($result);
 1390          }
 1391   
 1392          if (sizeof($match))
 1393          {
 1394              if ($max_smilies)
 1395              {
 1396                  // 'u' modifier has been added to correctly parse smilies within unicode strings
 1397                  // For details: http://tracker.phpbb.com/browse/PHPBB3-10117
 1398                  $num_matches = preg_match_all('#(?<=^|[\n .])(?:' . implode('|', $match) . ')(?![^<>]*>)#u', $this->message, $matches);
 1399                  unset($matches);
 1400   
 1401                  if ($num_matches !== false && $num_matches > $max_smilies)
 1402                  {
 1403                      $this->warn_msg[] = sprintf($user->lang['TOO_MANY_SMILIES'], $max_smilies);
 1404                      return;
 1405                  }
 1406              }
 1407   
 1408              // Make sure the delimiter # is added in front and at the end of every element within $match
 1409              // 'u' modifier has been added to correctly parse smilies within unicode strings
 1410              // For details: http://tracker.phpbb.com/browse/PHPBB3-10117
 1411   
 1412              $this->message = trim(preg_replace(explode(chr(0), '#(?<=^|[\n .])' . implode('(?![^<>]*>)#u' . chr(0) . '#(?<=^|[\n .])', $match) . '(?![^<>]*>)#u'), $replace, $this->message));
 1413          }
 1414      }
 1415   
 1416      /**
 1417      * Parse Attachments
 1418      */
 1419      function parse_attachments($form_name, $mode, $forum_id, $submit, $preview, $refresh, $is_message = false)
 1420      {
 1421          global $config, $auth, $user, $phpbb_root_path, $phpEx, $db, $request;
 1422   
 1423          $error = array();
 1424   
 1425          $num_attachments = sizeof($this->attachment_data);
 1426          $this->filename_data['filecomment'] = utf8_normalize_nfc(request_var('filecomment', '', true));
 1427          $upload = $request->file($form_name);
 1428          $upload_file = (!empty($upload) && $upload['name'] !== 'none' && trim($upload['name']));
 1429   
 1430          $add_file        = (isset($_POST['add_file'])) ? true : false;
 1431          $delete_file    = (isset($_POST['delete_file'])) ? true : false;
 1432   
 1433          // First of all adjust comments if changed
 1434          $actual_comment_list = utf8_normalize_nfc(request_var('comment_list', array(''), true));
 1435   
 1436          foreach ($actual_comment_list as $comment_key => $comment)
 1437          {
 1438              if (!isset($this->attachment_data[$comment_key]))
 1439              {
 1440                  continue;
 1441              }
 1442   
 1443              if ($this->attachment_data[$comment_key]['attach_comment'] != $actual_comment_list[$comment_key])
 1444              {
 1445                  $this->attachment_data[$comment_key]['attach_comment'] = $actual_comment_list[$comment_key];
 1446              }
 1447          }
 1448   
 1449          $cfg = array();
 1450          $cfg['max_attachments'] = ($is_message) ? $config['max_attachments_pm'] : $config['max_attachments'];
 1451          $forum_id = ($is_message) ? 0 : $forum_id;
 1452   
 1453          if ($submit && in_array($mode, array('post', 'reply', 'quote', 'edit')) && $upload_file)
 1454          {
 1455              if ($num_attachments < $cfg['max_attachments'] || $auth->acl_get('a_') || $auth->acl_get('m_', $forum_id))
 1456              {
 1457                  $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message);
 1458                  $error = $filedata['error'];
 1459   
 1460                  if ($filedata['post_attach'] && !sizeof($error))
 1461                  {
 1462                      $sql_ary = array(
 1463                          'physical_filename'    => $filedata['physical_filename'],
 1464                          'attach_comment'    => $this->filename_data['filecomment'],
 1465                          'real_filename'        => $filedata['real_filename'],
 1466                          'extension'            => $filedata['extension'],
 1467                          'mimetype'            => $filedata['mimetype'],
 1468                          'filesize'            => $filedata['filesize'],
 1469                          'filetime'            => $filedata['filetime'],
 1470                          'thumbnail'            => $filedata['thumbnail'],
 1471                          'is_orphan'            => 1,
 1472                          'in_message'        => ($is_message) ? 1 : 0,
 1473                          'poster_id'            => $user->data['user_id'],
 1474                      );
 1475   
 1476                      $db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
 1477   
 1478                      $new_entry = array(
 1479                          'attach_id'        => $db->sql_nextid(),
 1480                          'is_orphan'        => 1,
 1481                          'real_filename'    => $filedata['real_filename'],
 1482                          'attach_comment'=> $this->filename_data['filecomment'],
 1483                          'filesize'        => $filedata['filesize'],
 1484                      );
 1485   
 1486                      $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data);
 1487                      $this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message);
 1488   
 1489                      $this->filename_data['filecomment'] = '';
 1490   
 1491                      // This Variable is set to false here, because Attachments are entered into the
 1492                      // Database in two modes, one if the id_list is 0 and the second one if post_attach is true
 1493                      // Since post_attach is automatically switched to true if an Attachment got added to the filesystem,
 1494                      // but we are assigning an id of 0 here, we have to reset the post_attach variable to false.
 1495                      //
 1496                      // This is very relevant, because it could happen that the post got not submitted, but we do not
 1497                      // know this circumstance here. We could be at the posting page or we could be redirected to the entered
 1498                      // post. :)
 1499                      $filedata['post_attach'] = false;
 1500                  }
 1501              }
 1502              else
 1503              {
 1504                  $error[] = $user->lang('TOO_MANY_ATTACHMENTS', (int) $cfg['max_attachments']);
 1505              }
 1506          }
 1507   
 1508          if ($preview || $refresh || sizeof($error))
 1509          {
 1510              if (isset($this->plupload) && $this->plupload->is_active())
 1511              {
 1512                  $json_response = new \phpbb\json_response();
 1513              }
 1514   
 1515              // Perform actions on temporary attachments
 1516              if ($delete_file)
 1517              {
 1518                  include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
 1519   
 1520                  $index = array_keys(request_var('delete_file', array(0 => 0)));
 1521                  $index = (!empty($index)) ? $index[0] : false;
 1522   
 1523                  if ($index !== false && !empty($this->attachment_data[$index]))
 1524                  {
 1525                      // delete selected attachment
 1526                      if ($this->attachment_data[$index]['is_orphan'])
 1527                      {
 1528                          $sql = 'SELECT attach_id, physical_filename, thumbnail
 1529                              FROM ' . ATTACHMENTS_TABLE . '
 1530                              WHERE attach_id = ' . (int) $this->attachment_data[$index]['attach_id'] . '
 1531                                  AND is_orphan = 1
 1532                                  AND poster_id = ' . $user->data['user_id'];
 1533                          $result = $db->sql_query($sql);
 1534                          $row = $db->sql_fetchrow($result);
 1535                          $db->sql_freeresult($result);
 1536   
 1537                          if ($row)
 1538                          {
 1539                              phpbb_unlink($row['physical_filename'], 'file');
 1540   
 1541                              if ($row['thumbnail'])
 1542                              {
 1543                                  phpbb_unlink($row['physical_filename'], 'thumbnail');
 1544                              }
 1545   
 1546                              $db->sql_query('DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE attach_id = ' . (int) $this->attachment_data[$index]['attach_id']);
 1547                          }
 1548                      }
 1549                      else
 1550                      {
 1551                          delete_attachments('attach', array(intval($this->attachment_data[$index]['attach_id'])));
 1552                      }
 1553   
 1554                      unset($this->attachment_data[$index]);
 1555                      $this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "(\\1 == \$index) ? '' : ((\\1 > \$index) ? '[attachment=' . (\\1 - 1) . ']\\2[/attachment]' : '\\0')", $this->message);
 1556   
 1557                      // Reindex Array
 1558                      $this->attachment_data = array_values($this->attachment_data);
 1559                      if (isset($this->plupload) && $this->plupload->is_active())
 1560                      {
 1561                          $json_response->send($this->attachment_data);
 1562                      }
 1563                  }
 1564              }
 1565              else if (($add_file || $preview) && $upload_file)
 1566              {
 1567                  if ($num_attachments < $cfg['max_attachments'] || $auth->acl_gets('m_', 'a_', $forum_id))
 1568                  {
 1569                      $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message, false, $this->mimetype_guesser, $this->plupload);
 1570                      $error = array_merge($error, $filedata['error']);
 1571   
 1572                      if (!sizeof($error))
 1573                      {
 1574                          $sql_ary = array(
 1575                              'physical_filename'    => $filedata['physical_filename'],
 1576                              'attach_comment'    => $this->filename_data['filecomment'],
 1577                              'real_filename'        => $filedata['real_filename'],
 1578                              'extension'            => $filedata['extension'],
 1579                              'mimetype'            => $filedata['mimetype'],
 1580                              'filesize'            => $filedata['filesize'],
 1581                              'filetime'            => $filedata['filetime'],
 1582                              'thumbnail'            => $filedata['thumbnail'],
 1583                              'is_orphan'            => 1,
 1584                              'in_message'        => ($is_message) ? 1 : 0,
 1585                              'poster_id'            => $user->data['user_id'],
 1586                          );
 1587   
 1588                          $db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
 1589   
 1590                          $new_entry = array(
 1591                              'attach_id'        => $db->sql_nextid(),
 1592                              'is_orphan'        => 1,
 1593                              'real_filename'    => $filedata['real_filename'],
 1594                              'attach_comment'=> $this->filename_data['filecomment'],
 1595                              'filesize'        => $filedata['filesize'],
 1596                          );
 1597   
 1598                          $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data);
 1599                          $this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message);
 1600                          $this->filename_data['filecomment'] = '';
 1601   
 1602                          if (isset($this->plupload) && $this->plupload->is_active())
 1603                          {
 1604                              $download_url = append_sid("{$phpbb_root_path}download/file.{$phpEx}", 'mode=view&amp;id=' . $new_entry['attach_id']);
 1605   
 1606                              // Send the client the attachment data to maintain state
 1607                              $json_response->send(array('data' => $this->attachment_data, 'download_url' => $download_url));
 1608                          }
 1609                      }
 1610                  }
 1611                  else
 1612                  {
 1613                      $error[] = $user->lang('TOO_MANY_ATTACHMENTS', (int) $cfg['max_attachments']);
 1614                  }
 1615   
 1616                  if (!empty($error) && isset($this->plupload) && $this->plupload->is_active())
 1617                  {
 1618                      // If this is a plupload (and thus ajax) request, give the
 1619                      // client the first error we have
 1620                      $json_response->send(array(
 1621                          'jsonrpc' => '2.0',
 1622                          'id' => 'id',
 1623                          'error' => array(
 1624                              'code' => 105,
 1625                              'message' => current($error),
 1626                          ),
 1627                      ));
 1628                  }
 1629              }
 1630          }
 1631   
 1632          foreach ($error as $error_msg)
 1633          {
 1634              $this->warn_msg[] = $error_msg;
 1635          }
 1636      }
 1637   
 1638      /**
 1639      * Get Attachment Data
 1640      */
 1641      function get_submitted_attachment_data($check_user_id = false)
 1642      {
 1643          global $user, $db, $phpbb_root_path, $phpEx, $config;
 1644          global $request;
 1645   
 1646          $this->filename_data['filecomment'] = utf8_normalize_nfc(request_var('filecomment', '', true));
 1647          $attachment_data = $request->variable('attachment_data', array(0 => array('' => '')), true, \phpbb\request\request_interface::POST);
 1648          $this->attachment_data = array();
 1649   
 1650          $check_user_id = ($check_user_id === false) ? $user->data['user_id'] : $check_user_id;
 1651   
 1652          if (!sizeof($attachment_data))
 1653          {
 1654              return;
 1655          }
 1656   
 1657          $not_orphan = $orphan = array();
 1658   
 1659          foreach ($attachment_data as $pos => $var_ary)
 1660          {
 1661              if ($var_ary['is_orphan'])
 1662              {
 1663                  $orphan[(int) $var_ary['attach_id']] = $pos;
 1664              }
 1665              else
 1666              {
 1667                  $not_orphan[(int) $var_ary['attach_id']] = $pos;
 1668              }
 1669          }
 1670   
 1671          // Regenerate already posted attachments
 1672          if (sizeof($not_orphan))
 1673          {
 1674              // Get the attachment data, based on the poster id...
 1675              $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment, filesize
 1676                  FROM ' . ATTACHMENTS_TABLE . '
 1677                  WHERE ' . $db->sql_in_set('attach_id', array_keys($not_orphan)) . '
 1678                      AND poster_id = ' . $check_user_id;
 1679              $result = $db->sql_query($sql);
 1680   
 1681              while ($row = $db->sql_fetchrow($result))
 1682              {
 1683                  $pos = $not_orphan[$row['attach_id']];
 1684                  $this->attachment_data[$pos] = $row;
 1685                  $this->attachment_data[$pos]['attach_comment'] = $attachment_data[$pos]['attach_comment'];
 1686   
 1687                  unset($not_orphan[$row['attach_id']]);
 1688              }
 1689              $db->sql_freeresult($result);
 1690          }
 1691   
 1692          if (sizeof($not_orphan))
 1693          {
 1694              trigger_error('NO_ACCESS_ATTACHMENT', E_USER_ERROR);
 1695          }
 1696   
 1697          // Regenerate newly uploaded attachments
 1698          if (sizeof($orphan))
 1699          {
 1700              $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment, filesize
 1701                  FROM ' . ATTACHMENTS_TABLE . '
 1702                  WHERE ' . $db->sql_in_set('attach_id', array_keys($orphan)) . '
 1703                      AND poster_id = ' . $user->data['user_id'] . '
 1704                      AND is_orphan = 1';
 1705              $result = $db->sql_query($sql);
 1706   
 1707              while ($row = $db->sql_fetchrow($result))
 1708              {
 1709                  $pos = $orphan[$row['attach_id']];
 1710                  $this->attachment_data[$pos] = $row;
 1711                  $this->attachment_data[$pos]['attach_comment'] = $attachment_data[$pos]['attach_comment'];
 1712   
 1713                  unset($orphan[$row['attach_id']]);
 1714              }
 1715              $db->sql_freeresult($result);
 1716          }
 1717   
 1718          if (sizeof($orphan))
 1719          {
 1720              trigger_error('NO_ACCESS_ATTACHMENT', E_USER_ERROR);
 1721          }
 1722   
 1723          ksort($this->attachment_data);
 1724      }
 1725   
 1726      /**
 1727      * Parse Poll
 1728      */
 1729      function parse_poll(&$poll)
 1730      {
 1731          global $auth, $user, $config;
 1732   
 1733          $poll_max_options = $poll['poll_max_options'];
 1734   
 1735          // Parse Poll Option text ;)
 1736          $tmp_message = $this->message;
 1737          $this->message = $poll['poll_option_text'];
 1738          $bbcode_bitfield = $this->bbcode_bitfield;
 1739   
 1740          $poll['poll_option_text'] = $this->parse($poll['enable_bbcode'], ($config['allow_post_links']) ? $poll['enable_urls'] : false, $poll['enable_smilies'], $poll['img_status'], false, false, $config['allow_post_links'], false, 'poll');
 1741   
 1742          $bbcode_bitfield = base64_encode(base64_decode($bbcode_bitfield) | base64_decode($this->bbcode_bitfield));
 1743          $this->message = $tmp_message;
 1744   
 1745          // Parse Poll Title
 1746          $tmp_message = $this->message;
 1747          $this->message = $poll['poll_title'];
 1748          $this->bbcode_bitfield = $bbcode_bitfield;
 1749   
 1750          $poll['poll_options'] = explode("\n", trim($poll['poll_option_text']));
 1751          $poll['poll_options_size'] = sizeof($poll['poll_options']);
 1752   
 1753          if (!$poll['poll_title'] && $poll['poll_options_size'])
 1754          {
 1755              $this->warn_msg[] = $user->lang['NO_POLL_TITLE'];
 1756          }
 1757          else
 1758          {
 1759              if (utf8_strlen(preg_replace('#\[\/?[a-z\*\+\-]+(=[\S]+)?\]#ius', ' ', $this->message)) > 100)
 1760              {
 1761                  $this->warn_msg[] = $user->lang['POLL_TITLE_TOO_LONG'];
 1762              }
 1763              $poll['poll_title'] = $this->parse($poll['enable_bbcode'], ($config['allow_post_links']) ? $poll['enable_urls'] : false, $poll['enable_smilies'], $poll['img_status'], false, false, $config['allow_post_links'], false, 'poll');
 1764              if (strlen($poll['poll_title']) > 255)
 1765              {
 1766                  $this->warn_msg[] = $user->lang['POLL_TITLE_COMP_TOO_LONG'];
 1767              }
 1768          }
 1769   
 1770          $this->bbcode_bitfield = base64_encode(base64_decode($bbcode_bitfield) | base64_decode($this->bbcode_bitfield));
 1771          $this->message = $tmp_message;
 1772          unset($tmp_message);
 1773   
 1774          if (sizeof($poll['poll_options']) == 1)
 1775          {
 1776              $this->warn_msg[] = $user->lang['TOO_FEW_POLL_OPTIONS'];
 1777          }
 1778          else if ($poll['poll_options_size'] > (int) $config['max_poll_options'])
 1779          {
 1780              $this->warn_msg[] = $user->lang['TOO_MANY_POLL_OPTIONS'];
 1781          }
 1782          else if ($poll_max_options > $poll['poll_options_size'])
 1783          {
 1784              $this->warn_msg[] = $user->lang['TOO_MANY_USER_OPTIONS'];
 1785          }
 1786   
 1787          $poll['poll_max_options'] = ($poll['poll_max_options'] < 1) ? 1 : (($poll['poll_max_options'] > $config['max_poll_options']) ? $config['max_poll_options'] : $poll['poll_max_options']);
 1788      }
 1789   
 1790      /**
 1791      * Setter function for passing the plupload object
 1792      *
 1793      * @param \phpbb\plupload\plupload $plupload The plupload object
 1794      *
 1795      * @return null
 1796      */
 1797      public function set_plupload(\phpbb\plupload\plupload $plupload)
 1798      {
 1799          $this->plupload = $plupload;
 1800      }
 1801   
 1802      /**
 1803      * Setter function for passing the mimetype_guesser object
 1804      *
 1805      * @param \phpbb\mimetype\guesser $mimetype_guesser The mimetype_guesser object
 1806      *
 1807      * @return null
 1808      */
 1809      public function set_mimetype_guesser(\phpbb\mimetype\guesser $mimetype_guesser)
 1810      {
 1811          $this->mimetype_guesser = $mimetype_guesser;
 1812      }
 1813  }
 1814