Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

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_phpbb20.php

Zuletzt modifiziert: 02.04.2025, 15:02 - Dateigröße: 52.07 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  if (!defined('IN_PHPBB'))
0015  {
0016      exit;
0017  }
0018   
0019  /**
0020  * Helper functions for phpBB 2.0.x to phpBB 3.1.x conversion
0021  */
0022   
0023  /**
0024  * Set forum flags - only prune old polls by default
0025  */
0026  function phpbb_forum_flags()
0027  {
0028      // Set forum flags
0029      $forum_flags = 0;
0030   
0031      // FORUM_FLAG_LINK_TRACK
0032      $forum_flags += 0;
0033   
0034      // FORUM_FLAG_PRUNE_POLL
0035      $forum_flags += FORUM_FLAG_PRUNE_POLL;
0036   
0037      // FORUM_FLAG_PRUNE_ANNOUNCE
0038      $forum_flags += 0;
0039   
0040      // FORUM_FLAG_PRUNE_STICKY
0041      $forum_flags += 0;
0042   
0043      // FORUM_FLAG_ACTIVE_TOPICS
0044      $forum_flags += 0;
0045   
0046      // FORUM_FLAG_POST_REVIEW
0047      $forum_flags += FORUM_FLAG_POST_REVIEW;
0048   
0049      return $forum_flags;
0050  }
0051   
0052  /**
0053  * Insert/Convert forums
0054  */
0055  function phpbb_insert_forums()
0056  {
0057      global $db, $src_db, $same_db, $convert, $user;
0058   
0059      $db->sql_query($convert->truncate_statement . FORUMS_TABLE);
0060   
0061      // Determine the highest id used within the old forums table (we add the categories after the forum ids)
0062      $sql = 'SELECT MAX(forum_id) AS max_forum_id
0063          FROM ' . $convert->src_table_prefix . 'forums';
0064      $result = $src_db->sql_query($sql);
0065      $max_forum_id = (int) $src_db->sql_fetchfield('max_forum_id');
0066      $src_db->sql_freeresult($result);
0067   
0068      $max_forum_id++;
0069   
0070      // pruning disabled globally?
0071      $sql = "SELECT config_value
0072          FROM {$convert->src_table_prefix}config
0073          WHERE config_name = 'prune_enable'";
0074      $result = $src_db->sql_query($sql);
0075      $prune_enabled = (int) $src_db->sql_fetchfield('config_value');
0076      $src_db->sql_freeresult($result);
0077   
0078      // Insert categories
0079      $sql = 'SELECT cat_id, cat_title
0080          FROM ' . $convert->src_table_prefix . 'categories
0081          ORDER BY cat_order';
0082   
0083      if ($convert->mysql_convert && $same_db)
0084      {
0085          $src_db->sql_query("SET NAMES 'binary'");
0086      }
0087   
0088      $result = $src_db->sql_query($sql);
0089   
0090      if ($convert->mysql_convert && $same_db)
0091      {
0092          $src_db->sql_query("SET NAMES 'utf8'");
0093      }
0094   
0095      switch ($db->get_sql_layer())
0096      {
0097          case 'mssql_odbc':
0098          case 'mssqlnative':
0099              $db->sql_query('SET IDENTITY_INSERT ' . FORUMS_TABLE . ' ON');
0100          break;
0101      }
0102   
0103      $cats_added = array();
0104      while ($row = $src_db->sql_fetchrow($result))
0105      {
0106          $sql_ary = array(
0107              'forum_id'        => (int) $max_forum_id,
0108              'forum_name'    => ($row['cat_title']) ? htmlspecialchars(phpbb_set_default_encoding($row['cat_title']), ENT_COMPAT, 'UTF-8') : $user->lang['CATEGORY'],
0109              'parent_id'        => 0,
0110              'forum_parents'    => '',
0111              'forum_desc'    => '',
0112              'forum_type'    => FORUM_CAT,
0113              'forum_status'    => ITEM_UNLOCKED,
0114              'forum_rules'    => '',
0115          );
0116   
0117          $sql = 'SELECT MAX(right_id) AS right_id
0118              FROM ' . FORUMS_TABLE;
0119          $_result = $db->sql_query($sql);
0120          $cat_row = $db->sql_fetchrow($_result);
0121          $db->sql_freeresult($_result);
0122   
0123          $sql_ary['left_id'] = (int) ($cat_row['right_id'] + 1);
0124          $sql_ary['right_id'] = (int) ($cat_row['right_id'] + 2);
0125   
0126          $sql = 'INSERT INTO ' . FORUMS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
0127          $db->sql_query($sql);
0128   
0129          $cats_added[$row['cat_id']] = $max_forum_id;
0130          $max_forum_id++;
0131      }
0132      $src_db->sql_freeresult($result);
0133   
0134      // There may be installations having forums with non-existant category ids.
0135      // We try to catch them and add them to an "unknown" category instead of leaving them out.
0136      $sql = 'SELECT cat_id
0137          FROM ' . $convert->src_table_prefix . 'forums
0138          GROUP BY cat_id';
0139      $result = $src_db->sql_query($sql);
0140   
0141      $unknown_cat_id = false;
0142      while ($row = $src_db->sql_fetchrow($result))
0143      {
0144          // Catch those categories not been added before
0145          if (!isset($cats_added[$row['cat_id']]))
0146          {
0147              $unknown_cat_id = true;
0148          }
0149      }
0150      $src_db->sql_freeresult($result);
0151   
0152      // Is there at least one category not known?
0153      if ($unknown_cat_id === true)
0154      {
0155          $unknown_cat_id = 'ghost';
0156   
0157          $sql_ary = array(
0158              'forum_id'        => (int) $max_forum_id,
0159              'forum_name'    => (string) $user->lang['CATEGORY'],
0160              'parent_id'        => 0,
0161              'forum_parents'    => '',
0162              'forum_desc'    => '',
0163              'forum_type'    => FORUM_CAT,
0164              'forum_status'    => ITEM_UNLOCKED,
0165              'forum_rules'    => '',
0166          );
0167   
0168          $sql = 'SELECT MAX(right_id) AS right_id
0169              FROM ' . FORUMS_TABLE;
0170          $_result = $db->sql_query($sql);
0171          $cat_row = $db->sql_fetchrow($_result);
0172          $db->sql_freeresult($_result);
0173   
0174          $sql_ary['left_id'] = (int) ($cat_row['right_id'] + 1);
0175          $sql_ary['right_id'] = (int) ($cat_row['right_id'] + 2);
0176   
0177          $sql = 'INSERT INTO ' . FORUMS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
0178          $db->sql_query($sql);
0179   
0180          $cats_added[$unknown_cat_id] = $max_forum_id;
0181      }
0182   
0183      // Now insert the forums
0184      $sql = 'SELECT f.forum_id, f.forum_name, f.cat_id, f.forum_desc, f.forum_status, f.prune_enable, f.prune_next, fp.prune_days, fp.prune_freq FROM ' . $convert->src_table_prefix . 'forums f
0185          LEFT JOIN ' . $convert->src_table_prefix . 'forum_prune fp ON f.forum_id = fp.forum_id
0186          GROUP BY f.forum_id, f.forum_name, f.cat_id, f.forum_desc, f.forum_status, f.prune_enable, f.prune_next, f.forum_order, fp.prune_days, fp.prune_freq
0187          ORDER BY f.cat_id, f.forum_order';
0188   
0189      if ($convert->mysql_convert && $same_db)
0190      {
0191          $src_db->sql_query("SET NAMES 'binary'");
0192      }
0193   
0194      $result = $src_db->sql_query($sql);
0195   
0196      if ($convert->mysql_convert && $same_db)
0197      {
0198          $src_db->sql_query("SET NAMES 'utf8'");
0199      }
0200   
0201      while ($row = $src_db->sql_fetchrow($result))
0202      {
0203          // Some might have forums here with an id not being "possible"...
0204          // To be somewhat friendly we "change" the category id for those to a previously created ghost category
0205          if (!isset($cats_added[$row['cat_id']]) && $unknown_cat_id !== false)
0206          {
0207              $row['cat_id'] = $unknown_cat_id;
0208          }
0209   
0210          if (!isset($cats_added[$row['cat_id']]))
0211          {
0212              continue;
0213          }
0214   
0215          // Define the new forums sql ary
0216          $sql_ary = array(
0217              'forum_id'            => (int) $row['forum_id'],
0218              'forum_name'        => htmlspecialchars(phpbb_set_default_encoding($row['forum_name']), ENT_COMPAT, 'UTF-8'),
0219              'parent_id'            => (int) $cats_added[$row['cat_id']],
0220              'forum_parents'        => '',
0221              'forum_desc'        => htmlspecialchars(phpbb_set_default_encoding($row['forum_desc']), ENT_COMPAT, 'UTF-8'),
0222              'forum_type'        => FORUM_POST,
0223              'forum_status'        => is_item_locked($row['forum_status']),
0224              'enable_prune'        => ($prune_enabled) ? (int) $row['prune_enable'] : 0,
0225              'prune_next'        => (int) null_to_zero($row['prune_next']),
0226              'prune_days'        => (int) null_to_zero($row['prune_days']),
0227              'prune_viewed'        => 0,
0228              'prune_freq'        => (int) null_to_zero($row['prune_freq']),
0229   
0230              'forum_flags'        => phpbb_forum_flags(),
0231              'forum_options'        => 0,
0232   
0233              // Default values
0234              'forum_desc_bitfield'        => '',
0235              'forum_desc_options'        => 7,
0236              'forum_desc_uid'            => '',
0237              'forum_link'                => '',
0238              'forum_password'            => '',
0239              'forum_style'                => 0,
0240              'forum_image'                => '',
0241              'forum_rules'                => '',
0242              'forum_rules_link'            => '',
0243              'forum_rules_bitfield'        => '',
0244              'forum_rules_options'        => 7,
0245              'forum_rules_uid'            => '',
0246              'forum_topics_per_page'        => 0,
0247              'forum_posts_approved'        => 0,
0248              'forum_posts_unapproved'    => 0,
0249              'forum_posts_softdeleted'    => 0,
0250              'forum_topics_approved'        => 0,
0251              'forum_topics_unapproved'    => 0,
0252              'forum_topics_softdeleted'    => 0,
0253              'forum_last_post_id'        => 0,
0254              'forum_last_poster_id'        => 0,
0255              'forum_last_post_subject'    => '',
0256              'forum_last_post_time'        => 0,
0257              'forum_last_poster_name'    => '',
0258              'forum_last_poster_colour'    => '',
0259              'display_on_index'            => 1,
0260              'enable_indexing'            => 1,
0261              'enable_icons'                => 0,
0262          );
0263   
0264          // Now add the forums with proper left/right ids
0265          $sql = 'SELECT left_id, right_id
0266              FROM ' . FORUMS_TABLE . '
0267              WHERE forum_id = ' . $cats_added[$row['cat_id']];
0268          $_result = $db->sql_query($sql);
0269          $cat_row = $db->sql_fetchrow($_result);
0270          $db->sql_freeresult($_result);
0271   
0272          $sql = 'UPDATE ' . FORUMS_TABLE . '
0273              SET left_id = left_id + 2, right_id = right_id + 2
0274              WHERE left_id > ' . $cat_row['right_id'];
0275          $db->sql_query($sql);
0276   
0277          $sql = 'UPDATE ' . FORUMS_TABLE . '
0278              SET right_id = right_id + 2
0279              WHERE ' . $cat_row['left_id'] . ' BETWEEN left_id AND right_id';
0280          $db->sql_query($sql);
0281   
0282          $sql_ary['left_id'] = (int) $cat_row['right_id'];
0283          $sql_ary['right_id'] = (int) ($cat_row['right_id'] + 1);
0284   
0285          $sql = 'INSERT INTO ' . FORUMS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
0286          $db->sql_query($sql);
0287      }
0288      $src_db->sql_freeresult($result);
0289   
0290      switch ($db->get_sql_layer())
0291      {
0292          case 'postgres':
0293              $db->sql_query("SELECT SETVAL('" . FORUMS_TABLE . "_seq',(select case when max(forum_id)>0 then max(forum_id)+1 else 1 end from " . FORUMS_TABLE . '));');
0294          break;
0295   
0296          case 'mssql_odbc':
0297          case 'mssqlnative':
0298              $db->sql_query('SET IDENTITY_INSERT ' . FORUMS_TABLE . ' OFF');
0299          break;
0300   
0301          case 'oracle':
0302              $result = $db->sql_query('SELECT MAX(forum_id) as max_id FROM ' . FORUMS_TABLE);
0303              $row = $db->sql_fetchrow($result);
0304              $db->sql_freeresult($result);
0305   
0306              $largest_id = (int) $row['max_id'];
0307   
0308              if ($largest_id)
0309              {
0310                  $db->sql_query('DROP SEQUENCE ' . FORUMS_TABLE . '_seq');
0311                  $db->sql_query('CREATE SEQUENCE ' . FORUMS_TABLE . '_seq START WITH ' . ($largest_id + 1));
0312              }
0313          break;
0314      }
0315  }
0316   
0317  /**
0318  * Function for recoding text with the default language
0319  *
0320  * @param string $text text to recode to utf8
0321  * @param bool $grab_user_lang if set to true the function tries to use $convert_row['user_lang'] (and falls back to $convert_row['poster_id']) instead of the boards default language
0322  */
0323  function phpbb_set_encoding($text, $grab_user_lang = true)
0324  {
0325      global $lang_enc_array, $convert_row;
0326      global $convert, $phpEx;
0327   
0328      /*static $lang_enc_array = array(
0329          'korean'                        => 'euc-kr',
0330          'serbian'                        => 'windows-1250',
0331          'polish'                        => 'iso-8859-2',
0332          'kurdish'                        => 'windows-1254',
0333          'slovak'                        => 'Windows-1250',
0334          'russian'                        => 'windows-1251',
0335          'estonian'                        => 'iso-8859-4',
0336          'chinese_simplified'            => 'gb2312',
0337          'macedonian'                    => 'windows-1251',
0338          'azerbaijani'                    => 'UTF-8',
0339          'romanian'                        => 'iso-8859-2',
0340          'romanian_diacritice'            => 'iso-8859-2',
0341          'lithuanian'                    => 'windows-1257',
0342          'turkish'                        => 'iso-8859-9',
0343          'ukrainian'                        => 'windows-1251',
0344          'japanese'                        => 'shift_jis',
0345          'hungarian'                        => 'ISO-8859-2',
0346          'romanian_no_diacritics'        => 'iso-8859-2',
0347          'mongolian'                        => 'UTF-8',
0348          'slovenian'                        => 'windows-1250',
0349          'bosnian'                        => 'windows-1250',
0350          'czech'                            => 'Windows-1250',
0351          'farsi'                            => 'Windows-1256',
0352          'croatian'                        => 'windows-1250',
0353          'greek'                            => 'iso-8859-7',
0354          'russian_tu'                    => 'windows-1251',
0355          'sakha'                            => 'UTF-8',
0356          'serbian_cyrillic'                => 'windows-1251',
0357          'bulgarian'                        => 'windows-1251',
0358          'chinese_traditional_taiwan'    => 'big5',
0359          'chinese_traditional'            => 'big5',
0360          'arabic'                        => 'windows-1256',
0361          'hebrew'                        => 'WINDOWS-1255',
0362          'thai'                            => 'windows-874',
0363          //'chinese_traditional_taiwan'    => 'utf-8' // custom modified, we may have to do an include :-(
0364      );*/
0365   
0366      if (empty($lang_enc_array))
0367      {
0368          $lang_enc_array = array();
0369      }
0370   
0371      $get_lang = trim(get_config_value('default_lang'));
0372   
0373      // Do we need the users language encoding?
0374      if ($grab_user_lang && !empty($convert_row))
0375      {
0376          if (!empty($convert_row['user_lang']))
0377          {
0378              $get_lang = trim($convert_row['user_lang']);
0379          }
0380          else if (!empty($convert_row['poster_id']))
0381          {
0382              global $src_db, $same_db;
0383   
0384              if ($convert->mysql_convert && $same_db)
0385              {
0386                  $src_db->sql_query("SET NAMES 'binary'");
0387              }
0388   
0389              $sql = 'SELECT user_lang
0390                  FROM ' . $convert->src_table_prefix . 'users
0391                  WHERE user_id = ' . (int) $convert_row['poster_id'];
0392              $result = $src_db->sql_query($sql);
0393              $get_lang = (string) $src_db->sql_fetchfield('user_lang');
0394              $src_db->sql_freeresult($result);
0395   
0396              if ($convert->mysql_convert && $same_db)
0397              {
0398                  $src_db->sql_query("SET NAMES 'utf8'");
0399              }
0400   
0401              $get_lang = (!trim($get_lang)) ? trim(get_config_value('default_lang')) : trim($get_lang);
0402          }
0403      }
0404   
0405      if (!isset($lang_enc_array[$get_lang]))
0406      {
0407          $filename = $convert->options['forum_path'] . '/language/lang_' . $get_lang . '/lang_main.' . $phpEx;
0408   
0409          if (!file_exists($filename))
0410          {
0411              $get_lang = trim(get_config_value('default_lang'));
0412          }
0413   
0414          if (!isset($lang_enc_array[$get_lang]))
0415          {
0416              include($convert->options['forum_path'] . '/language/lang_' . $get_lang . '/lang_main.' . $phpEx);
0417              $lang_enc_array[$get_lang] = $lang['ENCODING'];
0418              unset($lang);
0419          }
0420      }
0421   
0422      return utf8_recode($text, $lang_enc_array[$get_lang]);
0423  }
0424   
0425  /**
0426  * Same as phpbb_set_encoding, but forcing boards default language
0427  */
0428  function phpbb_set_default_encoding($text)
0429  {
0430      return phpbb_set_encoding($text, false);
0431  }
0432   
0433  /**
0434  * Convert Birthday from Birthday MOD to phpBB Format
0435  */
0436  function phpbb_get_birthday($birthday = '')
0437  {
0438      if (defined('MOD_BIRTHDAY_TERRA'))
0439      {
0440          $birthday = (string) $birthday;
0441   
0442          // stored as month, day, year
0443          if (!$birthday)
0444          {
0445              return ' 0- 0-   0';
0446          }
0447   
0448          // We use the original mod code to retrieve the birthday (not ideal)
0449          preg_match('/(..)(..)(....)/', sprintf('%08d', $birthday), $birthday_parts);
0450   
0451          $month = $birthday_parts[1];
0452          $day = $birthday_parts[2];
0453          $year =  $birthday_parts[3];
0454   
0455          return sprintf('%2d-%2d-%4d', $day, $month, $year);
0456      }
0457      else
0458      {
0459          $birthday = (int) $birthday;
0460   
0461          if (!$birthday || $birthday == 999999)
0462          {
0463              return ' 0- 0-   0';
0464          }
0465   
0466          // The birthday mod from niels is using this code to transform to day/month/year
0467          return sprintf('%2d-%2d-%4d', gmdate('j', $birthday * 86400 + 1), gmdate('n', $birthday * 86400 + 1), gmdate('Y', $birthday * 86400 + 1));
0468      }
0469  }
0470   
0471  /**
0472  * Return correct user id value
0473  * Everyone's id will be one higher to allow the guest/anonymous user to have a positive id as well
0474  */
0475  function phpbb_user_id($user_id)
0476  {
0477      global $config;
0478   
0479      // Increment user id if the old forum is having a user with the id 1
0480      if (!isset($config['increment_user_id']))
0481      {
0482          global $src_db, $same_db, $convert;
0483   
0484          if ($convert->mysql_convert && $same_db)
0485          {
0486              $src_db->sql_query("SET NAMES 'binary'");
0487          }
0488   
0489          // Now let us set a temporary config variable for user id incrementing
0490          $sql = "SELECT user_id
0491              FROM {$convert->src_table_prefix}users
0492              WHERE user_id = 1";
0493          $result = $src_db->sql_query($sql);
0494          $id = (int) $src_db->sql_fetchfield('user_id');
0495          $src_db->sql_freeresult($result);
0496   
0497          // Try to get the maximum user id possible...
0498          $sql = "SELECT MAX(user_id) AS max_user_id
0499              FROM {$convert->src_table_prefix}users";
0500          $result = $src_db->sql_query($sql);
0501          $max_id = (int) $src_db->sql_fetchfield('max_user_id');
0502          $src_db->sql_freeresult($result);
0503   
0504          if ($convert->mysql_convert && $same_db)
0505          {
0506              $src_db->sql_query("SET NAMES 'utf8'");
0507          }
0508   
0509          // If there is a user id 1, we need to increment user ids. :/
0510          if ($id === 1)
0511          {
0512              $config->set('increment_user_id', ($max_id + 1), false);
0513              $config['increment_user_id'] = $max_id + 1;
0514          }
0515          else
0516          {
0517              $config->set('increment_user_id', 0, false);
0518              $config['increment_user_id'] = 0;
0519          }
0520      }
0521   
0522      // If the old user id is -1 in 2.0.x it is the anonymous user...
0523      if ($user_id == -1)
0524      {
0525          return ANONYMOUS;
0526      }
0527   
0528      if (!empty($config['increment_user_id']) && $user_id == 1)
0529      {
0530          return $config['increment_user_id'];
0531      }
0532   
0533      // A user id of 0 can happen, for example within the ban table if no user is banned...
0534      // Within the posts and topics table this can be "dangerous" but is the fault of the user
0535      // having mods installed (a poster id of 0 is not possible in 2.0.x).
0536      // Therefore, we return the user id "as is".
0537   
0538      return (int) $user_id;
0539  }
0540   
0541  /**
0542  * Return correct user id value
0543  * Everyone's id will be one higher to allow the guest/anonymous user to have a positive id as well
0544  */
0545  function phpbb_topic_replies_to_posts($num_replies)
0546  {
0547      return (int) $num_replies + 1;
0548  }
0549   
0550  /* Copy additional table fields from old forum to new forum if user wants this (for Mod compatibility for example)
0551  function phpbb_copy_table_fields()
0552  {
0553  }
0554  */
0555   
0556  /**
0557  * Convert authentication
0558  * user, group and forum table has to be filled in order to work
0559  */
0560  function phpbb_convert_authentication($mode)
0561  {
0562      global $db, $src_db, $same_db, $convert, $config;
0563   
0564      if ($mode == 'start')
0565      {
0566          $db->sql_query($convert->truncate_statement . ACL_USERS_TABLE);
0567          $db->sql_query($convert->truncate_statement . ACL_GROUPS_TABLE);
0568   
0569          // What we will do is handling all 2.0.x admins as founder to replicate what is common in 2.0.x.
0570          // After conversion the main admin need to make sure he is removing permissions and the founder status if wanted.
0571   
0572          // Grab user ids of users with user_level of ADMIN
0573          $sql = "SELECT user_id
0574              FROM {$convert->src_table_prefix}users
0575              WHERE user_level = 1
0576              ORDER BY user_regdate ASC";
0577          $result = $src_db->sql_query($sql);
0578   
0579          while ($row = $src_db->sql_fetchrow($result))
0580          {
0581              $user_id = (int) phpbb_user_id($row['user_id']);
0582              // Set founder admin...
0583              $sql = 'UPDATE ' . USERS_TABLE . '
0584                  SET user_type = ' . USER_FOUNDER . "
0585                  WHERE user_id = $user_id";
0586              $db->sql_query($sql);
0587          }
0588          $src_db->sql_freeresult($result);
0589   
0590          $sql = 'SELECT group_id
0591              FROM ' . GROUPS_TABLE . "
0592              WHERE group_name = '" . $db->sql_escape('BOTS') . "'";
0593          $result = $db->sql_query($sql);
0594          $bot_group_id = (int) $db->sql_fetchfield('group_id');
0595          $db->sql_freeresult($result);
0596      }
0597   
0598      // Grab forum auth information
0599      $sql = "SELECT *
0600          FROM {$convert->src_table_prefix}forums";
0601      $result = $src_db->sql_query($sql);
0602   
0603      $forum_access = array();
0604      while ($row = $src_db->sql_fetchrow($result))
0605      {
0606          $forum_access[$row['forum_id']] = $row;
0607      }
0608      $src_db->sql_freeresult($result);
0609   
0610      if ($convert->mysql_convert && $same_db)
0611      {
0612          $src_db->sql_query("SET NAMES 'binary'");
0613      }
0614      // Grab user auth information from 2.0.x board
0615      $sql = "SELECT ug.user_id, aa.*
0616          FROM {$convert->src_table_prefix}auth_access aa, {$convert->src_table_prefix}user_group ug, {$convert->src_table_prefix}groups g, {$convert->src_table_prefix}forums f
0617          WHERE g.group_id = aa.group_id
0618              AND g.group_single_user = 1
0619              AND ug.group_id = g.group_id
0620              AND f.forum_id = aa.forum_id";
0621      $result = $src_db->sql_query($sql);
0622   
0623      $user_access = array();
0624      while ($row = $src_db->sql_fetchrow($result))
0625      {
0626          $user_access[$row['forum_id']][] = $row;
0627      }
0628      $src_db->sql_freeresult($result);
0629   
0630      // Grab group auth information
0631      $sql = "SELECT g.group_id, aa.*
0632          FROM {$convert->src_table_prefix}auth_access aa, {$convert->src_table_prefix}groups g
0633          WHERE g.group_id = aa.group_id
0634              AND g.group_single_user <> 1";
0635      $result = $src_db->sql_query($sql);
0636   
0637      $group_access = array();
0638      while ($row = $src_db->sql_fetchrow($result))
0639      {
0640          $group_access[$row['forum_id']][] = $row;
0641      }
0642      $src_db->sql_freeresult($result);
0643   
0644      if ($convert->mysql_convert && $same_db)
0645      {
0646          $src_db->sql_query("SET NAMES 'utf8'");
0647      }
0648   
0649      // Add Forum Access List
0650      $auth_map = array(
0651          'auth_view'            => array('f_', 'f_list'),
0652          'auth_read'            => array('f_read', 'f_search'),
0653          'auth_post'            => array('f_post', 'f_bbcode', 'f_smilies', 'f_img', 'f_sigs', 'f_postcount', 'f_report', 'f_subscribe', 'f_print', 'f_email'),
0654          'auth_reply'        => 'f_reply',
0655          'auth_edit'            => 'f_edit',
0656          'auth_delete'        => 'f_delete',
0657          'auth_pollcreate'    => 'f_poll',
0658          'auth_vote'            => 'f_vote',
0659          'auth_announce'        => array('f_announce', 'f_announce_global'),
0660          'auth_sticky'        => 'f_sticky',
0661          'auth_attachments'    => array('f_attach', 'f_download'),
0662          'auth_download'        => 'f_download',
0663      );
0664   
0665      // Define the ACL constants used in 2.0 to make the code slightly more readable
0666      define('AUTH_ALL', 0);
0667      define('AUTH_REG', 1);
0668      define('AUTH_ACL', 2);
0669      define('AUTH_MOD', 3);
0670      define('AUTH_ADMIN', 5);
0671   
0672      // A mapping of the simple permissions used by 2.0
0673      $simple_auth_ary = array(
0674          'public'            => array(
0675              'auth_view'            => AUTH_ALL,
0676              'auth_read'            => AUTH_ALL,
0677              'auth_post'            => AUTH_ALL,
0678              'auth_reply'        => AUTH_ALL,
0679              'auth_edit'            => AUTH_REG,
0680              'auth_delete'        => AUTH_REG,
0681              'auth_sticky'        => AUTH_MOD,
0682              'auth_announce'        => AUTH_MOD,
0683              'auth_vote'            => AUTH_REG,
0684              'auth_pollcreate'    => AUTH_REG,
0685          ),
0686          'registered'        => array(
0687              'auth_view'            => AUTH_ALL,
0688              'auth_read'            => AUTH_ALL,
0689              'auth_post'            => AUTH_REG,
0690              'auth_reply'        => AUTH_REG,
0691              'auth_edit'            => AUTH_REG,
0692              'auth_delete'        => AUTH_REG,
0693              'auth_sticky'        => AUTH_MOD,
0694              'auth_announce'        => AUTH_MOD,
0695              'auth_vote'            => AUTH_REG,
0696              'auth_pollcreate'    => AUTH_REG,
0697          ),
0698          'registered_hidden'    => array(
0699              'auth_view'            => AUTH_REG,
0700              'auth_read'            => AUTH_REG,
0701              'auth_post'            => AUTH_REG,
0702              'auth_reply'        => AUTH_REG,
0703              'auth_edit'            => AUTH_REG,
0704              'auth_delete'        => AUTH_REG,
0705              'auth_sticky'        => AUTH_MOD,
0706              'auth_announce'        => AUTH_MOD,
0707              'auth_vote'            => AUTH_REG,
0708              'auth_pollcreate'    => AUTH_REG,
0709          ),
0710          'private'            => array(
0711              'auth_view'            => AUTH_ALL,
0712              'auth_read'            => AUTH_ACL,
0713              'auth_post'            => AUTH_ACL,
0714              'auth_reply'        => AUTH_ACL,
0715              'auth_edit'            => AUTH_ACL,
0716              'auth_delete'        => AUTH_ACL,
0717              'auth_sticky'        => AUTH_ACL,
0718              'auth_announce'        => AUTH_MOD,
0719              'auth_vote'            => AUTH_ACL,
0720              'auth_pollcreate'    => AUTH_ACL,
0721          ),
0722          'private_hidden'    => array(
0723              'auth_view'            => AUTH_ACL,
0724              'auth_read'            => AUTH_ACL,
0725              'auth_post'            => AUTH_ACL,
0726              'auth_reply'        => AUTH_ACL,
0727              'auth_edit'            => AUTH_ACL,
0728              'auth_delete'        => AUTH_ACL,
0729              'auth_sticky'        => AUTH_ACL,
0730              'auth_announce'        => AUTH_MOD,
0731              'auth_vote'            => AUTH_ACL,
0732              'auth_pollcreate'    => AUTH_ACL,
0733          ),
0734          'moderator'            => array(
0735              'auth_view'            => AUTH_ALL,
0736              'auth_read'            => AUTH_MOD,
0737              'auth_post'            => AUTH_MOD,
0738              'auth_reply'        => AUTH_MOD,
0739              'auth_edit'            => AUTH_MOD,
0740              'auth_delete'        => AUTH_MOD,
0741              'auth_sticky'        => AUTH_MOD,
0742              'auth_announce'        => AUTH_MOD,
0743              'auth_vote'            => AUTH_MOD,
0744              'auth_pollcreate'    => AUTH_MOD,
0745          ),
0746          'moderator_hidden'    => array(
0747              'auth_view'            => AUTH_MOD,
0748              'auth_read'            => AUTH_MOD,
0749              'auth_post'            => AUTH_MOD,
0750              'auth_reply'        => AUTH_MOD,
0751              'auth_edit'            => AUTH_MOD,
0752              'auth_delete'        => AUTH_MOD,
0753              'auth_sticky'        => AUTH_MOD,
0754              'auth_announce'        => AUTH_MOD,
0755              'auth_vote'            => AUTH_MOD,
0756              'auth_pollcreate'    => AUTH_MOD,
0757          ),
0758      );
0759   
0760      if ($mode == 'start')
0761      {
0762          user_group_auth('guests', 'SELECT user_id, {GUESTS} FROM ' . USERS_TABLE . ' WHERE user_id = ' . ANONYMOUS, false);
0763          user_group_auth('registered', 'SELECT user_id, {REGISTERED} FROM ' . USERS_TABLE . ' WHERE user_id <> ' . ANONYMOUS . " AND group_id <> $bot_group_id", false);
0764   
0765          // Selecting from old table
0766          if (!empty($config['increment_user_id']))
0767          {
0768              $auth_sql = 'SELECT user_id, {ADMINISTRATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1 AND user_id <> 1';
0769              user_group_auth('administrators', $auth_sql, true);
0770   
0771              $auth_sql = 'SELECT ' . $config['increment_user_id'] . ' as user_id, {ADMINISTRATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1 AND user_id = 1';
0772              user_group_auth('administrators', $auth_sql, true);
0773          }
0774          else
0775          {
0776              $auth_sql = 'SELECT user_id, {ADMINISTRATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1';
0777              user_group_auth('administrators', $auth_sql, true);
0778          }
0779   
0780          if (!empty($config['increment_user_id']))
0781          {
0782              $auth_sql = 'SELECT user_id, {GLOBAL_MODERATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1 AND user_id <> 1';
0783              user_group_auth('global_moderators', $auth_sql, true);
0784   
0785              $auth_sql = 'SELECT ' . $config['increment_user_id'] . ' as user_id, {GLOBAL_MODERATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1 AND user_id = 1';
0786              user_group_auth('global_moderators', $auth_sql, true);
0787          }
0788          else
0789          {
0790              $auth_sql = 'SELECT user_id, {GLOBAL_MODERATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1';
0791              user_group_auth('global_moderators', $auth_sql, true);
0792          }
0793      }
0794      else if ($mode == 'first')
0795      {
0796          // Go through all 2.0.x forums
0797          foreach ($forum_access as $forum)
0798          {
0799              $new_forum_id = (int) $forum['forum_id'];
0800   
0801              // Administrators have full access to all forums whatever happens
0802              mass_auth('group_role', $new_forum_id, 'administrators', 'FORUM_FULL');
0803   
0804              $matched_type = '';
0805              foreach ($simple_auth_ary as $key => $auth_levels)
0806              {
0807                  $matched = 1;
0808                  foreach ($auth_levels as $k => $level)
0809                  {
0810                      if ($forum[$k] != $auth_levels[$k])
0811                      {
0812                          $matched = 0;
0813                      }
0814                  }
0815   
0816                  if ($matched)
0817                  {
0818                      $matched_type = $key;
0819                      break;
0820                  }
0821              }
0822   
0823              switch ($matched_type)
0824              {
0825                  case 'public':
0826                      mass_auth('group_role', $new_forum_id, 'guests', 'FORUM_LIMITED');
0827                      mass_auth('group_role', $new_forum_id, 'registered', 'FORUM_LIMITED_POLLS');
0828                      mass_auth('group_role', $new_forum_id, 'bots', 'FORUM_BOT');
0829                  break;
0830   
0831                  case 'registered':
0832                      mass_auth('group_role', $new_forum_id, 'guests', 'FORUM_READONLY');
0833                      mass_auth('group_role', $new_forum_id, 'bots', 'FORUM_BOT');
0834   
0835                  // no break;
0836   
0837                  case 'registered_hidden':
0838                      mass_auth('group_role', $new_forum_id, 'registered', 'FORUM_POLLS');
0839                  break;
0840   
0841                  case 'private':
0842                  case 'private_hidden':
0843                  case 'moderator':
0844                  case 'moderator_hidden':
0845                  default:
0846                      // The permissions don't match a simple set, so we're going to have to map them directly
0847   
0848                      // No post approval for all, in 2.0.x this feature does not exist
0849                      mass_auth('group', $new_forum_id, 'guests', 'f_noapprove', ACL_YES);
0850                      mass_auth('group', $new_forum_id, 'registered', 'f_noapprove', ACL_YES);
0851   
0852                      // Go through authentication map
0853                      foreach ($auth_map as $old_auth_key => $new_acl)
0854                      {
0855                          // If old authentication key does not exist we continue
0856                          // This is helpful for mods adding additional authentication fields, we need to add them to the auth_map array
0857                          if (!isset($forum[$old_auth_key]))
0858                          {
0859                              continue;
0860                          }
0861   
0862                          // Now set the new ACL correctly
0863                          switch ($forum[$old_auth_key])
0864                          {
0865                              // AUTH_ALL
0866                              case AUTH_ALL:
0867                                  mass_auth('group', $new_forum_id, 'guests', $new_acl, ACL_YES);
0868                                  mass_auth('group', $new_forum_id, 'bots', $new_acl, ACL_YES);
0869                                  mass_auth('group', $new_forum_id, 'registered', $new_acl, ACL_YES);
0870                              break;
0871   
0872                              // AUTH_REG
0873                              case AUTH_REG:
0874                                  mass_auth('group', $new_forum_id, 'registered', $new_acl, ACL_YES);
0875                              break;
0876   
0877                              // AUTH_ACL
0878                              case AUTH_ACL:
0879                                  // Go through the old group access list for this forum
0880                                  if (isset($group_access[$forum['forum_id']]))
0881                                  {
0882                                      foreach ($group_access[$forum['forum_id']] as $index => $access)
0883                                      {
0884                                          // We only check for ACL_YES equivalence entry
0885                                          if (isset($access[$old_auth_key]) && $access[$old_auth_key] == 1)
0886                                          {
0887                                              mass_auth('group', $new_forum_id, (int) $access['group_id'], $new_acl, ACL_YES);
0888                                          }
0889                                      }
0890                                  }
0891   
0892                                  if (isset($user_access[$forum['forum_id']]))
0893                                  {
0894                                      foreach ($user_access[$forum['forum_id']] as $index => $access)
0895                                      {
0896                                          // We only check for ACL_YES equivalence entry
0897                                          if (isset($access[$old_auth_key]) && $access[$old_auth_key] == 1)
0898                                          {
0899                                              mass_auth('user', $new_forum_id, (int) phpbb_user_id($access['user_id']), $new_acl, ACL_YES);
0900                                          }
0901                                      }
0902                                  }
0903                              break;
0904   
0905                              // AUTH_MOD
0906                              case AUTH_MOD:
0907                                  if (isset($group_access[$forum['forum_id']]))
0908                                  {
0909                                      foreach ($group_access[$forum['forum_id']] as $index => $access)
0910                                      {
0911                                          // We only check for ACL_YES equivalence entry
0912                                          if (isset($access[$old_auth_key]) && $access[$old_auth_key] == 1)
0913                                          {
0914                                              mass_auth('group', $new_forum_id, (int) $access['group_id'], $new_acl, ACL_YES);
0915                                          }
0916                                      }
0917                                  }
0918   
0919                                  if (isset($user_access[$forum['forum_id']]))
0920                                  {
0921                                      foreach ($user_access[$forum['forum_id']] as $index => $access)
0922                                      {
0923                                          // We only check for ACL_YES equivalence entry
0924                                          if (isset($access[$old_auth_key]) && $access[$old_auth_key] == 1)
0925                                          {
0926                                              mass_auth('user', $new_forum_id, (int) phpbb_user_id($access['user_id']), $new_acl, ACL_YES);
0927                                          }
0928                                      }
0929                                  }
0930                              break;
0931                          }
0932                      }
0933                  break;
0934              }
0935          }
0936      }
0937      else if ($mode == 'second')
0938      {
0939          // Assign permission roles and other default permissions
0940   
0941          // guests having u_download and u_search ability
0942          $db->sql_query('INSERT INTO ' . ACL_GROUPS_TABLE . ' (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) SELECT ' . get_group_id('guests') . ', 0, auth_option_id, 0, 1 FROM ' . ACL_OPTIONS_TABLE . " WHERE auth_option IN ('u_', 'u_download', 'u_search')");
0943   
0944          // administrators/global mods having full user features
0945          mass_auth('group_role', 0, 'administrators', 'USER_FULL');
0946          mass_auth('group_role', 0, 'global_moderators', 'USER_FULL');
0947   
0948          // By default all converted administrators are given full access
0949          mass_auth('group_role', 0, 'administrators', 'ADMIN_FULL');
0950   
0951          // All registered users are assigned the standard user role
0952          mass_auth('group_role', 0, 'registered', 'USER_STANDARD');
0953          mass_auth('group_role', 0, 'registered_coppa', 'USER_STANDARD');
0954   
0955          // Instead of administrators being global moderators we give the MOD_FULL role to global mods (admins already assigned to this group)
0956          mass_auth('group_role', 0, 'global_moderators', 'MOD_FULL');
0957   
0958          // And now those who have had their avatar rights removed get assigned a more restrictive role
0959          $sql = 'SELECT user_id FROM ' . $convert->src_table_prefix . 'users
0960              WHERE user_allowavatar = 0
0961                  AND user_id > 0';
0962          $result = $src_db->sql_query($sql);
0963   
0964          while ($row = $src_db->sql_fetchrow($result))
0965          {
0966              mass_auth('user_role', 0, (int) phpbb_user_id($row['user_id']), 'USER_NOAVATAR');
0967          }
0968          $src_db->sql_freeresult($result);
0969   
0970          // And the same for those who have had their PM rights removed
0971          $sql = 'SELECT user_id FROM ' . $convert->src_table_prefix . 'users
0972              WHERE user_allow_pm = 0
0973                  AND user_id > 0';
0974          $result = $src_db->sql_query($sql);
0975   
0976          while ($row = $src_db->sql_fetchrow($result))
0977          {
0978              mass_auth('user_role', 0, (int) phpbb_user_id($row['user_id']), 'USER_NOPM');
0979          }
0980          $src_db->sql_freeresult($result);
0981      }
0982      else if ($mode == 'third')
0983      {
0984          // And now the moderators
0985          // We make sure that they have at least standard access to the forums they moderate in addition to the moderating permissions
0986   
0987          $mod_post_map = array(
0988              'auth_announce'        => array('f_announce', 'f_announce_global'),
0989              'auth_sticky'        => 'f_sticky'
0990          );
0991   
0992          foreach ($user_access as $forum_id => $access_map)
0993          {
0994              $forum_id = (int) $forum_id;
0995   
0996              foreach ($access_map as $access)
0997              {
0998                  if (isset($access['auth_mod']) && $access['auth_mod'] == 1)
0999                  {
1000                      mass_auth('user_role', $forum_id, (int) phpbb_user_id($access['user_id']), 'MOD_STANDARD');
1001                      mass_auth('user_role', $forum_id, (int) phpbb_user_id($access['user_id']), 'FORUM_STANDARD');
1002                      foreach ($mod_post_map as $old => $new)
1003                      {
1004                          if (isset($forum_access[$forum_id]) && isset($forum_access[$forum_id][$old]) && $forum_access[$forum_id][$old] == AUTH_MOD)
1005                          {
1006                              mass_auth('user', $forum_id, (int) phpbb_user_id($access['user_id']), $new, ACL_YES);
1007                          }
1008                      }
1009                  }
1010              }
1011          }
1012   
1013          foreach ($group_access as $forum_id => $access_map)
1014          {
1015              $forum_id = (int) $forum_id;
1016   
1017              foreach ($access_map as $access)
1018              {
1019                  if (isset($access['auth_mod']) && $access['auth_mod'] == 1)
1020                  {
1021                      mass_auth('group_role', $forum_id, (int) $access['group_id'], 'MOD_STANDARD');
1022                      mass_auth('group_role', $forum_id, (int) $access['group_id'], 'FORUM_STANDARD');
1023                      foreach ($mod_post_map as $old => $new)
1024                      {
1025                          if (isset($forum_access[$forum_id]) && isset($forum_access[$forum_id][$old]) && $forum_access[$forum_id][$old] == AUTH_MOD)
1026                          {
1027                              mass_auth('group', $forum_id, (int) $access['group_id'], $new, ACL_YES);
1028                          }
1029                      }
1030                  }
1031              }
1032          }
1033   
1034          // We grant everyone readonly access to the categories to ensure that the forums are visible
1035          $sql = 'SELECT forum_id, forum_name, parent_id, left_id, right_id
1036              FROM ' . FORUMS_TABLE . '
1037              ORDER BY left_id ASC';
1038          $result = $db->sql_query($sql);
1039   
1040          $parent_forums = $forums = array();
1041          while ($row = $db->sql_fetchrow($result))
1042          {
1043              if ($row['parent_id'] == 0)
1044              {
1045                  mass_auth('group_role', $row['forum_id'], 'administrators', 'FORUM_FULL');
1046                  mass_auth('group_role', $row['forum_id'], 'global_moderators', 'FORUM_FULL');
1047                  $parent_forums[] = $row;
1048              }
1049              else
1050              {
1051                  $forums[] = $row;
1052              }
1053          }
1054          $db->sql_freeresult($result);
1055   
1056          global $auth;
1057   
1058          // Let us see which groups have access to these forums...
1059          foreach ($parent_forums as $row)
1060          {
1061              // Get the children
1062              $branch = $forum_ids = array();
1063   
1064              foreach ($forums as $key => $_row)
1065              {
1066                  if ($_row['left_id'] > $row['left_id'] && $_row['left_id'] < $row['right_id'])
1067                  {
1068                      $branch[] = $_row;
1069                      $forum_ids[] = $_row['forum_id'];
1070                      continue;
1071                  }
1072              }
1073   
1074              if (count($forum_ids))
1075              {
1076                  // Now make sure the user is able to read these forums
1077                  $hold_ary = $auth->acl_group_raw_data(false, 'f_list', $forum_ids);
1078   
1079                  if (empty($hold_ary))
1080                  {
1081                      continue;
1082                  }
1083   
1084                  foreach ($hold_ary as $g_id => $f_id_ary)
1085                  {
1086                      $set_group = false;
1087   
1088                      foreach ($f_id_ary as $f_id => $auth_ary)
1089                      {
1090                          foreach ($auth_ary as $auth_option => $setting)
1091                          {
1092                              if ($setting == ACL_YES)
1093                              {
1094                                  $set_group = true;
1095                                  break 2;
1096                              }
1097                          }
1098                      }
1099   
1100                      if ($set_group)
1101                      {
1102                          mass_auth('group', $row['forum_id'], $g_id, 'f_list', ACL_YES);
1103                      }
1104                  }
1105              }
1106          }
1107      }
1108  }
1109   
1110  /**
1111  * Set primary group.
1112  * Really simple and only based on user_level (remaining groups will be assigned later)
1113  */
1114  function phpbb_set_primary_group($user_level)
1115  {
1116      global $convert_row;
1117   
1118      if ($user_level == 1)
1119      {
1120          return get_group_id('administrators');
1121      }
1122  /*    else if ($user_level == 2)
1123      {
1124          return get_group_id('global_moderators');
1125      }
1126      else if ($user_level == 0 && $convert_row['user_active'])*/
1127      else if ($convert_row['user_active'])
1128      {
1129          return get_group_id('registered');
1130      }
1131   
1132      return 0;
1133  }
1134   
1135  /**
1136  * Convert the group name, making sure to avoid conflicts with 3.0 special groups
1137  */
1138  function phpbb_convert_group_name($group_name)
1139  {
1140      $default_groups = array(
1141          'GUESTS',
1142          'REGISTERED',
1143          'REGISTERED_COPPA',
1144          'GLOBAL_MODERATORS',
1145          'ADMINISTRATORS',
1146          'BOTS',
1147      );
1148   
1149      if (in_array(strtoupper($group_name), $default_groups))
1150      {
1151          return 'phpBB2 - ' . $group_name;
1152      }
1153   
1154      return phpbb_set_default_encoding($group_name);
1155  }
1156   
1157  /**
1158  * Convert the group type constants
1159  */
1160  function phpbb_convert_group_type($group_type)
1161  {
1162      switch ($group_type)
1163      {
1164          case 0:
1165              return GROUP_OPEN;
1166          break;
1167   
1168          case 1:
1169              return GROUP_CLOSED;
1170          break;
1171   
1172          case 2:
1173              return GROUP_HIDDEN;
1174          break;
1175      }
1176   
1177      // Never return GROUP_SPECIAL here, because only phpBB3's default groups are allowed to have this type set.
1178      return GROUP_HIDDEN;
1179  }
1180   
1181  /**
1182  * Convert the topic type constants
1183  */
1184  function phpbb_convert_topic_type($topic_type)
1185  {
1186      switch ($topic_type)
1187      {
1188          case 0:
1189              return POST_NORMAL;
1190          break;
1191   
1192          case 1:
1193              return POST_STICKY;
1194          break;
1195   
1196          case 2:
1197              return POST_ANNOUNCE;
1198          break;
1199   
1200          case 3:
1201              return POST_GLOBAL;
1202          break;
1203      }
1204   
1205      return POST_NORMAL;
1206  }
1207   
1208  function phpbb_replace_size($matches)
1209  {
1210      return '[size=' . min(200, ceil(100.0 * (((double) $matches[1])/12.0))) . ':' . $matches[2] . ']';
1211  }
1212   
1213  /**
1214  * Reparse the message stripping out the bbcode_uid values and adding new ones and setting the bitfield
1215  * @todo What do we want to do about HTML in messages - currently it gets converted to the entities, but there may be some objections to this
1216  */
1217  function phpbb_prepare_message($message)
1218  {
1219      global $convert, $user, $convert_row, $message_parser;
1220   
1221      if (!$message)
1222      {
1223          $convert->row['mp_bbcode_bitfield'] = $convert_row['mp_bbcode_bitfield'] = 0;
1224          return '';
1225      }
1226   
1227      // Decode phpBB 2.0.x Message
1228      if (isset($convert->row['old_bbcode_uid']) && $convert->row['old_bbcode_uid'] != '')
1229      {
1230          // Adjust size...
1231          if (strpos($message, '[size=') !== false)
1232          {
1233              $message = preg_replace_callback('/\[size=(\d*):(' . $convert->row['old_bbcode_uid'] . ')\]/', 'phpbb_replace_size', $message);
1234          }
1235   
1236          $message = preg_replace('/\:(([a-z0-9]:)?)' . $convert->row['old_bbcode_uid'] . '/s', '', $message);
1237      }
1238   
1239      if (strpos($message, '[quote=') !== false)
1240      {
1241          $message = preg_replace('/\[quote="(.*?)"\]/s', '[quote=&quot;\1&quot;]', $message);
1242          $message = preg_replace('/\[quote=\\\"(.*?)\\\"\]/s', '[quote=&quot;\1&quot;]', $message);
1243   
1244          // let's hope that this solves more problems than it causes. Deal with escaped quotes.
1245          $message = str_replace('\"', '&quot;', $message);
1246          $message = str_replace('\&quot;', '&quot;', $message);
1247      }
1248   
1249      $message = str_replace('<br />', "\n", $message);
1250      $message = str_replace('<', '&lt;', $message);
1251      $message = str_replace('>', '&gt;', $message);
1252   
1253      // make the post UTF-8
1254      $message = phpbb_set_encoding($message);
1255   
1256      $message_parser->warn_msg = array(); // Reset the errors from the previous message
1257      $message_parser->bbcode_uid = make_uid($convert->row['post_time']);
1258      $message_parser->message = $message;
1259      unset($message);
1260   
1261      // Make sure options are set.
1262  //    $enable_html = (!isset($row['enable_html'])) ? false : $row['enable_html'];
1263      $enable_bbcode = (!isset($convert->row['enable_bbcode'])) ? true : $convert->row['enable_bbcode'];
1264      $enable_smilies = (!isset($convert->row['enable_smilies'])) ? true : $convert->row['enable_smilies'];
1265      $enable_magic_url = (!isset($convert->row['enable_magic_url'])) ? true : $convert->row['enable_magic_url'];
1266   
1267      // 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')
1268      $message_parser->parse($enable_bbcode, $enable_magic_url, $enable_smilies);
1269   
1270      if (count($message_parser->warn_msg))
1271      {
1272          $msg_id = isset($convert->row['post_id']) ? $convert->row['post_id'] : $convert->row['privmsgs_id'];
1273          $convert->p_master->error('<span style="color:red">' . $user->lang['POST_ID'] . ': ' . $msg_id . ' ' . $user->lang['CONV_ERROR_MESSAGE_PARSER'] . ': <br /><br />' . implode('<br />', $message_parser->warn_msg), __LINE__, __FILE__, true);
1274      }
1275   
1276      $convert->row['mp_bbcode_bitfield'] = $convert_row['mp_bbcode_bitfield'] = $message_parser->bbcode_bitfield;
1277   
1278      $message = $message_parser->message;
1279      unset($message_parser->message);
1280   
1281      return $message;
1282  }
1283   
1284  /**
1285  * Return the bitfield calculated by the previous function
1286  */
1287  function get_bbcode_bitfield()
1288  {
1289      global $convert_row;
1290   
1291      return $convert_row['mp_bbcode_bitfield'];
1292  }
1293   
1294  /**
1295  * Determine the last user to edit a post
1296  * In practice we only tracked edits by the original poster in 2.0.x so this will only be set if they had edited their own post
1297  */
1298  function phpbb_post_edit_user()
1299  {
1300      global $convert_row;
1301   
1302      if (isset($convert_row['post_edit_count']))
1303      {
1304          return phpbb_user_id($convert_row['poster_id']);
1305      }
1306   
1307      return 0;
1308  }
1309   
1310  /**
1311  * Obtain the path to uploaded files on the 2.0.x forum
1312  * This is only used if the Attachment MOD was installed
1313  */
1314  function phpbb_get_files_dir()
1315  {
1316      if (!defined('MOD_ATTACHMENT'))
1317      {
1318          return;
1319      }
1320   
1321      global $src_db, $same_db, $convert, $user;
1322   
1323      if ($convert->mysql_convert && $same_db)
1324      {
1325          $src_db->sql_query("SET NAMES 'binary'");
1326      }
1327      $sql = 'SELECT config_value AS upload_dir
1328          FROM ' . $convert->src_table_prefix . "attachments_config
1329          WHERE config_name = 'upload_dir'";
1330      $result = $src_db->sql_query($sql);
1331      $upload_path = $src_db->sql_fetchfield('upload_dir');
1332      $src_db->sql_freeresult($result);
1333   
1334      $sql = 'SELECT config_value AS ftp_upload
1335          FROM ' . $convert->src_table_prefix . "attachments_config
1336          WHERE config_name = 'allow_ftp_upload'";
1337      $result = $src_db->sql_query($sql);
1338      $ftp_upload = (int) $src_db->sql_fetchfield('ftp_upload');
1339      $src_db->sql_freeresult($result);
1340   
1341      if ($convert->mysql_convert && $same_db)
1342      {
1343          $src_db->sql_query("SET NAMES 'utf8'");
1344      }
1345   
1346      if ($ftp_upload)
1347      {
1348          $convert->p_master->error($user->lang['CONV_ERROR_ATTACH_FTP_DIR'], __LINE__, __FILE__);
1349      }
1350   
1351      return $upload_path;
1352  }
1353   
1354  /**
1355  * Copy thumbnails of uploaded images from the 2.0.x forum
1356  * This is only used if the Attachment MOD was installed
1357  */
1358  function phpbb_copy_thumbnails()
1359  {
1360      global $convert, $config, $phpbb_root_path;
1361   
1362      $src_path = $convert->options['forum_path'] . '/' . phpbb_get_files_dir() . '/thumbs/';
1363   
1364      if ($handle = @opendir($src_path))
1365      {
1366          while ($entry = readdir($handle))
1367          {
1368              if ($entry[0] == '.')
1369              {
1370                  continue;
1371              }
1372   
1373              if (is_dir($src_path . $entry))
1374              {
1375                  continue;
1376              }
1377              else
1378              {
1379                  copy_file($src_path . $entry, $config['upload_path'] . '/' . preg_replace('/^t_/', 'thumb_', $entry));
1380                  @unlink($phpbb_root_path . $config['upload_path'] . '/thumbs/' . $entry);
1381              }
1382          }
1383          closedir($handle);
1384      }
1385  }
1386   
1387  /**
1388  * Convert the attachment category constants
1389  * This is only used if the Attachment MOD was installed
1390  */
1391  function phpbb_attachment_category($cat_id)
1392  {
1393      switch ($cat_id)
1394      {
1395          case 1:
1396              return ATTACHMENT_CATEGORY_IMAGE;
1397          break;
1398   
1399          case 2:
1400              return ATTACHMENT_CATEGORY_WM;
1401          break;
1402      }
1403   
1404      return ATTACHMENT_CATEGORY_NONE;
1405  }
1406   
1407  /**
1408  * Convert the attachment extension names
1409  * This is only used if the Attachment MOD was installed
1410  */
1411  function phpbb_attachment_extension_group_name()
1412  {
1413      global $db, $phpbb_root_path, $phpEx;
1414   
1415      // Update file extension group names to use language strings.
1416      $sql = 'SELECT lang_dir
1417          FROM ' . LANG_TABLE;
1418      $result = $db->sql_query($sql);
1419   
1420      $extension_groups_updated = array();
1421      while ($row = $db->sql_fetchrow($result))
1422      {
1423          $lang_dir = basename($row['lang_dir']);
1424          $lang_file = $phpbb_root_path . 'language/' . $lang_dir . '/acp/attachments.' . $phpEx;
1425   
1426          if (!file_exists($lang_file))
1427          {
1428              continue;
1429          }
1430   
1431          $lang = array();
1432          include($lang_file);
1433   
1434          foreach ($lang as $lang_key => $lang_val)
1435          {
1436              if (isset($extension_groups_updated[$lang_key]) || strpos($lang_key, 'EXT_GROUP_') !== 0)
1437              {
1438                  continue;
1439              }
1440   
1441              $sql_ary = array(
1442                  'group_name'    => substr($lang_key, 10), // Strip off 'EXT_GROUP_'
1443              );
1444   
1445              $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . '
1446                  SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
1447                      WHERE group_name = '" . $db->sql_escape($lang_val) . "'";
1448              $db->sql_query($sql);
1449   
1450              $extension_groups_updated[$lang_key] = true;
1451          }
1452      }
1453      $db->sql_freeresult($result);
1454  }
1455   
1456  /**
1457  * Obtain list of forums in which different attachment categories can be used
1458  */
1459  function phpbb_attachment_forum_perms($forum_permissions)
1460  {
1461      if (empty($forum_permissions))
1462      {
1463          return '';
1464      }
1465   
1466      // Decode forum permissions
1467      $forum_ids = array();
1468   
1469      $one_char_encoding = '#';
1470      $two_char_encoding = '.';
1471   
1472      $auth_len = 1;
1473      for ($pos = 0; $pos < strlen($forum_permissions); $pos += $auth_len)
1474      {
1475          $forum_auth = substr($forum_permissions, $pos, 1);
1476          if ($forum_auth == $one_char_encoding)
1477          {
1478              $auth_len = 1;
1479              continue;
1480          }
1481          else if ($forum_auth == $two_char_encoding)
1482          {
1483              $auth_len = 2;
1484              $pos--;
1485              continue;
1486          }
1487   
1488          $forum_auth = substr($forum_permissions, $pos, $auth_len);
1489          $forum_id = base64_unpack($forum_auth);
1490   
1491          $forum_ids[] = (int) $forum_id;
1492      }
1493   
1494      if (count($forum_ids))
1495      {
1496          return attachment_forum_perms($forum_ids);
1497      }
1498   
1499      return '';
1500  }
1501   
1502  /**
1503  * Convert the avatar type constants
1504  */
1505  function phpbb_avatar_type($type)
1506  {
1507      switch ($type)
1508      {
1509          case 1:
1510              return AVATAR_UPLOAD;
1511          break;
1512   
1513          case 2:
1514              return AVATAR_REMOTE;
1515          break;
1516   
1517          case 3:
1518              return AVATAR_GALLERY;
1519          break;
1520      }
1521   
1522      return 0;
1523  }
1524   
1525   
1526  /**
1527  * Just undos the replacing of '<' and '>'
1528  */
1529  function  phpbb_smilie_html_decode($code)
1530  {
1531      $code = str_replace('&lt;', '<', $code);
1532      return str_replace('&gt;', '>', $code);
1533  }
1534   
1535  /**
1536  * Transfer avatars, copying the image if it was uploaded
1537  */
1538  function phpbb_import_avatar($user_avatar)
1539  {
1540      global $convert_row;
1541   
1542      if (!$convert_row['user_avatar_type'])
1543      {
1544          return '';
1545      }
1546      else if ($convert_row['user_avatar_type'] == 1)
1547      {
1548          // Uploaded avatar
1549          return import_avatar($user_avatar, false, $convert_row['user_id']);
1550      }
1551      else if ($convert_row['user_avatar_type'] == 2)
1552      {
1553          // Remote avatar
1554          return $user_avatar;
1555      }
1556      else if ($convert_row['user_avatar_type'] == 3)
1557      {
1558          // Gallery avatar
1559          return $user_avatar;
1560      }
1561   
1562      return '';
1563  }
1564   
1565   
1566  /**
1567  * Find out about the avatar's dimensions
1568  */
1569  function phpbb_get_avatar_height($user_avatar)
1570  {
1571      global $convert_row;
1572   
1573      if (empty($convert_row['user_avatar_type']))
1574      {
1575          return 0;
1576      }
1577      return get_avatar_height($user_avatar, 'phpbb_avatar_type', $convert_row['user_avatar_type']);
1578  }
1579   
1580   
1581  /**
1582  * Find out about the avatar's dimensions
1583  */
1584  function phpbb_get_avatar_width($user_avatar)
1585  {
1586      global $convert_row;
1587   
1588      if (empty($convert_row['user_avatar_type']))
1589      {
1590          return 0;
1591      }
1592   
1593      return get_avatar_width($user_avatar, 'phpbb_avatar_type', $convert_row['user_avatar_type']);
1594  }
1595   
1596   
1597  /**
1598  * Calculate the correct to_address field for private messages
1599  */
1600  function phpbb_privmsgs_to_userid($to_userid)
1601  {
1602      return 'u_' . phpbb_user_id($to_userid);
1603  }
1604   
1605  /**
1606  * Calculate whether a private message was unread using the bitfield
1607  */
1608  function phpbb_unread_pm($pm_type)
1609  {
1610      return ($pm_type == 5) ? 1 : 0;
1611  }
1612   
1613  /**
1614  * Calculate whether a private message was new using the bitfield
1615  */
1616  function phpbb_new_pm($pm_type)
1617  {
1618      return ($pm_type == 1) ? 1 : 0;
1619  }
1620   
1621  /**
1622  * Obtain the folder_id for the custom folder created to replace the savebox from 2.0.x (used to store saved private messages)
1623  */
1624  function phpbb_get_savebox_id($user_id)
1625  {
1626      global $db;
1627   
1628      $user_id = phpbb_user_id($user_id);
1629   
1630      // Only one custom folder, check only one
1631      $sql = 'SELECT folder_id
1632          FROM ' . PRIVMSGS_FOLDER_TABLE . '
1633          WHERE user_id = ' . $user_id;
1634      $result = $db->sql_query_limit($sql, 1);
1635      $folder_id = (int) $db->sql_fetchfield('folder_id');
1636      $db->sql_freeresult($result);
1637   
1638      return $folder_id;
1639  }
1640   
1641  /**
1642  * Transfer attachment specific configuration options
1643  * These were not stored in the main config table on 2.0.x
1644  * This is only used if the Attachment MOD was installed
1645  */
1646  function phpbb_import_attach_config()
1647  {
1648      global $src_db, $same_db, $convert, $config;
1649   
1650      if ($convert->mysql_convert && $same_db)
1651      {
1652          $src_db->sql_query("SET NAMES 'binary'");
1653      }
1654   
1655      $sql = 'SELECT *
1656          FROM ' . $convert->src_table_prefix . 'attachments_config';
1657      $result = $src_db->sql_query($sql);
1658   
1659      if ($convert->mysql_convert && $same_db)
1660      {
1661          $src_db->sql_query("SET NAMES 'utf8'");
1662      }
1663   
1664      $attach_config = array();
1665      while ($row = $src_db->sql_fetchrow($result))
1666      {
1667          $attach_config[$row['config_name']] = $row['config_value'];
1668      }
1669      $src_db->sql_freeresult($result);
1670   
1671      $config->set('allow_attachments', 1);
1672   
1673      // old attachment mod? Must be very old if this entry do not exist...
1674      if (!empty($attach_config['display_order']))
1675      {
1676          $config->set('display_order', $attach_config['display_order']);
1677      }
1678      $config->set('max_filesize', $attach_config['max_filesize']);
1679      $config->set('max_filesize_pm', $attach_config['max_filesize_pm']);
1680      $config->set('attachment_quota', $attach_config['attachment_quota']);
1681      $config->set('max_attachments', $attach_config['max_attachments']);
1682      $config->set('max_attachments_pm', $attach_config['max_attachments_pm']);
1683      $config->set('allow_pm_attach', $attach_config['allow_pm_attach']);
1684   
1685      $config->set('img_display_inlined', $attach_config['img_display_inlined']);
1686      $config->set('img_max_width', $attach_config['img_max_width']);
1687      $config->set('img_max_height', $attach_config['img_max_height']);
1688      $config->set('img_link_width', $attach_config['img_link_width']);
1689      $config->set('img_link_height', $attach_config['img_link_height']);
1690      $config->set('img_create_thumbnail', $attach_config['img_create_thumbnail']);
1691      $config->set('img_max_thumb_width', 400);
1692      $config->set('img_min_thumb_filesize', $attach_config['img_min_thumb_filesize']);
1693  }
1694   
1695  /**
1696  * Calculate the date a user became inactive
1697  */
1698  function phpbb_inactive_time()
1699  {
1700      global $convert_row;
1701   
1702      if ($convert_row['user_active'])
1703      {
1704          return 0;
1705      }
1706   
1707      if ($convert_row['user_lastvisit'])
1708      {
1709          return $convert_row['user_lastvisit'];
1710      }
1711   
1712      return $convert_row['user_regdate'];
1713  }
1714   
1715  /**
1716  * Calculate the reason a user became inactive
1717  * We can't actually tell the difference between a manual deactivation and one for profile changes
1718  * from the data available to assume the latter
1719  */
1720  function phpbb_inactive_reason()
1721  {
1722      global $convert_row;
1723   
1724      if ($convert_row['user_active'])
1725      {
1726          return 0;
1727      }
1728   
1729      if ($convert_row['user_lastvisit'])
1730      {
1731          return INACTIVE_PROFILE;
1732      }
1733   
1734      return INACTIVE_REGISTER;
1735  }
1736   
1737  /**
1738  * Adjust 2.0.x disallowed names to 3.0.x format
1739  */
1740  function phpbb_disallowed_username($username)
1741  {
1742      // Replace * with %
1743      $username = phpbb_set_default_encoding(str_replace('*', '%', $username));
1744      return utf8_htmlspecialchars($username);
1745  }
1746   
1747  /**
1748  * Checks whether there are any usernames on the old board that would map to the same
1749  * username_clean on phpBB3. Prints out a list if any exist and exits.
1750  */
1751  function phpbb_create_userconv_table()
1752  {
1753      global $db;
1754   
1755      switch ($db->get_sql_layer())
1756      {
1757          case 'mysqli':
1758              $map_dbms = 'mysql_41';
1759          break;
1760   
1761          case 'mssql_odbc':
1762          case 'mssqlnative':
1763              $map_dbms = 'mssql';
1764          break;
1765   
1766          default:
1767              $map_dbms = $db->get_sql_layer();
1768          break;
1769      }
1770   
1771      // create a temporary table in which we store the clean usernames
1772      $drop_sql = 'DROP TABLE ' . USERCONV_TABLE;
1773      switch ($map_dbms)
1774      {
1775          case 'mssql':
1776              $create_sql = 'CREATE TABLE [' . USERCONV_TABLE . '] (
1777                  [user_id] [int] NOT NULL ,
1778                  [username_clean] [varchar] (255) DEFAULT (\'\') NOT NULL
1779              )';
1780          break;
1781   
1782          case 'mysql_41':
1783              $create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' (
1784                  user_id mediumint(8) NOT NULL,
1785                  username_clean varchar(255) DEFAULT \'\' NOT NULL
1786              ) CHARACTER SET `utf8` COLLATE `utf8_bin`';
1787          break;
1788   
1789          case 'oracle':
1790              $create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' (
1791                  user_id number(8) NOT NULL,
1792                  username_clean varchar2(255) DEFAULT \'\'
1793              )';
1794          break;
1795   
1796          case 'postgres':
1797              $create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' (
1798                  user_id INT4 DEFAULT \'0\',
1799                  username_clean varchar_ci DEFAULT \'\' NOT NULL
1800              )';
1801          break;
1802   
1803          case 'sqlite3':
1804              $create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' (
1805                  user_id INTEGER NOT NULL DEFAULT \'0\',
1806                  username_clean varchar(255) NOT NULL DEFAULT \'\'
1807              )';
1808          break;
1809      }
1810   
1811      $db->sql_return_on_error(true);
1812      $db->sql_query($drop_sql);
1813      $db->sql_return_on_error(false);
1814      $db->sql_query($create_sql);
1815  }
1816   
1817  function phpbb_check_username_collisions()
1818  {
1819      global $db, $src_db, $convert, $user, $lang;
1820   
1821      // now find the clean version of the usernames that collide
1822      $sql = 'SELECT username_clean
1823          FROM ' . USERCONV_TABLE .'
1824          GROUP BY username_clean
1825          HAVING COUNT(user_id) > 1';
1826      $result = $db->sql_query($sql);
1827   
1828      $colliding_names = array();
1829      while ($row = $db->sql_fetchrow($result))
1830      {
1831          $colliding_names[] = $row['username_clean'];
1832      }
1833      $db->sql_freeresult($result);
1834   
1835      // there was at least one collision, the admin will have to solve it before conversion can continue
1836      if (count($colliding_names))
1837      {
1838          $sql = 'SELECT user_id, username_clean
1839              FROM ' . USERCONV_TABLE . '
1840              WHERE ' . $db->sql_in_set('username_clean', $colliding_names);
1841          $result = $db->sql_query($sql);
1842          unset($colliding_names);
1843   
1844          $colliding_user_ids = array();
1845          while ($row = $db->sql_fetchrow($result))
1846          {
1847              $colliding_user_ids[(int) $row['user_id']] = $row['username_clean'];
1848          }
1849          $db->sql_freeresult($result);
1850   
1851          $sql = 'SELECT username, user_id, user_posts
1852              FROM ' . $convert->src_table_prefix . 'users
1853              WHERE ' . $src_db->sql_in_set('user_id', array_keys($colliding_user_ids));
1854          $result = $src_db->sql_query($sql);
1855   
1856          $colliding_users = array();
1857          while ($row = $src_db->sql_fetchrow($result))
1858          {
1859              $row['user_id'] = (int) $row['user_id'];
1860              if (isset($colliding_user_ids[$row['user_id']]))
1861              {
1862                  $colliding_users[$colliding_user_ids[$row['user_id']]][] = $row;
1863              }
1864          }
1865          $src_db->sql_freeresult($result);
1866          unset($colliding_user_ids);
1867   
1868          $list = '';
1869          foreach ($colliding_users as $username_clean => $users)
1870          {
1871              $list .= sprintf($user->lang['COLLIDING_CLEAN_USERNAME'], $username_clean) . "<br />\n";
1872              foreach ($users as $i => $row)
1873              {
1874                  $list .= sprintf($user->lang['COLLIDING_USER'], $row['user_id'], phpbb_set_default_encoding($row['username']), $row['user_posts']) . "<br />\n";
1875              }
1876          }
1877   
1878          $lang['INST_ERR_FATAL'] = $user->lang['CONV_ERR_FATAL'];
1879          $convert->p_master->error('<span style="color:red">' . $user->lang['COLLIDING_USERNAMES_FOUND'] . '</span></b><br /><br />' . $list . '<b>', __LINE__, __FILE__);
1880      }
1881   
1882      $drop_sql = 'DROP TABLE ' . USERCONV_TABLE;
1883      $db->sql_query($drop_sql);
1884  }
1885   
1886  function phpbb_convert_timezone($timezone)
1887  {
1888      global $config, $db, $phpbb_root_path, $phpEx, $table_prefix;
1889   
1890      $factory = new \phpbb\db\tools\factory();
1891      $timezone_migration = new \phpbb\db\migration\data\v310\timezone($config, $db, $factory->get($db), $phpbb_root_path, $phpEx, $table_prefix);
1892      return $timezone_migration->convert_phpbb30_timezone($timezone, 0);
1893  }
1894   
1895  function phpbb_add_notification_options($user_notify_pm)
1896  {
1897      global $convert_row, $db;
1898   
1899      $user_id = phpbb_user_id($convert_row['user_id']);
1900      if ($user_id == ANONYMOUS)
1901      {
1902          return;
1903      }
1904   
1905      $rows = array();
1906   
1907      $rows[] = array(
1908          'item_type'        => 'post',
1909          'item_id'        => 0,
1910          'user_id'        => (int) $user_id,
1911          'notify'        => 1,
1912          'method'        => 'email',
1913      );
1914      $rows[] = array(
1915          'item_type'        => 'topic',
1916          'item_id'        => 0,
1917          'user_id'        => (int) $user_id,
1918          'notify'        => 1,
1919          'method'        => 'email',
1920      );
1921      if ($user_notify_pm)
1922      {
1923          $rows[] = array(
1924              'item_type'        => 'pm',
1925              'item_id'        => 0,
1926              'user_id'        => (int) $user_id,
1927              'notify'        => 1,
1928              'method'        => 'email',
1929          );
1930      }
1931   
1932      $db->sql_multi_insert(USER_NOTIFICATIONS_TABLE, $rows);
1933  }
1934   
1935  function phpbb_convert_password_hash($hash)
1936  {
1937      global $phpbb_container;
1938   
1939      /* @var $manager \phpbb\passwords\manager */
1940      $manager = $phpbb_container->get('passwords.manager');
1941      $hash = $manager->hash($hash, '$H$');
1942   
1943      return '$CP$' . $hash;
1944  }
1945