Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

So funktioniert es


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

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

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

functions_phpbb20.php

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