Verzeichnisstruktur phpBB-3.0.0


Veröffentlicht
12.12.2007

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

functions_content.php

Zuletzt modifiziert: 09.10.2024, 12:50 - Dateigröße: 34.31 KiB


 0001  <?php
 0002  /**
 0003  *
 0004  * @package phpBB3
 0005  * @version $Id$
 0006  * @copyright (c) 2005 phpBB Group
 0007  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 0008  *
 0009  */
 0010   
 0011  /**
 0012  * @ignore
 0013  */
 0014  if (!defined('IN_PHPBB'))
 0015  {
 0016      exit;
 0017  }
 0018   
 0019  /**
 0020  * gen_sort_selects()
 0021  * make_jumpbox()
 0022  * bump_topic_allowed()
 0023  * get_context()
 0024  * decode_message()
 0025  * strip_bbcode()
 0026  * generate_text_for_display()
 0027  * generate_text_for_storage()
 0028  * generate_text_for_edit()
 0029  * make_clickable_callback()
 0030  * make_clickable()
 0031  * censor_text()
 0032  * bbcode_nl2br()
 0033  * smiley_text()
 0034  * parse_attachments()
 0035  * extension_allowed()
 0036  * truncate_string()
 0037  * get_username_string()
 0038  * class bitfield
 0039  */
 0040   
 0041  /**
 0042  * Generate sort selection fields
 0043  */
 0044  function gen_sort_selects(&$limit_days, &$sort_by_text, &$sort_days, &$sort_key, &$sort_dir, &$s_limit_days, &$s_sort_key, &$s_sort_dir, &$u_sort_param)
 0045  {
 0046      global $user;
 0047   
 0048      $sort_dir_text = array('a' => $user->lang['ASCENDING'], 'd' => $user->lang['DESCENDING']);
 0049   
 0050      // Check if the key is selectable. If not, we reset to the first key found.
 0051      // This ensures the values are always valid.
 0052      if (!isset($limit_days[$sort_days]))
 0053      {
 0054          @reset($limit_days);
 0055          $sort_days = key($limit_days);
 0056      }
 0057   
 0058      if (!isset($sort_by_text[$sort_key]))
 0059      {
 0060          @reset($sort_by_text);
 0061          $sort_key = key($sort_by_text);
 0062      }
 0063   
 0064      if (!isset($sort_dir_text[$sort_dir]))
 0065      {
 0066          @reset($sort_dir_text);
 0067          $sort_dir = key($sort_dir_text);
 0068      }
 0069   
 0070      $s_limit_days = '<select name="st">';
 0071      foreach ($limit_days as $day => $text)
 0072      {
 0073          $selected = ($sort_days == $day) ? ' selected="selected"' : '';
 0074          $s_limit_days .= '<option value="' . $day . '"' . $selected . '>' . $text . '</option>';
 0075      }
 0076      $s_limit_days .= '</select>';
 0077   
 0078      $s_sort_key = '<select name="sk">';
 0079      foreach ($sort_by_text as $key => $text)
 0080      {
 0081          $selected = ($sort_key == $key) ? ' selected="selected"' : '';
 0082          $s_sort_key .= '<option value="' . $key . '"' . $selected . '>' . $text . '</option>';
 0083      }
 0084      $s_sort_key .= '</select>';
 0085   
 0086      $s_sort_dir = '<select name="sd">';
 0087      foreach ($sort_dir_text as $key => $value)
 0088      {
 0089          $selected = ($sort_dir == $key) ? ' selected="selected"' : '';
 0090          $s_sort_dir .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>';
 0091      }
 0092      $s_sort_dir .= '</select>';
 0093   
 0094      $u_sort_param = "st=$sort_days&amp;sk=$sort_key&amp;sd=$sort_dir";
 0095   
 0096      return;
 0097  }
 0098   
 0099  /**
 0100  * Generate Jumpbox
 0101  */
 0102  function make_jumpbox($action, $forum_id = false, $select_all = false, $acl_list = false, $force_display = false)
 0103  {
 0104      global $config, $auth, $template, $user, $db;
 0105   
 0106      // We only return if the jumpbox is not forced to be displayed (in case it is needed for functionality)
 0107      if (!$config['load_jumpbox'] && $force_display === false)
 0108      {
 0109          return;
 0110      }
 0111   
 0112      $sql = 'SELECT forum_id, forum_name, parent_id, forum_type, left_id, right_id
 0113          FROM ' . FORUMS_TABLE . '
 0114          ORDER BY left_id ASC';
 0115      $result = $db->sql_query($sql, 600);
 0116   
 0117      $right = $padding = 0;
 0118      $padding_store = array('0' => 0);
 0119      $display_jumpbox = false;
 0120      $iteration = 0;
 0121   
 0122      // Sometimes it could happen that forums will be displayed here not be displayed within the index page
 0123      // This is the result of forums not displayed at index, having list permissions and a parent of a forum with no permissions.
 0124      // If this happens, the padding could be "broken"
 0125   
 0126      while ($row = $db->sql_fetchrow($result))
 0127      {
 0128          if ($row['left_id'] < $right)
 0129          {
 0130              $padding++;
 0131              $padding_store[$row['parent_id']] = $padding;
 0132          }
 0133          else if ($row['left_id'] > $right + 1)
 0134          {
 0135              // Ok, if the $padding_store for this parent is empty there is something wrong. For now we will skip over it.
 0136              // @todo digging deep to find out "how" this can happen.
 0137              $padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : $padding;
 0138          }
 0139   
 0140          $right = $row['right_id'];
 0141   
 0142          if ($row['forum_type'] == FORUM_CAT && ($row['left_id'] + 1 == $row['right_id']))
 0143          {
 0144              // Non-postable forum with no subforums, don't display
 0145              continue;
 0146          }
 0147   
 0148          if (!$auth->acl_get('f_list', $row['forum_id']))
 0149          {
 0150              // if the user does not have permissions to list this forum skip
 0151              continue;
 0152          }
 0153   
 0154          if ($acl_list && !$auth->acl_gets($acl_list, $row['forum_id']))
 0155          {
 0156              continue;
 0157          }
 0158   
 0159          if (!$display_jumpbox)
 0160          {
 0161              $template->assign_block_vars('jumpbox_forums', array(
 0162                  'FORUM_ID'        => ($select_all) ? 0 : -1,
 0163                  'FORUM_NAME'    => ($select_all) ? $user->lang['ALL_FORUMS'] : $user->lang['SELECT_FORUM'],
 0164                  'S_FORUM_COUNT'    => $iteration)
 0165              );
 0166   
 0167              $iteration++;
 0168              $display_jumpbox = true;
 0169          }
 0170   
 0171          $template->assign_block_vars('jumpbox_forums', array(
 0172              'FORUM_ID'        => $row['forum_id'],
 0173              'FORUM_NAME'    => $row['forum_name'],
 0174              'SELECTED'        => ($row['forum_id'] == $forum_id) ? ' selected="selected"' : '',
 0175              'S_FORUM_COUNT'    => $iteration,
 0176              'S_IS_CAT'        => ($row['forum_type'] == FORUM_CAT) ? true : false,
 0177              'S_IS_LINK'        => ($row['forum_type'] == FORUM_LINK) ? true : false,
 0178              'S_IS_POST'        => ($row['forum_type'] == FORUM_POST) ? true : false)
 0179          );
 0180   
 0181          for ($i = 0; $i < $padding; $i++)
 0182          {
 0183              $template->assign_block_vars('jumpbox_forums.level', array());
 0184          }
 0185          $iteration++;
 0186      }
 0187      $db->sql_freeresult($result);
 0188      unset($padding_store);
 0189   
 0190      $template->assign_vars(array(
 0191          'S_DISPLAY_JUMPBOX'    => $display_jumpbox,
 0192          'S_JUMPBOX_ACTION'    => $action)
 0193      );
 0194   
 0195      return;
 0196  }
 0197   
 0198  /**
 0199  * Bump Topic Check - used by posting and viewtopic
 0200  */
 0201  function bump_topic_allowed($forum_id, $topic_bumped, $last_post_time, $topic_poster, $last_topic_poster)
 0202  {
 0203      global $config, $auth, $user;
 0204   
 0205      // Check permission and make sure the last post was not already bumped
 0206      if (!$auth->acl_get('f_bump', $forum_id) || $topic_bumped)
 0207      {
 0208          return false;
 0209      }
 0210   
 0211      // Check bump time range, is the user really allowed to bump the topic at this time?
 0212      $bump_time = ($config['bump_type'] == 'm') ? $config['bump_interval'] * 60 : (($config['bump_type'] == 'h') ? $config['bump_interval'] * 3600 : $config['bump_interval'] * 86400);
 0213   
 0214      // Check bump time
 0215      if ($last_post_time + $bump_time > time())
 0216      {
 0217          return false;
 0218      }
 0219   
 0220      // Check bumper, only topic poster and last poster are allowed to bump
 0221      if ($topic_poster != $user->data['user_id'] && $last_topic_poster != $user->data['user_id'])
 0222      {
 0223          return false;
 0224      }
 0225   
 0226      // A bump time of 0 will completely disable the bump feature... not intended but might be useful.
 0227      return $bump_time;
 0228  }
 0229   
 0230  /**
 0231  * Generates a text with approx. the specified length which contains the specified words and their context
 0232  *
 0233  * @param    string    $text    The full text from which context shall be extracted
 0234  * @param    string    $words    An array of words which should be contained in the result, has to be a valid part of a PCRE pattern (escape with preg_quote!)
 0235  * @param    int        $length    The desired length of the resulting text, however the result might be shorter or longer than this value
 0236  *
 0237  * @return    string            Context of the specified words separated by "..."
 0238  */
 0239  function get_context($text, $words, $length = 400)
 0240  {
 0241      // first replace all whitespaces with single spaces
 0242      $text = preg_replace('/ +/', ' ', strtr($text, "\t\n\r\x0C ", '     '), $text);
 0243   
 0244      $word_indizes = array();
 0245      if (sizeof($words))
 0246      {
 0247          $match = '';
 0248          // find the starting indizes of all words
 0249          foreach ($words as $word)
 0250          {
 0251              if ($word)
 0252              {
 0253                  if (preg_match('#(?:[^\w]|^)(' . $word . ')(?:[^\w]|$)#i', $text, $match))
 0254                  {
 0255                      $pos = utf8_strpos($text, $match[1]);
 0256                      if ($pos !== false)
 0257                      {
 0258                          $word_indizes[] = $pos;
 0259                      }
 0260                  }
 0261              }
 0262          }
 0263          unset($match);
 0264   
 0265          if (sizeof($word_indizes))
 0266          {
 0267              $word_indizes = array_unique($word_indizes);
 0268              sort($word_indizes);
 0269   
 0270              $wordnum = sizeof($word_indizes);
 0271              // number of characters on the right and left side of each word
 0272              $sequence_length = (int) ($length / (2 * $wordnum)) - 2;
 0273              $final_text = '';
 0274              $word = $j = 0;
 0275              $final_text_index = -1;
 0276   
 0277              // cycle through every character in the original text
 0278              for ($i = $word_indizes[$word], $n = utf8_strlen($text); $i < $n; $i++)
 0279              {
 0280                  // if the current position is the start of one of the words then append $sequence_length characters to the final text
 0281                  if (isset($word_indizes[$word]) && ($i == $word_indizes[$word]))
 0282                  {
 0283                      if ($final_text_index < $i - $sequence_length - 1)
 0284                      {
 0285                          $final_text .= '... ' . preg_replace('#^([^ ]*)#', '', utf8_substr($text, $i - $sequence_length, $sequence_length));
 0286                      }
 0287                      else
 0288                      {
 0289                          // if the final text is already nearer to the current word than $sequence_length we only append the text
 0290                          // from its current index on and distribute the unused length to all other sequenes
 0291                          $sequence_length += (int) (($final_text_index - $i + $sequence_length + 1) / (2 * $wordnum));
 0292                          $final_text .= utf8_substr($text, $final_text_index + 1, $i - $final_text_index - 1);
 0293                      }
 0294                      $final_text_index = $i - 1;
 0295   
 0296                      // add the following characters to the final text (see below)
 0297                      $word++;
 0298                      $j = 1;
 0299                  }
 0300   
 0301                  if ($j > 0)
 0302                  {
 0303                      // add the character to the final text and increment the sequence counter
 0304                      $final_text .= utf8_substr($text, $i, 1);
 0305                      $final_text_index++;
 0306                      $j++;
 0307   
 0308                      // if this is a whitespace then check whether we are done with this sequence
 0309                      if (utf8_substr($text, $i, 1) == ' ')
 0310                      {
 0311                          // only check whether we have to exit the context generation completely if we haven't already reached the end anyway
 0312                          if ($i + 4 < $n)
 0313                          {
 0314                              if (($j > $sequence_length && $word >= $wordnum) || utf8_strlen($final_text) > $length)
 0315                              {
 0316                                  $final_text .= ' ...';
 0317                                  break;
 0318                              }
 0319                          }
 0320                          else
 0321                          {
 0322                              // make sure the text really reaches the end
 0323                              $j -= 4;
 0324                          }
 0325   
 0326                          // stop context generation and wait for the next word
 0327                          if ($j > $sequence_length)
 0328                          {
 0329                              $j = 0;
 0330                          }
 0331                      }
 0332                  }
 0333              }
 0334              return $final_text;
 0335          }
 0336      }
 0337   
 0338      if (!sizeof($words) || !sizeof($word_indizes))
 0339      {
 0340          return (utf8_strlen($text) >= $length + 3) ? utf8_substr($text, 0, $length) . '...' : $text;
 0341      }
 0342  }
 0343   
 0344  /**
 0345  * Decode text whereby text is coming from the db and expected to be pre-parsed content
 0346  * We are placing this outside of the message parser because we are often in need of it...
 0347  */
 0348  function decode_message(&$message, $bbcode_uid = '')
 0349  {
 0350      global $config;
 0351   
 0352      if ($bbcode_uid)
 0353      {
 0354          $match = array('<br />', "[/*:m:$bbcode_uid]", ":u:$bbcode_uid", ":o:$bbcode_uid", ":$bbcode_uid");
 0355          $replace = array("\n", '', '', '', '');
 0356      }
 0357      else
 0358      {
 0359          $match = array('<br />');
 0360          $replace = array("\n");
 0361      }
 0362   
 0363      $message = str_replace($match, $replace, $message);
 0364   
 0365      $match = get_preg_expression('bbcode_htm');
 0366      $replace = array('\1', '\1', '\2', '\1', '', '');
 0367   
 0368      $message = preg_replace($match, $replace, $message);
 0369  }
 0370   
 0371  /**
 0372  * Strips all bbcode from a text and returns the plain content
 0373  */
 0374  function strip_bbcode(&$text, $uid = '')
 0375  {
 0376      if (!$uid)
 0377      {
 0378          $uid = '[0-9a-z]{5,}';
 0379      }
 0380   
 0381      $text = preg_replace("#\[\/?[a-z0-9\*\+\-]+(?:=(?:&quot;.*&quot;|[^\]]*))?(?::[a-z])?(\:$uid)\]#", ' ', $text);
 0382   
 0383      $match = get_preg_expression('bbcode_htm');
 0384      $replace = array('\1', '\1', '\2', '\1', '', '');
 0385      
 0386      $text = preg_replace($match, $replace, $text);
 0387  }
 0388   
 0389  /**
 0390  * For display of custom parsed text on user-facing pages
 0391  * Expects $text to be the value directly from the database (stored value)
 0392  */
 0393  function generate_text_for_display($text, $uid, $bitfield, $flags)
 0394  {
 0395      static $bbcode;
 0396   
 0397      if (!$text)
 0398      {
 0399          return '';
 0400      }
 0401   
 0402      $text = censor_text($text);
 0403   
 0404      // Parse bbcode if bbcode uid stored and bbcode enabled
 0405      if ($uid && ($flags & OPTION_FLAG_BBCODE))
 0406      {
 0407          if (!class_exists('bbcode'))
 0408          {
 0409              global $phpbb_root_path, $phpEx;
 0410              include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
 0411          }
 0412   
 0413          if (empty($bbcode))
 0414          {
 0415              $bbcode = new bbcode($bitfield);
 0416          }
 0417          else
 0418          {
 0419              $bbcode->bbcode($bitfield);
 0420          }
 0421          
 0422          $bbcode->bbcode_second_pass($text, $uid);
 0423      }
 0424   
 0425      $text = bbcode_nl2br($text);
 0426      $text = smiley_text($text, !($flags & OPTION_FLAG_SMILIES));
 0427   
 0428      return $text;
 0429  }
 0430   
 0431  /**
 0432  * For parsing custom parsed text to be stored within the database.
 0433  * This function additionally returns the uid and bitfield that needs to be stored.
 0434  * Expects $text to be the value directly from request_var() and in it's non-parsed form
 0435  */
 0436  function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bbcode = false, $allow_urls = false, $allow_smilies = false)
 0437  {
 0438      global $phpbb_root_path, $phpEx;
 0439   
 0440      $uid = $bitfield = '';
 0441   
 0442      if (!$text)
 0443      {
 0444          return;
 0445      }
 0446   
 0447      if (!class_exists('parse_message'))
 0448      {
 0449          include($phpbb_root_path . 'includes/message_parser.' . $phpEx);
 0450      }
 0451   
 0452      $message_parser = new parse_message($text);
 0453      $message_parser->parse($allow_bbcode, $allow_urls, $allow_smilies);
 0454   
 0455      $text = $message_parser->message;
 0456      $uid = $message_parser->bbcode_uid;
 0457   
 0458      // If the bbcode_bitfield is empty, there is no need for the uid to be stored.
 0459      if (!$message_parser->bbcode_bitfield)
 0460      {
 0461          $uid = '';
 0462      }
 0463   
 0464      $flags = (($allow_bbcode) ? OPTION_FLAG_BBCODE : 0) + (($allow_smilies) ? OPTION_FLAG_SMILIES : 0) + (($allow_urls) ? OPTION_FLAG_LINKS : 0);
 0465      $bitfield = $message_parser->bbcode_bitfield;
 0466   
 0467      return;
 0468  }
 0469   
 0470  /**
 0471  * For decoding custom parsed text for edits as well as extracting the flags
 0472  * Expects $text to be the value directly from the database (pre-parsed content)
 0473  */
 0474  function generate_text_for_edit($text, $uid, $flags)
 0475  {
 0476      global $phpbb_root_path, $phpEx;
 0477   
 0478      decode_message($text, $uid);
 0479   
 0480      return array(
 0481          'allow_bbcode'    => ($flags & OPTION_FLAG_BBCODE) ? 1 : 0,
 0482          'allow_smilies'    => ($flags & OPTION_FLAG_SMILIES) ? 1 : 0,
 0483          'allow_urls'    => ($flags & OPTION_FLAG_LINKS) ? 1 : 0,
 0484          'text'            => $text
 0485      );
 0486  }
 0487   
 0488  /**
 0489  * A subroutine of make_clickable used with preg_replace
 0490  * It places correct HTML around an url, shortens the displayed text
 0491  * and makes sure no entities are inside URLs
 0492  */
 0493  function make_clickable_callback($type, $whitespace, $url, $relative_url, $class)
 0494  {
 0495      $append            = '';
 0496      $url            = htmlspecialchars_decode($url);
 0497      $relative_url    = htmlspecialchars_decode($relative_url);
 0498   
 0499      // make sure no HTML entities were matched
 0500      $chars = array('<', '>', '"');
 0501      $split = false;
 0502   
 0503      foreach ($chars as $char)
 0504      {
 0505          $next_split = strpos($url, $char);
 0506          if ($next_split !== false)
 0507          {
 0508              $split = ($split !== false) ? min($split, $next_split) : $next_split;
 0509          }
 0510      }
 0511   
 0512      if ($split !== false)
 0513      {
 0514          // an HTML entity was found, so the URL has to end before it
 0515          $append            = substr($url, $split) . $relative_url;
 0516          $url            = substr($url, 0, $split);
 0517          $relative_url    = '';
 0518      }
 0519      else if ($relative_url)
 0520      {
 0521          // same for $relative_url
 0522          $split = false;
 0523          foreach ($chars as $char)
 0524          {
 0525              $next_split = strpos($relative_url, $char);
 0526              if ($next_split !== false)
 0527              {
 0528                  $split = ($split !== false) ? min($split, $next_split) : $next_split;
 0529              }
 0530          }
 0531   
 0532          if ($split !== false)
 0533          {
 0534              $append            = substr($relative_url, $split);
 0535              $relative_url    = substr($relative_url, 0, $split);
 0536          }
 0537      }
 0538   
 0539      // if the last character of the url is a punctuation mark, exclude it from the url
 0540      $last_char = ($relative_url) ? $relative_url[strlen($relative_url) - 1] : $url[strlen($url) - 1];
 0541   
 0542      switch ($last_char)
 0543      {
 0544          case '.':
 0545          case '?':
 0546          case '!':
 0547          case ':':
 0548          case ',':
 0549              $append = $last_char;
 0550              if ($relative_url)
 0551              {
 0552                  $relative_url = substr($relative_url, 0, -1);
 0553              }
 0554              else
 0555              {
 0556                  $url = substr($url, 0, -1);
 0557              }
 0558          break;
 0559      }
 0560   
 0561      switch ($type)
 0562      {
 0563          case MAGIC_URL_LOCAL:
 0564              $tag            = 'l';
 0565              $relative_url    = preg_replace('/[&?]sid=[0-9a-f]{32}$/', '', preg_replace('/([&?])sid=[0-9a-f]{32}&/', '$1', $relative_url));
 0566              $url            = $url . '/' . $relative_url;
 0567              $text            = ($relative_url) ? $relative_url : $url;
 0568          break;
 0569   
 0570          case MAGIC_URL_FULL:
 0571              $tag    = 'm';
 0572              $text    = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url;
 0573          break;
 0574   
 0575          case MAGIC_URL_WWW:
 0576              $tag    = 'w';
 0577              $url    = 'http://' . $url;
 0578              $text    = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url;
 0579          break;
 0580   
 0581          case MAGIC_URL_EMAIL:
 0582              $tag    = 'e';
 0583              $text    = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url;
 0584              $url    = 'mailto:' . $url;
 0585          break;
 0586      }
 0587   
 0588      $url    = htmlspecialchars($url);
 0589      $text    = htmlspecialchars($text);
 0590      $append    = htmlspecialchars($append);
 0591   
 0592      $html    = "$whitespace<!-- $tag --><a$class href=\"$url\">$text</a><!-- $tag -->$append";
 0593   
 0594      return $html;
 0595  }
 0596   
 0597  /**
 0598  * make_clickable function
 0599  *
 0600  * Replace magic urls of form http://xxx.xxx., www.xxx. and xxx@xxx.xxx.
 0601  * Cuts down displayed size of link if over 50 chars, turns absolute links
 0602  * into relative versions when the server/script path matches the link
 0603  */
 0604  function make_clickable($text, $server_url = false, $class = 'postlink')
 0605  {
 0606      if ($server_url === false)
 0607      {
 0608          $server_url = generate_board_url();
 0609      }
 0610   
 0611      static $magic_url_match;
 0612      static $magic_url_replace;
 0613      static $static_class;
 0614   
 0615      if (!is_array($magic_url_match) || $static_class != $class)
 0616      {
 0617          $static_class = $class;
 0618          $class = ($static_class) ? ' class="' . $static_class . '"' : '';
 0619          $local_class = ($static_class) ? ' class="' . $static_class . '-local"' : '';
 0620   
 0621          $magic_url_match = $magic_url_replace = array();
 0622          // Be sure to not let the matches cross over. ;)
 0623   
 0624          // relative urls for this board
 0625          $magic_url_match[] = '#(^|[\n\t (>.])(' . preg_quote($server_url, '#') . ')/(' . get_preg_expression('relative_url_inline') . ')#ie';
 0626          $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_LOCAL, '\$1', '\$2', '\$3', '$local_class')";
 0627   
 0628          // matches a xxxx://aaaaa.bbb.cccc. ...
 0629          $magic_url_match[] = '#(^|[\n\t (>.])(' . get_preg_expression('url_inline') . ')#ie';
 0630          $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_FULL, '\$1', '\$2', '', '$class')";
 0631   
 0632          // matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing
 0633          $magic_url_match[] = '#(^|[\n\t (>])(' . get_preg_expression('www_url_inline') . ')#ie';
 0634          $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_WWW, '\$1', '\$2', '', '$class')";
 0635   
 0636          // matches an email@domain type address at the start of a line, or after a space or after what might be a BBCode.
 0637          $magic_url_match[] = '/(^|[\n\t (>])(' . get_preg_expression('email') . ')/ie';
 0638          $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_EMAIL, '\$1', '\$2', '', '')";
 0639      }
 0640   
 0641      return preg_replace($magic_url_match, $magic_url_replace, $text);
 0642  }
 0643   
 0644  /**
 0645  * Censoring
 0646  */
 0647  function censor_text($text)
 0648  {
 0649      static $censors;
 0650      global $cache;
 0651   
 0652      if (!isset($censors) || !is_array($censors))
 0653      {
 0654          // obtain_word_list is taking care of the users censor option and the board-wide option
 0655          $censors = $cache->obtain_word_list();
 0656      }
 0657   
 0658      if (sizeof($censors))
 0659      {
 0660          return preg_replace($censors['match'], $censors['replace'], $text);
 0661      }
 0662   
 0663      return $text;
 0664  }
 0665   
 0666  /**
 0667  * custom version of nl2br which takes custom BBCodes into account
 0668  */
 0669  function bbcode_nl2br($text)
 0670  {
 0671      // custom BBCodes might contain carriage returns so they
 0672      // are not converted into <br /> so now revert that
 0673      $text = str_replace(array("\n", "\r"), array('<br />', "\n"), $text);
 0674      return $text;
 0675  }
 0676   
 0677  /**
 0678  * Smiley processing
 0679  */
 0680  function smiley_text($text, $force_option = false)
 0681  {
 0682      global $config, $user, $phpbb_root_path;
 0683   
 0684      if ($force_option || !$config['allow_smilies'] || !$user->optionget('viewsmilies'))
 0685      {
 0686          return preg_replace('#<!\-\- s(.*?) \-\-><img src="\{SMILIES_PATH\}\/.*? \/><!\-\- s\1 \-\->#', '\1', $text);
 0687      }
 0688      else
 0689      {
 0690          return preg_replace('#<!\-\- s(.*?) \-\-><img src="\{SMILIES_PATH\}\/(.*?) \/><!\-\- s\1 \-\->#', '<img src="' . $phpbb_root_path . $config['smilies_path'] . '/\2 />', $text);
 0691      }
 0692  }
 0693   
 0694  /**
 0695  * General attachment parsing
 0696  *
 0697  * @param mixed $forum_id The forum id the attachments are displayed in (false if in private message)
 0698  * @param string &$message The post/private message
 0699  * @param array &$attachments The attachments to parse for (inline) display. The attachments array will hold templated data after parsing.
 0700  * @param array &$update_count The attachment counts to be updated - will be filled
 0701  * @param bool $preview If set to true the attachments are parsed for preview. Within preview mode the comments are fetched from the given $attachments array and not fetched from the database.
 0702  */
 0703  function parse_attachments($forum_id, &$message, &$attachments, &$update_count, $preview = false)
 0704  {
 0705      if (!sizeof($attachments))
 0706      {
 0707          return;
 0708      }
 0709   
 0710      global $template, $cache, $user;
 0711      global $extensions, $config, $phpbb_root_path, $phpEx;
 0712   
 0713      //
 0714      $compiled_attachments = array();
 0715   
 0716      if (!isset($template->filename['attachment_tpl']))
 0717      {
 0718          $template->set_filenames(array(
 0719              'attachment_tpl'    => 'attachment.html')
 0720          );
 0721      }
 0722   
 0723      if (empty($extensions) || !is_array($extensions))
 0724      {
 0725          $extensions = $cache->obtain_attach_extensions($forum_id);
 0726      }
 0727   
 0728      // Look for missing attachment information...
 0729      $attach_ids = array();
 0730      foreach ($attachments as $pos => $attachment)
 0731      {
 0732          // If is_orphan is set, we need to retrieve the attachments again...
 0733          if (!isset($attachment['extension']) && !isset($attachment['physical_filename']))
 0734          {
 0735              $attach_ids[(int) $attachment['attach_id']] = $pos;
 0736          }
 0737      }
 0738   
 0739      // Grab attachments (security precaution)
 0740      if (sizeof($attach_ids))
 0741      {
 0742          global $db;
 0743   
 0744          $new_attachment_data = array();
 0745   
 0746          $sql = 'SELECT *
 0747              FROM ' . ATTACHMENTS_TABLE . '
 0748              WHERE ' . $db->sql_in_set('attach_id', array_keys($attach_ids));
 0749          $result = $db->sql_query($sql);
 0750   
 0751          while ($row = $db->sql_fetchrow($result))
 0752          {
 0753              if (!isset($attach_ids[$row['attach_id']]))
 0754              {
 0755                  continue;
 0756              }
 0757   
 0758              // If we preview attachments we will set some retrieved values here
 0759              if ($preview)
 0760              {
 0761                  $row['attach_comment'] = $attachments[$attach_ids[$row['attach_id']]]['attach_comment'];
 0762              }
 0763   
 0764              $new_attachment_data[$attach_ids[$row['attach_id']]] = $row;
 0765          }
 0766          $db->sql_freeresult($result);
 0767   
 0768          $attachments = $new_attachment_data;
 0769          unset($new_attachment_data);
 0770      }
 0771   
 0772      // Sort correctly
 0773      if ($config['display_order'])
 0774      {
 0775          // Ascending sort
 0776          krsort($attachments);
 0777      }
 0778      else
 0779      {
 0780          // Descending sort
 0781          ksort($attachments);
 0782      }
 0783   
 0784      foreach ($attachments as $attachment)
 0785      {
 0786          if (!sizeof($attachment))
 0787          {
 0788              continue;
 0789          }
 0790   
 0791          // We need to reset/empty the _file block var, because this function might be called more than once
 0792          $template->destroy_block_vars('_file');
 0793   
 0794          $block_array = array();
 0795          
 0796          // Some basics...
 0797          $attachment['extension'] = strtolower(trim($attachment['extension']));
 0798          $filename = $phpbb_root_path . $config['upload_path'] . '/' . basename($attachment['physical_filename']);
 0799          $thumbnail_filename = $phpbb_root_path . $config['upload_path'] . '/thumb_' . basename($attachment['physical_filename']);
 0800   
 0801          $upload_icon = '';
 0802   
 0803          if (isset($extensions[$attachment['extension']]))
 0804          {
 0805              if ($user->img('icon_topic_attach', '') && !$extensions[$attachment['extension']]['upload_icon'])
 0806              {
 0807                  $upload_icon = $user->img('icon_topic_attach', '');
 0808              }
 0809              else if ($extensions[$attachment['extension']]['upload_icon'])
 0810              {
 0811                  $upload_icon = '<img src="' . $phpbb_root_path . $config['upload_icons_path'] . '/' . trim($extensions[$attachment['extension']]['upload_icon']) . '" alt="" />';
 0812              }
 0813          }
 0814   
 0815          $filesize = $attachment['filesize'];
 0816          $size_lang = ($filesize >= 1048576) ? $user->lang['MB'] : ( ($filesize >= 1024) ? $user->lang['KB'] : $user->lang['BYTES'] );
 0817          $filesize = ($filesize >= 1048576) ? round((round($filesize / 1048576 * 100) / 100), 2) : (($filesize >= 1024) ? round((round($filesize / 1024 * 100) / 100), 2) : $filesize);
 0818   
 0819          $comment = bbcode_nl2br(censor_text($attachment['attach_comment']));
 0820   
 0821          $block_array += array(
 0822              'UPLOAD_ICON'        => $upload_icon,
 0823              'FILESIZE'            => $filesize,
 0824              'SIZE_LANG'            => $size_lang,
 0825              'DOWNLOAD_NAME'        => basename($attachment['real_filename']),
 0826              'COMMENT'            => $comment,
 0827          );
 0828   
 0829          $denied = false;
 0830   
 0831          if (!extension_allowed($forum_id, $attachment['extension'], $extensions))
 0832          {
 0833              $denied = true;
 0834   
 0835              $block_array += array(
 0836                  'S_DENIED'            => true,
 0837                  'DENIED_MESSAGE'    => sprintf($user->lang['EXTENSION_DISABLED_AFTER_POSTING'], $attachment['extension'])
 0838              );
 0839          }
 0840   
 0841          if (!$denied)
 0842          {
 0843              $l_downloaded_viewed = $download_link = '';
 0844              $display_cat = $extensions[$attachment['extension']]['display_cat'];
 0845   
 0846              if ($display_cat == ATTACHMENT_CATEGORY_IMAGE)
 0847              {
 0848                  if ($attachment['thumbnail'])
 0849                  {
 0850                      $display_cat = ATTACHMENT_CATEGORY_THUMB;
 0851                  }
 0852                  else
 0853                  {
 0854                      if ($config['img_display_inlined'])
 0855                      {
 0856                          if ($config['img_link_width'] || $config['img_link_height'])
 0857                          {
 0858                              $dimension = @getimagesize($filename);
 0859   
 0860                              // If the dimensions could not be determined or the image being 0x0 we display it as a link for safety purposes
 0861                              if ($dimension === false || empty($dimension[0]) || empty($dimension[1]))
 0862                              {
 0863                                  $display_cat = ATTACHMENT_CATEGORY_NONE;
 0864                              }
 0865                              else
 0866                              {
 0867                                  $display_cat = ($dimension[0] <= $config['img_link_width'] && $dimension[1] <= $config['img_link_height']) ? ATTACHMENT_CATEGORY_IMAGE : ATTACHMENT_CATEGORY_NONE;
 0868                              }
 0869                          }
 0870                      }
 0871                      else
 0872                      {
 0873                          $display_cat = ATTACHMENT_CATEGORY_NONE;
 0874                      }
 0875                  }
 0876              }
 0877   
 0878              // Make some descisions based on user options being set.
 0879              if (($display_cat == ATTACHMENT_CATEGORY_IMAGE || $display_cat == ATTACHMENT_CATEGORY_THUMB) && !$user->optionget('viewimg'))
 0880              {
 0881                  $display_cat = ATTACHMENT_CATEGORY_NONE;
 0882              }
 0883   
 0884              if ($display_cat == ATTACHMENT_CATEGORY_FLASH && !$user->optionget('viewflash'))
 0885              {
 0886                  $display_cat = ATTACHMENT_CATEGORY_NONE;
 0887              }
 0888   
 0889              $download_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $attachment['attach_id']);
 0890   
 0891              switch ($display_cat)
 0892              {
 0893                  // Images
 0894                  case ATTACHMENT_CATEGORY_IMAGE:
 0895                      $l_downloaded_viewed = 'VIEWED_COUNT';
 0896                      $inline_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $attachment['attach_id']);
 0897                      $download_link .= '&amp;mode=view';
 0898   
 0899                      $block_array += array(
 0900                          'S_IMAGE'        => true,
 0901                          'U_INLINE_LINK'        => $inline_link,
 0902                      );
 0903   
 0904                      $update_count[] = $attachment['attach_id'];
 0905                  break;
 0906   
 0907                  // Images, but display Thumbnail
 0908                  case ATTACHMENT_CATEGORY_THUMB:
 0909                      $l_downloaded_viewed = 'VIEWED_COUNT';
 0910                      $thumbnail_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $attachment['attach_id'] . '&amp;t=1');
 0911                      $download_link .= '&amp;mode=view';
 0912   
 0913                      $block_array += array(
 0914                          'S_THUMBNAIL'        => true,
 0915                          'THUMB_IMAGE'        => $thumbnail_link,
 0916                      );
 0917                  break;
 0918   
 0919                  // Windows Media Streams
 0920                  case ATTACHMENT_CATEGORY_WM:
 0921                      $l_downloaded_viewed = 'VIEWED_COUNT';
 0922   
 0923                      // Giving the filename directly because within the wm object all variables are in local context making it impossible
 0924                      // to validate against a valid session (all params can differ)
 0925                      // $download_link = $filename;
 0926   
 0927                      $block_array += array(
 0928                          'U_FORUM'        => generate_board_url(),
 0929                          'ATTACH_ID'        => $attachment['attach_id'],
 0930                          'S_WM_FILE'        => true,
 0931                      );
 0932   
 0933                      // Viewed/Heared File ... update the download count
 0934                      $update_count[] = $attachment['attach_id'];
 0935                  break;
 0936   
 0937                  // Real Media Streams
 0938                  case ATTACHMENT_CATEGORY_RM:
 0939                  case ATTACHMENT_CATEGORY_QUICKTIME:
 0940                      $l_downloaded_viewed = 'VIEWED_COUNT';
 0941   
 0942                      $block_array += array(
 0943                          'S_RM_FILE'            => ($display_cat == ATTACHMENT_CATEGORY_RM) ? true : false,
 0944                          'S_QUICKTIME_FILE'    => ($display_cat == ATTACHMENT_CATEGORY_QUICKTIME) ? true : false,
 0945                          'U_FORUM'            => generate_board_url(),
 0946                          'ATTACH_ID'            => $attachment['attach_id'],
 0947                      );
 0948   
 0949                      // Viewed/Heared File ... update the download count
 0950                      $update_count[] = $attachment['attach_id'];
 0951                  break;
 0952   
 0953                  // Macromedia Flash Files
 0954                  case ATTACHMENT_CATEGORY_FLASH:
 0955                      list($width, $height) = @getimagesize($filename);
 0956   
 0957                      $l_downloaded_viewed = 'VIEWED_COUNT';
 0958   
 0959                      $block_array += array(
 0960                          'S_FLASH_FILE'    => true,
 0961                          'WIDTH'            => $width,
 0962                          'HEIGHT'        => $height,
 0963                      );
 0964   
 0965                      // Viewed/Heared File ... update the download count
 0966                      $update_count[] = $attachment['attach_id'];
 0967                  break;
 0968   
 0969                  default:
 0970                      $l_downloaded_viewed = 'DOWNLOAD_COUNT';
 0971   
 0972                      $block_array += array(
 0973                          'S_FILE'        => true,
 0974                      );
 0975                  break;
 0976              }
 0977   
 0978              $l_download_count = (!isset($attachment['download_count']) || $attachment['download_count'] == 0) ? $user->lang[$l_downloaded_viewed . '_NONE'] : (($attachment['download_count'] == 1) ? sprintf($user->lang[$l_downloaded_viewed], $attachment['download_count']) : sprintf($user->lang[$l_downloaded_viewed . 'S'], $attachment['download_count']));
 0979   
 0980              $block_array += array(
 0981                  'U_DOWNLOAD_LINK'        => $download_link,
 0982                  'L_DOWNLOAD_COUNT'        => $l_download_count
 0983              );
 0984          }
 0985   
 0986          $template->assign_block_vars('_file', $block_array);
 0987   
 0988          $compiled_attachments[] = $template->assign_display('attachment_tpl');
 0989      }
 0990   
 0991      $attachments = $compiled_attachments;
 0992      unset($compiled_attachments);
 0993   
 0994      $tpl_size = sizeof($attachments);
 0995   
 0996      $unset_tpl = array();
 0997   
 0998      preg_match_all('#<!\-\- ia([0-9]+) \-\->(.*?)<!\-\- ia\1 \-\->#', $message, $matches, PREG_PATTERN_ORDER);
 0999   
 1000      $replace = array();
 1001      foreach ($matches[0] as $num => $capture)
 1002      {
 1003          // Flip index if we are displaying the reverse way
 1004          $index = ($config['display_order']) ? ($tpl_size-($matches[1][$num] + 1)) : $matches[1][$num];
 1005   
 1006          $replace['from'][] = $matches[0][$num];
 1007          $replace['to'][] = (isset($attachments[$index])) ? $attachments[$index] : sprintf($user->lang['MISSING_INLINE_ATTACHMENT'], $matches[2][array_search($index, $matches[1])]);
 1008   
 1009          $unset_tpl[] = $index;
 1010      }
 1011   
 1012      if (isset($replace['from']))
 1013      {
 1014          $message = str_replace($replace['from'], $replace['to'], $message);
 1015      }
 1016   
 1017      $unset_tpl = array_unique($unset_tpl);
 1018   
 1019      // Needed to let not display the inlined attachments at the end of the post again
 1020      foreach ($unset_tpl as $index)
 1021      {
 1022          unset($attachments[$index]);
 1023      }
 1024  }
 1025   
 1026  /**
 1027  * Check if extension is allowed to be posted.
 1028  *
 1029  * @param mixed $forum_id The forum id to check or false if private message
 1030  * @param string $extension The extension to check, for example zip.
 1031  * @param array &$extensions The extension array holding the information from the cache (will be obtained if empty)
 1032  *
 1033  * @return bool False if the extension is not allowed to be posted, else true.
 1034  */
 1035  function extension_allowed($forum_id, $extension, &$extensions)
 1036  {
 1037      if (empty($extensions))
 1038      {
 1039          global $cache;
 1040          $extensions = $cache->obtain_attach_extensions($forum_id);
 1041      }
 1042   
 1043      return (!isset($extensions['_allowed_'][$extension])) ? false : true;
 1044  }
 1045   
 1046  /**
 1047  * Truncates string while retaining special characters if going over the max length
 1048  * The default max length is 60 at the moment
 1049  */
 1050  function truncate_string($string, $max_length = 60, $allow_reply = true, $append = '')
 1051  {
 1052      $chars = array();
 1053   
 1054      $strip_reply = false;
 1055      $stripped = false;
 1056      if ($allow_reply && strpos($string, 'Re: ') === 0)
 1057      {
 1058          $strip_reply = true;
 1059          $string = substr($string, 4);
 1060      }
 1061   
 1062      $_chars = utf8_str_split(htmlspecialchars_decode($string));
 1063      $chars = array_map('utf8_htmlspecialchars', $_chars);
 1064   
 1065      // Now check the length ;)
 1066      if (sizeof($chars) > $max_length)
 1067      {
 1068          // Cut off the last elements from the array
 1069          $string = implode('', array_slice($chars, 0, $max_length - utf8_strlen($append)));
 1070          $stripped = true;
 1071      }
 1072   
 1073      if ($strip_reply)
 1074      {
 1075          $string = 'Re: ' . $string;
 1076      }
 1077      
 1078      if ($append != '' && $stripped)
 1079      {
 1080          $string = $string . $append;
 1081      }
 1082   
 1083      return $string;
 1084  }
 1085   
 1086  /**
 1087  * Get username details for placing into templates.
 1088  *
 1089  * @param string $mode Can be profile (for getting an url to the profile), username (for obtaining the username), colour (for obtaining the user colour), full (for obtaining a html string representing a coloured link to the users profile) or no_profile (the same as full but forcing no profile link)
 1090  * @param int $user_id The users id
 1091  * @param string $username The users name
 1092  * @param string $username_colour The users colour
 1093  * @param string $guest_username optional parameter to specify the guest username. It will be used in favor of the GUEST language variable then.
 1094  * @param string $custom_profile_url optional parameter to specify a profile url. The user id get appended to this url as &amp;u={user_id}
 1095  *
 1096  * @return string A string consisting of what is wanted based on $mode.
 1097  */
 1098  function get_username_string($mode, $user_id, $username, $username_colour = '', $guest_username = false, $custom_profile_url = false)
 1099  {
 1100      global $phpbb_root_path, $phpEx, $user, $auth;
 1101   
 1102      $profile_url = '';
 1103      $username_colour = ($username_colour) ? '#' . $username_colour : '';
 1104   
 1105      if ($guest_username === false)
 1106      {
 1107          $username = ($username) ? $username : $user->lang['GUEST'];
 1108      }
 1109      else
 1110      {
 1111          $username = ($user_id && $user_id != ANONYMOUS) ? $username : ((!empty($guest_username)) ? $guest_username : $user->lang['GUEST']);
 1112      }
 1113   
 1114      // Only show the link if not anonymous
 1115      if ($mode != 'no_profile' && $user_id && $user_id != ANONYMOUS)
 1116      {
 1117          // Do not show the link if the user is already logged in but do not have u_viewprofile permissions (relevant for bots mostly).
 1118          // For all others the link leads to a login page or the profile.
 1119          if ($user->data['user_id'] != ANONYMOUS && !$auth->acl_get('u_viewprofile'))
 1120          {
 1121              $profile_url = '';
 1122          }
 1123          else
 1124          {
 1125              $profile_url = ($custom_profile_url !== false) ? $custom_profile_url . '&amp;u=' . (int) $user_id : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile&amp;u=' . (int) $user_id);
 1126          }
 1127      }
 1128      else
 1129      {
 1130          $profile_url = '';
 1131      }
 1132   
 1133      switch ($mode)
 1134      {
 1135          case 'profile':
 1136              return $profile_url;
 1137          break;
 1138   
 1139          case 'username':
 1140              return $username;
 1141          break;
 1142   
 1143          case 'colour':
 1144              return $username_colour;
 1145          break;
 1146   
 1147          case 'no_profile':
 1148          case 'full':
 1149          default:
 1150   
 1151              $tpl = '';
 1152              if (!$profile_url && !$username_colour)
 1153              {
 1154                  $tpl = '{USERNAME}';
 1155              }
 1156              else if (!$profile_url && $username_colour)
 1157              {
 1158                  $tpl = '<span style="color: {USERNAME_COLOUR};" class="username-coloured">{USERNAME}</span>';
 1159              }
 1160              else if ($profile_url && !$username_colour)
 1161              {
 1162                  $tpl = '<a href="{PROFILE_URL}">{USERNAME}</a>';
 1163              }
 1164              else if ($profile_url && $username_colour)
 1165              {
 1166                  $tpl = '<a href="{PROFILE_URL}" style="color: {USERNAME_COLOUR};" class="username-coloured">{USERNAME}</a>';
 1167              }
 1168   
 1169              return str_replace(array('{PROFILE_URL}', '{USERNAME_COLOUR}', '{USERNAME}'), array($profile_url, $username_colour, $username), $tpl);
 1170          break;
 1171      }
 1172  }
 1173   
 1174  /**
 1175  * @package phpBB3
 1176  */
 1177  class bitfield
 1178  {
 1179      var $data;
 1180   
 1181      function bitfield($bitfield = '')
 1182      {
 1183          $this->data = base64_decode($bitfield);
 1184      }
 1185   
 1186      /**
 1187      */
 1188      function get($n)
 1189      {
 1190          // Get the ($n / 8)th char
 1191          $byte = $n >> 3;
 1192   
 1193          if (strlen($this->data) >= $byte + 1)
 1194          {
 1195              $c = $this->data[$byte];
 1196      
 1197              // Lookup the ($n % 8)th bit of the byte
 1198              $bit = 7 - ($n & 7);
 1199              return (bool) (ord($c) & (1 << $bit));
 1200          }
 1201          else
 1202          {
 1203              return false;
 1204          }
 1205      }
 1206   
 1207      function set($n)
 1208      {
 1209          $byte = $n >> 3;
 1210          $bit = 7 - ($n & 7);
 1211   
 1212          if (strlen($this->data) >= $byte + 1)
 1213          {
 1214              $this->data[$byte] = $this->data[$byte] | chr(1 << $bit);
 1215          }
 1216          else
 1217          {
 1218              $this->data .= str_repeat("\0", $byte - strlen($this->data));
 1219              $this->data .= chr(1 << $bit);
 1220          }
 1221      }
 1222   
 1223      function clear($n)
 1224      {
 1225          $byte = $n >> 3;
 1226   
 1227          if (strlen($this->data) >= $byte + 1)
 1228          {
 1229              $bit = 7 - ($n & 7);
 1230              $this->data[$byte] = $this->data[$byte] &~ chr(1 << $bit);
 1231          }
 1232      }
 1233   
 1234      function get_blob()
 1235      {
 1236          return $this->data;
 1237      }
 1238   
 1239      function get_base64()
 1240      {
 1241          return base64_encode($this->data);
 1242      }
 1243   
 1244      function get_bin()
 1245      {
 1246          $bin = '';
 1247          $len = strlen($this->data);
 1248   
 1249          for ($i = 0; $i < $len; ++$i)
 1250          {
 1251              $bin .= str_pad(decbin(ord($this->data[$i])), 8, '0', STR_PAD_LEFT);
 1252          }
 1253   
 1254          return $bin;
 1255      }
 1256   
 1257      function get_all_set()
 1258      {
 1259          return array_keys(array_filter(str_split($this->get_bin())));
 1260      }
 1261   
 1262      function merge($bitfield)
 1263      {
 1264          $this->data = $this->data | $bitfield->get_blob();
 1265      }
 1266  }
 1267   
 1268  ?>