PageRenderTime 59ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/db_update.php

https://github.com/Dratone/EveBB
PHP | 2574 lines | 1841 code | 484 blank | 249 comment | 286 complexity | afa639545f1502687311831e57f3a52d MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * Copyright (C) 2008-2011 FluxBB
  4. * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
  5. * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
  6. */
  7. // The FluxBB version this script updates to
  8. define('UPDATE_TO', '1.4.5');
  9. define('UPDATE_TO_EVEBB', '1.1.14');
  10. define('UPDATE_TO_DB_REVISION', 12);
  11. define('UPDATE_TO_SI_REVISION', 2);
  12. define('UPDATE_TO_PARSER_REVISION', 2);
  13. define('MIN_PHP_VERSION', '4.4.0');
  14. define('MIN_MYSQL_VERSION', '4.1.2');
  15. define('MIN_PGSQL_VERSION', '7.0.0');
  16. define('PUN_SEARCH_MIN_WORD', 3);
  17. define('PUN_SEARCH_MAX_WORD', 20);
  18. // The MySQL connection character set that was used for FluxBB 1.2 - in 99% of cases this should be detected automatically,
  19. // but can be overridden using the below constant if required.
  20. //define('FORUM_DEFAULT_CHARSET', 'latin1');
  21. // The number of items to process per page view (lower this if the update script times out during UTF-8 conversion)
  22. define('PER_PAGE', 300);
  23. // Don't set to UTF-8 until after we've found out what the default character set is
  24. define('FORUM_NO_SET_NAMES', 1);
  25. // Make sure we are running at least MIN_PHP_VERSION
  26. if (!function_exists('version_compare') || version_compare(PHP_VERSION, MIN_PHP_VERSION, '<'))
  27. exit('You are running PHP version '.PHP_VERSION.'. EveBB '.UPDATE_TO.' requires at least PHP '.MIN_PHP_VERSION.' to run properly. You must upgrade your PHP installation before you can continue.');
  28. define('PUN_ROOT', dirname(__FILE__).'/');
  29. // Attempt to load the configuration file config.php
  30. if (file_exists(PUN_ROOT.'config.php'))
  31. include PUN_ROOT.'config.php';
  32. // If we have the 1.3-legacy constant defined, define the proper 1.4 constant so we don't get an incorrect "need to install" message
  33. if (defined('FORUM'))
  34. define('PUN', FORUM);
  35. // If PUN isn't defined, config.php is missing or corrupt
  36. if (!defined('PUN'))
  37. {
  38. header('Location: install.php');
  39. exit;
  40. }
  41. // Enable debug mode
  42. if (!defined('PUN_DEBUG'))
  43. define('PUN_DEBUG', 1);
  44. // Load the functions script
  45. require PUN_ROOT.'include/functions.php';
  46. // Load UTF-8 functions
  47. require PUN_ROOT.'include/utf8/utf8.php';
  48. // Strip out "bad" UTF-8 characters
  49. forum_remove_bad_characters();
  50. // Reverse the effect of register_globals
  51. forum_unregister_globals();
  52. // Turn on full PHP error reporting
  53. error_reporting(E_ALL);
  54. // Force POSIX locale (to prevent functions such as strtolower() from messing up UTF-8 strings)
  55. setlocale(LC_CTYPE, 'C');
  56. // Turn off magic_quotes_runtime
  57. if (get_magic_quotes_runtime())
  58. set_magic_quotes_runtime(0);
  59. // Strip slashes from GET/POST/COOKIE (if magic_quotes_gpc is enabled)
  60. if (get_magic_quotes_gpc())
  61. {
  62. function stripslashes_array($array)
  63. {
  64. return is_array($array) ? array_map('stripslashes_array', $array) : stripslashes($array);
  65. }
  66. $_GET = stripslashes_array($_GET);
  67. $_POST = stripslashes_array($_POST);
  68. $_COOKIE = stripslashes_array($_COOKIE);
  69. $_REQUEST = stripslashes_array($_REQUEST);
  70. }
  71. // If a cookie name is not specified in config.php, we use the default (forum_cookie)
  72. if (empty($cookie_name))
  73. $cookie_name = 'pun_cookie';
  74. // If the cache directory is not specified, we use the default setting
  75. if (!defined('FORUM_CACHE_DIR'))
  76. define('FORUM_CACHE_DIR', PUN_ROOT.'cache/');
  77. // Turn off PHP time limit
  78. @set_time_limit(0);
  79. // Define a few commonly used constants
  80. define('PUN_UNVERIFIED', 0);
  81. define('PUN_ADMIN', 1);
  82. define('PUN_MOD', 2);
  83. define('PUN_GUEST', 3);
  84. define('PUN_MEMBER', 4);
  85. // Load DB abstraction layer and try to connect
  86. require PUN_ROOT.'include/dblayer/common_db.php';
  87. // Check what the default character set is - since 1.2 didn't specify any we will use whatever the default was (usually latin1)
  88. $old_connection_charset = defined('FORUM_DEFAULT_CHARSET') ? FORUM_DEFAULT_CHARSET : $db->get_names();
  89. // Set the connection to UTF-8 now
  90. $db->set_names('utf8');
  91. // Get the forum config
  92. $result = $db->query('SELECT * FROM '.$db->prefix.'config') or error('Unable to fetch config.', __FILE__, __LINE__, $db->error());
  93. while ($cur_config_item = $db->fetch_row($result))
  94. $pun_config[$cur_config_item[0]] = $cur_config_item[1];
  95. // Load language file
  96. $default_lang = $pun_config['o_default_lang'];
  97. if (!file_exists(PUN_ROOT.'lang/'.$default_lang.'/update.php'))
  98. $default_lang = 'English';
  99. require PUN_ROOT.'lang/'.$default_lang.'/update.php';
  100. // Check current version
  101. $cur_version = $pun_config['o_cur_version'];
  102. $cur_eve_version = isset($pun_config['o_cur_eve_version']) ? $pun_config['o_cur_eve_version'] : '1.0.0';
  103. if (version_compare($cur_version, '1.2', '<'))
  104. error(sprintf($lang_update['Version mismatch error'], $db_name));
  105. // Do some DB type specific checks
  106. $mysql = false;
  107. switch ($db_type)
  108. {
  109. case 'mysql':
  110. case 'mysqli':
  111. case 'mysql_innodb':
  112. case 'mysqli_innodb':
  113. $mysql_info = $db->get_version();
  114. if (version_compare($mysql_info['version'], MIN_MYSQL_VERSION, '<'))
  115. error(sprintf($lang_update['You are running error'], 'MySQL', $mysql_info['version'], UPDATE_TO, MIN_MYSQL_VERSION));
  116. $mysql = true;
  117. break;
  118. case 'pgsql':
  119. $pgsql_info = $db->get_version();
  120. if (version_compare($pgsql_info['version'], MIN_PGSQL_VERSION, '<'))
  121. error(sprintf($lang_update['You are running error'], 'PostgreSQL', $pgsql_info['version'], UPDATE_TO, MIN_PGSQL_VERSION));
  122. break;
  123. }
  124. // Check the database, search index and parser revision and the current version
  125. if (isset($pun_config['o_database_revision']) && $pun_config['o_database_revision'] >= UPDATE_TO_DB_REVISION &&
  126. isset($pun_config['o_searchindex_revision']) && $pun_config['o_searchindex_revision'] >= UPDATE_TO_SI_REVISION &&
  127. isset($pun_config['o_parser_revision']) && $pun_config['o_parser_revision'] >= UPDATE_TO_PARSER_REVISION &&
  128. version_compare($pun_config['o_cur_version'], UPDATE_TO, '>=') &&
  129. version_compare($pun_config['o_eve_cur_version'], UPDATE_TO_EVEBB, '>='))
  130. error($lang_update['No update error']);
  131. $default_style = $pun_config['o_default_style'];
  132. if (!file_exists(PUN_ROOT.'style/'.$default_style.'.css'))
  133. $default_style = 'Air';
  134. // Start a session, used to queue up errors if duplicate users occur when converting from FluxBB v1.2.
  135. session_start();
  136. //
  137. // Determines whether $str is UTF-8 encoded or not
  138. //
  139. function seems_utf8($str)
  140. {
  141. $str_len = strlen($str);
  142. for ($i = 0; $i < $str_len; ++$i)
  143. {
  144. if (ord($str[$i]) < 0x80) continue; # 0bbbbbbb
  145. else if ((ord($str[$i]) & 0xE0) == 0xC0) $n=1; # 110bbbbb
  146. else if ((ord($str[$i]) & 0xF0) == 0xE0) $n=2; # 1110bbbb
  147. else if ((ord($str[$i]) & 0xF8) == 0xF0) $n=3; # 11110bbb
  148. else if ((ord($str[$i]) & 0xFC) == 0xF8) $n=4; # 111110bb
  149. else if ((ord($str[$i]) & 0xFE) == 0xFC) $n=5; # 1111110b
  150. else return false; # Does not match any model
  151. for ($j = 0; $j < $n; ++$j) # n bytes matching 10bbbbbb follow ?
  152. {
  153. if ((++$i == strlen($str)) || ((ord($str[$i]) & 0xC0) != 0x80))
  154. return false;
  155. }
  156. }
  157. return true;
  158. }
  159. //
  160. // Translates the number from a HTML numeric entity into an UTF-8 character
  161. //
  162. function dcr2utf8($src)
  163. {
  164. $dest = '';
  165. if ($src < 0)
  166. return false;
  167. else if ($src <= 0x007f)
  168. $dest .= chr($src);
  169. else if ($src <= 0x07ff)
  170. {
  171. $dest .= chr(0xc0 | ($src >> 6));
  172. $dest .= chr(0x80 | ($src & 0x003f));
  173. }
  174. else if ($src == 0xFEFF)
  175. {
  176. // nop -- zap the BOM
  177. }
  178. else if ($src >= 0xD800 && $src <= 0xDFFF)
  179. {
  180. // found a surrogate
  181. return false;
  182. }
  183. else if ($src <= 0xffff)
  184. {
  185. $dest .= chr(0xe0 | ($src >> 12));
  186. $dest .= chr(0x80 | (($src >> 6) & 0x003f));
  187. $dest .= chr(0x80 | ($src & 0x003f));
  188. }
  189. else if ($src <= 0x10ffff)
  190. {
  191. $dest .= chr(0xf0 | ($src >> 18));
  192. $dest .= chr(0x80 | (($src >> 12) & 0x3f));
  193. $dest .= chr(0x80 | (($src >> 6) & 0x3f));
  194. $dest .= chr(0x80 | ($src & 0x3f));
  195. }
  196. else
  197. {
  198. // out of range
  199. return false;
  200. }
  201. return $dest;
  202. }
  203. //
  204. // Attempts to convert $str from $old_charset to UTF-8. Also converts HTML entities (including numeric entities) to UTF-8 characters
  205. //
  206. function convert_to_utf8(&$str, $old_charset)
  207. {
  208. if ($str === null || $str == '')
  209. return false;
  210. $save = $str;
  211. // Replace literal entities (for non-UTF-8 compliant html_entity_encode)
  212. if (version_compare(PHP_VERSION, '5.0.0', '<') && $old_charset == 'ISO-8859-1' || $old_charset == 'ISO-8859-15')
  213. $str = html_entity_decode($str, ENT_QUOTES, $old_charset);
  214. if ($old_charset != 'UTF-8' && !seems_utf8($str))
  215. {
  216. if (function_exists('iconv'))
  217. $str = iconv($old_charset == 'ISO-8859-1' ? 'WINDOWS-1252' : 'ISO-8859-1', 'UTF-8', $str);
  218. else if (function_exists('mb_convert_encoding'))
  219. $str = mb_convert_encoding($str, 'UTF-8', $old_charset == 'ISO-8859-1' ? 'WINDOWS-1252' : 'ISO-8859-1');
  220. else if ($old_charset == 'ISO-8859-1')
  221. $str = utf8_encode($str);
  222. }
  223. // Replace literal entities (for UTF-8 compliant html_entity_encode)
  224. if (version_compare(PHP_VERSION, '5.0.0', '>='))
  225. $str = html_entity_decode($str, ENT_QUOTES, 'UTF-8');
  226. // Replace numeric entities
  227. $str = preg_replace_callback('/&#([0-9]+);/', 'utf8_callback_1', $str);
  228. $str = preg_replace_callback('/&#x([a-f0-9]+);/i', 'utf8_callback_2', $str);
  229. // Remove "bad" characters
  230. $str = remove_bad_characters($str);
  231. return ($save != $str);
  232. }
  233. function utf8_callback_1($matches)
  234. {
  235. return dcr2utf8($matches[1]);
  236. }
  237. function utf8_callback_2($matches)
  238. {
  239. return dcr2utf8(hexdec($matches[1]));
  240. }
  241. //
  242. // Alter a table to be utf8. MySQL only
  243. // Function based on update_convert_table_utf8() from the Drupal project (http://drupal.org/)
  244. //
  245. function alter_table_utf8($table)
  246. {
  247. global $mysql, $db;
  248. static $types;
  249. if (!$mysql)
  250. return;
  251. if (!isset($types))
  252. {
  253. $types = array(
  254. 'char' => 'binary',
  255. 'varchar' => 'varbinary',
  256. 'tinytext' => 'tinyblob',
  257. 'mediumtext' => 'mediumblob',
  258. 'text' => 'blob',
  259. 'longtext' => 'longblob'
  260. );
  261. }
  262. // Set table default charset to utf8
  263. $db->query('ALTER TABLE '.$table.' CHARACTER SET utf8') or error('Unable to set table character set', __FILE__, __LINE__, $db->error());
  264. // Find out which columns need converting and build SQL statements
  265. $result = $db->query('SHOW FULL COLUMNS FROM '.$table) or error('Unable to fetch column information', __FILE__, __LINE__, $db->error());
  266. while ($cur_column = $db->fetch_assoc($result))
  267. {
  268. if ($cur_column['Collation'] === null)
  269. continue;
  270. list($type) = explode('(', $cur_column['Type']);
  271. if (isset($types[$type]) && strpos($cur_column['Collation'], 'utf8') === false)
  272. {
  273. $allow_null = ($cur_column['Null'] == 'YES');
  274. $collate = (substr($cur_column['Collation'], -3) == 'bin') ? 'utf8_bin' : 'utf8_general_ci';
  275. $db->alter_field($table, $cur_column['Field'], preg_replace('/'.$type.'/i', $types[$type], $cur_column['Type']), $allow_null, $cur_column['Default'], null, true) or error('Unable to alter field to binary', __FILE__, __LINE__, $db->error());
  276. $db->alter_field($table, $cur_column['Field'], $cur_column['Type'].' CHARACTER SET utf8 COLLATE '.$collate, $allow_null, $cur_column['Default'], null, true) or error('Unable to alter field to utf8', __FILE__, __LINE__, $db->error());
  277. }
  278. }
  279. }
  280. //
  281. // Safely converts text type columns into utf8
  282. // If finished returns true, otherwise returns $end_at
  283. //
  284. function convert_table_utf8($table, $callback, $old_charset, $key = null, $start_at = null, $error_callback = null)
  285. {
  286. global $mysql, $db, $old_connection_charset;
  287. $finished = true;
  288. $end_at = 0;
  289. if ($mysql)
  290. {
  291. // Only set up the tables if we are doing this in 1 go, or its the first go
  292. if ($start_at === null || $start_at == 0)
  293. {
  294. // Drop any temp table that exists, in-case it's left over from a failed update
  295. $db->drop_table($table.'_utf8', true) or error('Unable to drop left over temp table', __FILE__, __LINE__, $db->error());
  296. // Copy the table
  297. $db->query('CREATE TABLE '.$table.'_utf8 LIKE '.$table) or error('Unable to create new table', __FILE__, __LINE__, $db->error());
  298. // Set table default charset to utf8
  299. alter_table_utf8($table.'_utf8');
  300. }
  301. // Change to the old character set so MySQL doesn't attempt to perform conversion on the data from the old table
  302. $db->set_names($old_connection_charset);
  303. // Move & Convert everything
  304. $result = $db->query('SELECT * FROM '.$table.($start_at === null ? '' : ' WHERE '.$key.'>'.$start_at).' ORDER BY '.$key.' ASC'.($start_at === null ? '' : ' LIMIT '.PER_PAGE), false) or error('Unable to select from old table', __FILE__, __LINE__, $db->error());
  305. // Change back to utf8 mode so we can insert it into the new table
  306. $db->set_names('utf8');
  307. while ($cur_item = $db->fetch_assoc($result))
  308. {
  309. $cur_item = call_user_func($callback, $cur_item, $old_charset);
  310. $temp = array();
  311. foreach ($cur_item as $idx => $value)
  312. $temp[$idx] = $value === null ? 'NULL' : '\''.$db->escape($value).'\'';
  313. $db->query('INSERT INTO '.$table.'_utf8('.implode(',', array_keys($temp)).') VALUES ('.implode(',', array_values($temp)).')') or ($error_callback === null ? error('Unable to insert data to new table', __FILE__, __LINE__, $db->error()) : call_user_func($error_callback, $cur_item));
  314. $end_at = $cur_item[$key];
  315. }
  316. // If we aren't doing this all in 1 go and $end_at has a value (i.e. we have processed at least 1 row), figure out if we have more to do or not
  317. if ($start_at !== null && $end_at > 0)
  318. {
  319. $result = $db->query('SELECT 1 FROM '.$table.' WHERE '.$key.'>'.$end_at.' ORDER BY '.$key.' ASC LIMIT 1') or error('Unable to check for next row', __FILE__, __LINE__, $db->error());
  320. $finished = $db->num_rows($result) == 0;
  321. }
  322. // Only swap the tables if we are doing this in 1 go, or its the last go
  323. if ($finished)
  324. {
  325. // Delete old table
  326. $db->drop_table($table, true) or error('Unable to drop old table', __FILE__, __LINE__, $db->error());
  327. // Rename table
  328. $db->query('ALTER TABLE '.$table.'_utf8 RENAME '.$table) or error('Unable to rename new table', __FILE__, __LINE__, $db->error());
  329. return true;
  330. }
  331. return $end_at;
  332. }
  333. else
  334. {
  335. // Convert everything
  336. $result = $db->query('SELECT * FROM '.$table.($start_at === null ? '' : ' WHERE '.$key.'>'.$start_at).' ORDER BY '.$key.' ASC'.($start_at === null ? '' : ' LIMIT '.PER_PAGE)) or error('Unable to select from table', __FILE__, __LINE__, $db->error());
  337. while ($cur_item = $db->fetch_assoc($result))
  338. {
  339. $cur_item = call_user_func($callback, $cur_item, $old_charset);
  340. $temp = array();
  341. foreach ($cur_item as $idx => $value)
  342. $temp[] = $idx.'='.($value === null ? 'NULL' : '\''.$db->escape($value).'\'');
  343. if (!empty($temp))
  344. $db->query('UPDATE '.$table.' SET '.implode(', ', $temp).' WHERE '.$key.'=\''.$db->escape($cur_item[$key]).'\'') or error('Unable to update data', __FILE__, __LINE__, $db->error());
  345. $end_at = $cur_item[$key];
  346. }
  347. if ($start_at !== null && $end_at > 0)
  348. {
  349. $result = $db->query('SELECT 1 FROM '.$table.' WHERE '.$key.'>'.$end_at.' ORDER BY '.$key.' ASC LIMIT 1') or error('Unable to check for next row', __FILE__, __LINE__, $db->error());
  350. if ($db->num_rows($result) == 0)
  351. return true;
  352. return $end_at;
  353. }
  354. return true;
  355. }
  356. }
  357. /* EVEBB Updates*/
  358. /**
  359. * Installs the tables for poll support.
  360. */
  361. function install_poll()
  362. {
  363. global $db, $db_type, $pun_config;
  364. $db->add_field('topics', 'poll_type', 'TINYINT(4)', false, 0) or error('Unable to add poll_type field', __FILE__, __LINE__, $db->error());
  365. $db->add_field('topics', 'poll_time', 'INT(10) UNSIGNED', false, 0) or error('Unable to add poll_time field', __FILE__, __LINE__, $db->error());
  366. $db->add_field('topics', 'poll_term', 'TINYINT(4)', false, 0) or error('Unable to add poll_term field', __FILE__, __LINE__, $db->error());
  367. $db->add_field('topics', 'poll_kol', 'INT(10) UNSIGNED', false, 0) or error('Unable to add poll_kol field', __FILE__, __LINE__, $db->error());
  368. $schema = array(
  369. 'FIELDS' => array(
  370. 'tid' => array(
  371. 'datatype' => 'INT(10) UNSIGNED',
  372. 'allow_null' => false,
  373. 'default' => '0'
  374. ),
  375. 'question' => array(
  376. 'datatype' => 'TINYINT(4)',
  377. 'allow_null' => false,
  378. 'default' => '0'
  379. ),
  380. 'field' => array(
  381. 'datatype' => 'TINYINT(4)',
  382. 'allow_null' => false,
  383. 'default' => '0'
  384. ),
  385. 'choice' => array(
  386. 'datatype' => 'VARCHAR(255)',
  387. 'allow_null' => false,
  388. 'default' => '\'\''
  389. ),
  390. 'votes' => array(
  391. 'datatype' => 'INT(10) UNSIGNED',
  392. 'allow_null' => false,
  393. 'default' => '0'
  394. )
  395. ),
  396. 'PRIMARY KEY' => array('tid', 'question', 'field')
  397. );
  398. $db->create_table('poll', $schema) or error('Unable to create table poll', __FILE__, __LINE__, $db->error());
  399. $schema = array(
  400. 'FIELDS' => array(
  401. 'tid' => array(
  402. 'datatype' => 'INT(10) UNSIGNED',
  403. 'allow_null' => false
  404. ),
  405. 'uid' => array(
  406. 'datatype' => 'INT(10) UNSIGNED',
  407. 'allow_null' => false
  408. ),
  409. 'rez' => array(
  410. 'datatype' => 'TEXT',
  411. 'allow_null' => true
  412. )
  413. ),
  414. 'PRIMARY KEY' => array('tid', 'uid')
  415. );
  416. $db->create_table('poll_voted', $schema) or error('Unable to create table poll_voted', __FILE__, __LINE__, $db->error());
  417. // Insert config data
  418. $config = array(
  419. 'o_poll_enabled' => "'0'",
  420. 'o_poll_max_ques' => "'3'",
  421. 'o_poll_max_field' => "'20'",
  422. 'o_poll_time' => "'60'",
  423. 'o_poll_term' => "'3'",
  424. 'o_poll_guest' => "'0'",
  425. );
  426. while (list($conf_name, $conf_value) = @each($config))
  427. {
  428. $db->query('INSERT INTO '.$db->prefix."config (conf_name, conf_value) VALUES('$conf_name', $conf_value)")
  429. or error('Unable to insert into table '.$db->prefix.'config. Please check your configuration and try again.');
  430. }
  431. forum_clear_cache();
  432. }
  433. /**
  434. * Installs the table for RSS feed support.
  435. */
  436. function install_feed() {
  437. global $db;
  438. $db->query('CREATE TABLE '.$db->prefix.'feeds ( url varchar(255) NOT NULL default \'\', max int(11) NOT NULL default 0, closed tinyint(1) NOT NULL default 0, forum_id int(11) NOT NULL default 0, last_post INT(10) NOT NULL default 0, num_posts INT(10) NOT NULL default 0, PRIMARY KEY (url) )' );
  439. } //End install_feed().
  440. /**
  441. * This massively long function makes the DB ready for sub forums.
  442. */
  443. function install_subforum() {
  444. global $db;
  445. $db->add_field('forums', 'parent_forum_id', 'INT', true, 0);
  446. } //End install_subform().
  447. /**
  448. * Installs the tables for the Private Messaging System.
  449. */
  450. function install_npms() {
  451. global $db, $db_type, $pun_config;
  452. $schema = array(
  453. 'FIELDS' => array(
  454. 'bl_id' => array(
  455. 'datatype' => 'INT(10) UNSIGNED',
  456. 'allow_null' => false,
  457. 'default' => '0'
  458. ),
  459. 'bl_user_id' => array(
  460. 'datatype' => 'INT(10) UNSIGNED',
  461. 'allow_null' => false,
  462. 'default' => '0'
  463. ),
  464. 'bl_user' => array(
  465. 'datatype' => 'VARCHAR(200)',
  466. 'allow_null' => false,
  467. 'default' => '\'\''
  468. ),
  469. ),
  470. 'INDEXES' => array(
  471. 'bl_id_idx' => array('bl_id'),
  472. 'bl_user_id_idx' => array('bl_user_id')
  473. )
  474. );
  475. $db->create_table('pms_new_block', $schema) or error('Unable to create pms_new_block table', __FILE__, __LINE__, $db->error());
  476. $schema = array(
  477. 'FIELDS' => array(
  478. 'id' => array(
  479. 'datatype' => 'SERIAL',
  480. 'allow_null' => false
  481. ),
  482. 'poster' => array(
  483. 'datatype' => 'VARCHAR(200)',
  484. 'allow_null' => false,
  485. 'default' => '\'\''
  486. ),
  487. 'poster_id' => array(
  488. 'datatype' => 'INT(10) UNSIGNED',
  489. 'allow_null' => false,
  490. 'default' => '1'
  491. ),
  492. 'poster_ip' => array(
  493. 'datatype' => 'VARCHAR(39)',
  494. 'allow_null' => true
  495. ),
  496. 'message' => array(
  497. 'datatype' => 'TEXT',
  498. 'allow_null' => true
  499. ),
  500. 'hide_smilies' => array(
  501. 'datatype' => 'TINYINT(1)',
  502. 'allow_null' => false,
  503. 'default' => '0'
  504. ),
  505. 'posted' => array(
  506. 'datatype' => 'INT(10) UNSIGNED',
  507. 'allow_null' => false,
  508. 'default' => '0'
  509. ),
  510. 'edited' => array(
  511. 'datatype' => 'INT(10) UNSIGNED',
  512. 'allow_null' => true
  513. ),
  514. 'edited_by' => array(
  515. 'datatype' => 'VARCHAR(200)',
  516. 'allow_null' => true
  517. ),
  518. 'post_seen' => array(
  519. 'datatype' => 'TINYINT(1)',
  520. 'allow_null' => false,
  521. 'default' => '0'
  522. ),
  523. 'post_new' => array(
  524. 'datatype' => 'TINYINT(1)',
  525. 'allow_null' => false,
  526. 'default' => '1'
  527. ),
  528. 'topic_id' => array(
  529. 'datatype' => 'INT(10) UNSIGNED',
  530. 'allow_null' => false,
  531. 'default' => '0'
  532. )
  533. ),
  534. 'PRIMARY KEY' => array('id'),
  535. 'INDEXES' => array(
  536. 'topic_id_idx' => array('topic_id'),
  537. 'multi_idx' => array('poster_id', 'topic_id')
  538. )
  539. );
  540. $db->create_table('pms_new_posts', $schema) or error('Unable to create pms_new_posts table', __FILE__, __LINE__, $db->error());
  541. $schema = array(
  542. 'FIELDS' => array(
  543. 'id' => array(
  544. 'datatype' => 'SERIAL',
  545. 'allow_null' => false
  546. ),
  547. 'topic' => array(
  548. 'datatype' => 'VARCHAR(255)',
  549. 'allow_null' => false,
  550. 'default' => '\'\''
  551. ),
  552. 'starter' => array(
  553. 'datatype' => 'VARCHAR(200)',
  554. 'allow_null' => false,
  555. 'default' => '\'\''
  556. ),
  557. 'starter_id' => array(
  558. 'datatype' => 'INT(10) UNSIGNED',
  559. 'allow_null' => false,
  560. 'default' => '0'
  561. ),
  562. 'to_user' => array(
  563. 'datatype' => 'VARCHAR(200)',
  564. 'allow_null' => false,
  565. 'default' => '\'\''
  566. ),
  567. 'to_id' => array(
  568. 'datatype' => 'INT(10) UNSIGNED',
  569. 'allow_null' => false,
  570. 'default' => '0'
  571. ),
  572. 'replies' => array(
  573. 'datatype' => 'MEDIUMINT(8) UNSIGNED',
  574. 'allow_null' => false,
  575. 'default' => '0'
  576. ),
  577. 'last_posted' => array(
  578. 'datatype' => 'INT(10) UNSIGNED',
  579. 'allow_null' => false,
  580. 'default' => '0'
  581. ),
  582. 'last_poster' => array(
  583. 'datatype' => 'TINYINT(1)',
  584. 'allow_null' => false,
  585. 'default' => '0'
  586. ),
  587. 'see_st' => array(
  588. 'datatype' => 'INT(10) UNSIGNED',
  589. 'allow_null' => false,
  590. 'default' => '0'
  591. ),
  592. 'see_to' => array(
  593. 'datatype' => 'INT(10) UNSIGNED',
  594. 'allow_null' => false,
  595. 'default' => '0'
  596. ),
  597. 'topic_st' => array(
  598. 'datatype' => 'TINYINT(4)',
  599. 'allow_null' => false,
  600. 'default' => '0'
  601. ),
  602. 'topic_to' => array(
  603. 'datatype' => 'TINYINT(4)',
  604. 'allow_null' => false,
  605. 'default' => '0'
  606. ),
  607. ),
  608. 'PRIMARY KEY' => array('id'),
  609. 'INDEXES' => array(
  610. 'multi_idx_st' => array('starter_id', 'topic_st'),
  611. 'multi_idx_to' => array('to_id', 'topic_to')
  612. )
  613. );
  614. $db->create_table('pms_new_topics', $schema) or error('Unable to create pms_new_topics table', __FILE__, __LINE__, $db->error());
  615. $db->add_field('groups', 'g_pm', 'TINYINT(1)', false, 1) or error('Unable to add g_pm field', __FILE__, __LINE__, $db->error());
  616. $db->add_field('groups', 'g_pm_limit', 'INT(10) UNSIGNED', false, 100) or error('Unable to add g_pm_limit field', __FILE__, __LINE__, $db->error());
  617. $db->add_field('users', 'messages_enable', 'TINYINT(1)', false, 1) or error('Unable to add messages_enable field', __FILE__, __LINE__, $db->error());
  618. $db->add_field('users', 'messages_email', 'TINYINT(1)', false, 0) or error('Unable to add messages_email field', __FILE__, __LINE__, $db->error());
  619. $db->add_field('users', 'messages_flag', 'TINYINT(1)', false, 0) or error('Unable to add messages_flag field', __FILE__, __LINE__, $db->error());
  620. $db->add_field('users', 'messages_new', 'INT(10) UNSIGNED', false, 0) or error('Unable to add messages_new field', __FILE__, __LINE__, $db->error());
  621. $db->add_field('users', 'messages_all', 'INT(10) UNSIGNED', false, 0) or error('Unable to add messages_all field', __FILE__, __LINE__, $db->error());
  622. $db->add_field('users', 'pmsn_last_post', 'INT(10) UNSIGNED', true) or error('Unable to add pmsn_last_post field', __FILE__, __LINE__, $db->error());
  623. $db->query('UPDATE '.$db->prefix.'groups SET g_pm_limit=0 WHERE g_id='.PUN_ADMIN) or error('Unable to merge groups', __FILE__, __LINE__, $db->error());
  624. // Insert config data
  625. $config = array(
  626. 'o_pms_enabled' => '1',
  627. 'o_pms_min_kolvo' => '0',
  628. 'o_pms_flasher' => '0',
  629. );
  630. while (list($conf_name, $conf_value) = @each($config))
  631. {
  632. if (!array_key_exists($conf_name, $pun_config))
  633. $db->query('INSERT INTO '.$db->prefix."config (conf_name, conf_value) VALUES('$conf_name', $conf_value)")
  634. or error('Unable to insert into table '.$db->prefix.'config. Please check your configuration and try again.');
  635. }
  636. // Delete all .php files in the cache (someone might have visited the forums while we were updating and thus, generated incorrect cache files)
  637. forum_clear_cache();
  638. } //End install_npms().
  639. /**
  640. * Installs the database for the attachements.
  641. */
  642. function install_attach($basepath='')
  643. {
  644. global $db, $db_type, $pun_config, $mod_version;
  645. //include PUN_ROOT.'include/attach/attach_incl.php';
  646. //first check so that the path seems reasonable
  647. if(!((substr($basepath,0,1) == '/' || substr($basepath,1,1) == ':') && substr($basepath,-1) == '/'))
  648. error('The pathname specified doesn\'t comply with the rules set. Go back and make sure that it\'s the complete path, and that it ends with a slash and that it either start with a slash (example: "/home/username/attachments/", on *nix servers (unix, linux, bsd, solaris etc.)) or a driveletter (example: "C:/webpages/attachments/" on windows servers)');
  649. // create the files table
  650. $schema_files = array(
  651. 'FIELDS' => array(
  652. 'id' => array(
  653. 'datatype' => 'SERIAL',
  654. 'allow_null' => false
  655. ),
  656. 'owner' => array(
  657. 'datatype' => 'INT(10)',
  658. 'allow_null' => false,
  659. 'default' => '0'
  660. ),
  661. 'post_id' => array(
  662. 'datatype' => 'INT(10)',
  663. 'allow_null' => false,
  664. 'default' => '0'
  665. ),
  666. 'filename' => array(
  667. 'datatype' => 'VARCHAR(255)',
  668. 'allow_null' => false,
  669. ),
  670. 'extension' => array(
  671. 'datatype' => 'VARCHAR(64)',
  672. 'allow_null' => false,
  673. ),
  674. 'mime' => array(
  675. 'datatype' => 'VARCHAR(64)',
  676. 'allow_null' => false
  677. ),
  678. 'location' => array(
  679. 'datatype' => 'TEXT',
  680. 'allow_null' => false
  681. ),
  682. 'size' => array(
  683. 'datatype' => 'INT(10)',
  684. 'allow_null' => false,
  685. 'default' => '0'
  686. ),
  687. 'downloads' => array(
  688. 'datatype' => 'INT(10)',
  689. 'allow_null' => false,
  690. 'default' => '0'
  691. )
  692. ),
  693. 'PRIMARY KEY' => array('id'),
  694. );
  695. $db->create_table('attach_2_files', $schema_files) or error('Unable to create table "attach_2_files"', __FILE__, __LINE__, $db->error());
  696. // create the files table
  697. $schema_rules = array(
  698. 'FIELDS' => array(
  699. 'id' => array(
  700. 'datatype' => 'SERIAL',
  701. 'allow_null' => false
  702. ),
  703. 'forum_id' => array(
  704. 'datatype' => 'INT(10)',
  705. 'allow_null' => false,
  706. 'default' => '0'
  707. ),
  708. 'group_id' => array(
  709. 'datatype' => 'INT(10)',
  710. 'allow_null' => false,
  711. 'default' => '0'
  712. ),
  713. 'rules' => array(
  714. 'datatype' => 'INT(10)',
  715. 'allow_null' => false,
  716. 'default' => '0'
  717. ),
  718. 'size' => array(
  719. 'datatype' => 'INT(10)',
  720. 'allow_null' => false,
  721. 'default' => '0'
  722. ),
  723. 'per_post' => array(
  724. 'datatype' => 'TINYINT(4)',
  725. 'allow_null' => false,
  726. 'default' => '1'
  727. ),
  728. 'file_ext' => array(
  729. 'datatype' => 'TEXT',
  730. 'allow_null' => false
  731. ),
  732. ),
  733. 'PRIMARY KEY' => array('id'),
  734. );
  735. $db->create_table('attach_2_rules', $schema_rules) or error('Unable to create table "attach_2_rules"', __FILE__, __LINE__, $db->error());
  736. //ok path could be correct, try to make a subfolder :D
  737. $newname = attach_generate_pathname($basepath);
  738. if(!attach_create_subfolder($newname,$basepath))
  739. error('Unable to create new subfolder with name "'.$newname.'", make sure php has write access to that folder!',__FILE__,__LINE__);
  740. // ok, add the stuff needed in the config cache
  741. $attach_config = array( 'attach_always_deny' => 'html"htm"php"php3"php4"php5"exe"com"bat',
  742. 'attach_basefolder' => $basepath,
  743. 'attach_create_orphans' => '1',
  744. 'attach_cur_version' => $mod_version,
  745. 'attach_icon_folder' => 'img/attach/',
  746. 'attach_icon_extension' => 'txt"log"doc"pdf"wav"mp3"ogg"avi"mpg"mpeg"png"jpg"jpeg"gif"zip"rar"7z"gz"tar',
  747. 'attach_icon_name' => 'text.png"text.png"doc.png"doc.png"audio.png"audio.png"audio.png"video.png"video.png"video.png"image.png"image.png"image.png"image.png"compress.png"compress.png"compress.png"compress.png"compress.png',
  748. 'attach_max_size' => '100000',
  749. 'attach_subfolder' => $newname,
  750. 'attach_use_icon' => '1');
  751. foreach($attach_config AS $key => $value)
  752. $db->query("INSERT INTO ".$db->prefix."config (conf_name, conf_value) VALUES ('$key', '".$db->escape($value)."')") or error('Unable to add column "'.$key.'" to config table', __FILE__, __LINE__, $db->error());
  753. // and now, update the cache...
  754. require_once PUN_ROOT.'include/cache.php';
  755. generate_config_cache();
  756. } //End install_attach()
  757. function attach_create_subfolder($newfolder='',$basepath){
  758. // check to see if that folder is there already, then just update the config ...
  759. if(!is_dir($basepath.$newfolder)){
  760. // if the folder doesn't exist, try to create it
  761. if(!mkdir($basepath.$newfolder,0755))
  762. error('Unable to create new subfolder with name \''.$basepath.$newfolder.'\' with mode 0755',__FILE__,__LINE__);
  763. // create a .htaccess and index.html file in the new subfolder
  764. if(!copy($basepath.'.htaccess', $basepath.$newfolder.'/.htaccess'))
  765. error('Unable to copy .htaccess file to new subfolder with name \''.$basepath.$newfolder.'\'',__FILE__,__LINE__);
  766. if(!copy($basepath.'index.html', $basepath.$newfolder.'/index.html'))
  767. error('Unable to copy index.html file to new subfolder with name \''.$basepath.$newfolder.'\'',__FILE__,__LINE__);
  768. // if the folder was created continue
  769. }
  770. // return true if everything has gone as planned, return false if the new folder could not be created (rights etc?)
  771. return true;
  772. }
  773. function attach_generate_pathname($storagepath=''){
  774. if(strlen($storagepath)!=0){
  775. //we have to check so that path doesn't exist already...
  776. $not_unique=true;
  777. while($not_unique){
  778. $newdir = attach_generate_pathname();
  779. if(!is_dir($storagepath.$newdir))return $newdir;
  780. }
  781. }else
  782. return substr(md5(time().'54ÂŁ7 k3yw0rd, r3pl4ce |f U w4nt t0'),0,32);
  783. }
  784. function attach_generate_filename($storagepath, $messagelenght=0, $filesize=0){
  785. $not_unique=true;
  786. while($not_unique){
  787. $newfile = md5(attach_generate_pathname().$messagelenght.$filesize.'Some more salt keyworbs, change if you want to').'.attach';
  788. if(!is_file($storagepath.$newfile))return $newfile;
  789. }
  790. }
  791. function update_forum_perm($forum_id) {
  792. global $db;
  793. //This 'fills in' blank permissions, used for multi-group joins.
  794. //I personally prefer to work on *some* data than assume something based on a lack of data.
  795. $result = $db->query('SELECT g_id, g_read_board, g_post_replies, g_post_topics FROM '.$db->prefix.'groups WHERE g_id!='.PUN_ADMIN) or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error());
  796. while ($cur_group = $db->fetch_assoc($result)) {
  797. $sql = "SELECT * FROM ".$db->prefix."forum_perms WHERE group_id=".$cur_group['g_id']." AND forum_id=".$forum_id;
  798. if (!$perms = $db->query($sql)) {
  799. continue;
  800. } //End if.
  801. if ($db->num_rows($perms) == 0) {
  802. $read_forum_new = '0';
  803. $post_replies_new = '0';
  804. $post_topics_new = '0';
  805. } else {
  806. $perms = $db->fetch_assoc($perms);
  807. $read_forum_new = ($perms['read_forum'] != '') ? $perms['read_forum'] : '0';
  808. $post_replies_new = ($perms['post_replies'] != '') ? $perms['post_replies'] : '0';
  809. $post_topics_new = ($perms['post_topics'] != '') ? $perms['post_topics'] : '0';
  810. } //End if - else.
  811. $fields = array(
  812. 'forum_id' => $forum_id,
  813. 'group_id' => $cur_group['g_id'],
  814. 'read_forum' => $read_forum_new,
  815. 'post_replies' => $post_replies_new,
  816. 'post_topics' => $post_topics_new
  817. );
  818. if (!$db->insert_or_update($fields, array('forum_id', 'group_id'), $db->prefix.'forum_perms')) {
  819. if (defined('PUN_DEBUG')) {
  820. error('Unable to add group to table.', __FILE__, __LINE__, $db->error());
  821. } //End if.
  822. $log .= "[".$cur_group['g_id']."]: Unable to add permissions [".$old_group."].\n";
  823. continue;
  824. } //End if.
  825. }
  826. } //End update_forum_perm().
  827. /* EVEBB Updates*/
  828. header('Content-type: text/html; charset=utf-8');
  829. // Empty all output buffers and stop buffering
  830. while (@ob_end_clean());
  831. $stage = isset($_REQUEST['stage']) ? $_REQUEST['stage'] : '';
  832. $old_charset = isset($_REQUEST['req_old_charset']) ? str_replace('ISO8859', 'ISO-8859', strtoupper($_REQUEST['req_old_charset'])) : 'ISO-8859-1';
  833. $start_at = isset($_REQUEST['start_at']) ? intval($_REQUEST['start_at']) : 0;
  834. $query_str = '';
  835. // Show form
  836. if (empty($stage))
  837. {
  838. ?>
  839. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  840. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
  841. <head>
  842. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  843. <title><?php echo $lang_update['Update'] ?></title>
  844. <link rel="stylesheet" type="text/css" href="style/<?php echo $default_style ?>.css" />
  845. </head>
  846. <body onload="document.getElementById('install').req_db_type.focus();document.getElementById('install').start.disabled=false;">
  847. <div id="pundb_update" class="pun">
  848. <div class="top-box"><div><!-- Top Corners --></div></div>
  849. <div class="punwrap">
  850. <div id="brdheader" class="block">
  851. <div class="box">
  852. <div id="brdtitle" class="inbox">
  853. <h1><span><?php echo $lang_update['Update'] ?></span></h1>
  854. <div id="brddesc"><p><?php echo $lang_update['Update message'] ?></p><p><strong><?php echo $lang_update['Note']; ?></strong> <?php echo $lang_update['Members message']; ?></p></div>
  855. </div>
  856. </div>
  857. </div>
  858. <div id="brdmain">
  859. <div class="blockform">
  860. <h2><span><?php echo $lang_update['Update'] ?></span></h2>
  861. <div class="box">
  862. <form method="post" action="db_update.php">
  863. <div class="inform">
  864. <input type="hidden" name="stage" value="evebb" />
  865. <fieldset>
  866. <legend><?php echo $lang_update['Administrator only'] ?></legend>
  867. <div class="infldset">
  868. <p><?php echo $lang_update['Database password info'] ?></p>
  869. <p><strong><?php echo $lang_update['Note']; ?></strong> <?php echo $lang_update['Database password note'] ?></p>
  870. <label class="required"><strong><?php echo $lang_update['Database password'] ?> <span><?php echo $lang_update['Required'] ?></span></strong><br /><input type="password" id="req_db_pass" name="req_db_pass" /><br /></label>
  871. </div>
  872. </fieldset>
  873. </div>
  874. <div class="inform">
  875. <div class="forminfo">
  876. <p><?php echo $lang_update['Intro 1'] ?></p>
  877. <p><?php echo $lang_update['Intro 2'] ?></p>
  878. <?php
  879. if (strpos($cur_version, '1.2') === 0)
  880. {
  881. if (!function_exists('iconv') && !function_exists('mb_convert_encoding'))
  882. {
  883. ?>
  884. <p><?php echo $lang_update['No charset conversion'] ?></p>
  885. <?php
  886. }
  887. ?>
  888. </div>
  889. </div>
  890. <div class="inform">
  891. <div class="forminfo">
  892. <p><?php echo $lang_update['Enable conversion'] ?></p>
  893. <p><?php echo $lang_update['Current character set'] ?></p>
  894. </div>
  895. <fieldset>
  896. <legend><?php echo $lang_update['Charset conversion'] ?></legend>
  897. <div class="infldset">
  898. <div class="rbox">
  899. <label><input type="checkbox" name="convert_charset" value="1" checked="checked" /><?php echo $lang_update['Enable conversion label'] ?><br /></label>
  900. </div>
  901. <label>
  902. <strong><?php echo $lang_update['Current character set label'] ?></strong><br /><?php echo $lang_update['Current character set info'] ?><br />
  903. <input type="text" name="req_old_charset" size="12" maxlength="20" value="<?php echo $old_charset ?>" /><br />
  904. </label>
  905. </div>
  906. </fieldset>
  907. <?php
  908. }
  909. else
  910. echo "\t\t\t\t".'</div>'."\n";
  911. ?>
  912. </div>
  913. <p class="buttons"><input type="submit" name="start" value="<?php echo $lang_update['Start update'] ?>" /></p>
  914. </form>
  915. </div>
  916. </div>
  917. </div>
  918. </div>
  919. <div class="end-box"><div><!-- Bottom Corners --></div></div>
  920. </div>
  921. </body>
  922. </html>
  923. <?php
  924. $db->end_transaction();
  925. $db->close();
  926. exit;
  927. }
  928. // Read the lock file
  929. $lock = file_exists(FORUM_CACHE_DIR.'db_update.lock') ? trim(file_get_contents(FORUM_CACHE_DIR.'db_update.lock')) : false;
  930. $lock_error = false;
  931. // Generate or fetch the UID - this confirms we have a valid admin
  932. if (isset($_POST['req_db_pass']))
  933. {
  934. $req_db_pass = strtolower(trim($_POST['req_db_pass']));
  935. switch ($db_type)
  936. {
  937. // For SQLite we compare against the database file name, since the password is left blank
  938. case 'sqlite':
  939. if ($req_db_pass != strtolower($db_name))
  940. error(sprintf($lang_update['Invalid file error'], 'config.php'));
  941. break;
  942. // For everything else, check the password matches
  943. default:
  944. if ($req_db_pass != strtolower($db_password))
  945. error(sprintf($lang_update['Invalid password error'], 'config.php'));
  946. break;
  947. }
  948. // Generate a unique id to identify this session, only if this is a valid session
  949. $uid = pun_hash($req_db_pass.'|'.uniqid(rand(), true));
  950. if ($lock) // We already have a lock file
  951. $lock_error = true;
  952. else // Create the lock file
  953. {
  954. $fh = @fopen(FORUM_CACHE_DIR.'db_update.lock', 'wb');
  955. if (!$fh)
  956. error(sprintf($lang_update['Unable to lock error'], 'cache'));
  957. fwrite($fh, $uid);
  958. fclose($fh);
  959. }
  960. }
  961. else if (isset($_GET['uid']))
  962. {
  963. $uid = trim($_GET['uid']);
  964. if (!$lock || $lock != $uid) // The lock doesn't exist or doesn't match the given UID
  965. $lock_error = true;
  966. }
  967. else
  968. error($lang_update['No password error']);
  969. // If there is an error with the lock file
  970. if ($lock_error)
  971. error(sprintf($lang_update['Script runs error'], FORUM_CACHE_DIR.'db_update.lock'));
  972. switch ($stage)
  973. {
  974. case 'evebb':
  975. $query_str = '?stage=start';
  976. /*EveBB runs first*/
  977. //Updates for mods.
  978. // If we don't have the teamspeak3 table, create it
  979. if (!$db->table_exists('teamspeak3')) {
  980. $schema = array(
  981. 'FIELDS' => array(
  982. 'user_id' => array(
  983. 'datatype' => 'INT(10) UNSIGNED',
  984. 'allow_null' => false,
  985. 'default' => '0'
  986. ),
  987. 'username' => array(
  988. 'datatype' => 'VARCHAR(100)',
  989. 'allow_null' => false
  990. ),
  991. 'token' => array(
  992. 'datatype' => 'VARCHAR(100)',
  993. 'allow_null' => false
  994. )
  995. ),
  996. 'PRIMARY KEY' => array('user_id')
  997. );
  998. $db->create_table('teamspeak3', $schema) or error('Unable to create teamspeak3 table', __FILE__, __LINE__, $db->error());
  999. } //End if.
  1000. //Only install the mods if they aren't already installed.
  1001. if (!$db->table_exists('pms_new_block')) {
  1002. install_npms();
  1003. } //End if.
  1004. if (!$db->field_exists('api_auth', 'cak_type')) {
  1005. $db->add_field('api_auth', 'cak_type', 'INT(10) UNSIGNED', false, '0', null)
  1006. or error('Unable to add CAK Type field.', __FILE__, __LINE__, $db->error());
  1007. } //End if.
  1008. if (!$db->field_exists('forums', 'parent_forum_id')) {
  1009. install_subforum();
  1010. } //End if.
  1011. if (!$db->table_exists('attach_2_files')) {
  1012. install_attach(rtrim(dirname(__FILE__), '/\\') . DIRECTORY_SEPARATOR.'attachments/');
  1013. } //End if,
  1014. if (!$db->table_exists('feeds')) {
  1015. install_feed();
  1016. } //End if.
  1017. if (!$db->table_exists('poll')) {
  1018. install_poll();
  1019. } //End if.
  1020. if (!$db->table_exists('session')) {
  1021. //Session table
  1022. $schema = array(
  1023. 'FIELDS' => array(
  1024. 'user_id' => array(
  1025. 'datatype' => 'INT(10) UNSIGNED',
  1026. 'allow_null' => false,
  1027. 'default' => '0'
  1028. ),
  1029. 'token' => array(
  1030. 'datatype' => 'VARCHAR(32)',
  1031. 'allow_null' => false
  1032. ),
  1033. 'stamp' => array(
  1034. 'datatype' => 'INT(10) UNSIGNED',
  1035. 'allow_null' => false
  1036. ),
  1037. 'length' => array(
  1038. 'datatype' => 'INT(10) UNSIGNED',
  1039. 'allow_null' => false
  1040. ),
  1041. 'ip' => array(
  1042. 'datatype' => 'VARCHAR(32)',
  1043. 'allow_null' => false
  1044. )
  1045. ),
  1046. 'PRIMARY KEY' => array('user_id')
  1047. );
  1048. $db->create_table('session', $schema) or error('Unable to create session table', __FILE__, __LINE__, $db->error());
  1049. } //End is.
  1050. if (version_compare($cur_eve_version, '1.1.1', '<=')) {
  1051. //Update/insert new configs.
  1052. $db->drop_table('api_skill_queue');
  1053. $schema = array(
  1054. 'FIELDS' => array(
  1055. 'character_id' => array(
  1056. 'datatype' => 'INT(10) UNSIGNED',
  1057. 'allow_null' => false
  1058. ),
  1059. 'queuePosition' => array(
  1060. 'datatype' => 'INT(10) UNSIGNED',
  1061. 'allow_null' => false
  1062. ),
  1063. 'typeID' => array(
  1064. 'datatype' => 'INT(10) UNSIGNED',
  1065. 'allow_null' => false
  1066. ),
  1067. 'level' => array(
  1068. 'datatype' => 'INT(10) UNSIGNED',
  1069. 'allow_null' => false
  1070. ),
  1071. 'startSP' => array(
  1072. 'datatype' => 'INT(10) UNSIGNED',
  1073. 'allow_null' => false
  1074. ),
  1075. 'endSP' => array(
  1076. 'datatype' => 'INT(10) UNSIGNED',
  1077. 'allow_null' => false
  1078. ),
  1079. 'startTime' => array(
  1080. 'datatype' => 'VARCHAR(25)',
  1081. 'allow_null' => false
  1082. ),
  1083. 'endTime' => array(
  1084. 'datatype' => 'VARCHAR(25)',
  1085. 'allow_null' => false
  1086. ),
  1087. 'last_update' => array(
  1088. 'datatype' => 'INT(10) UNSIGNED',
  1089. 'allow_null' => false
  1090. )
  1091. ),
  1092. 'PRIMARY KEY' => array('character_id', 'typeID', 'queuePosition')
  1093. );
  1094. $db->create_table('api_skill_queue', $schema) or error('Unable to create skill queue table', __FILE__, __LINE__, $db->error());
  1095. $db->insert_or_update(
  1096. array('conf_name' => 'o_eve_cak_mask', 'conf_value' => '33947656'), //Fields
  1097. 'conf_name', //Primary Key
  1098. $db->prefix.'config' //Table
  1099. );
  1100. $db->insert_or_update(
  1101. array('conf_name' => 'o_eve_cak_type', 'conf_value' => '1'), //Fields
  1102. 'conf_name', //Primary Key
  1103. $db->prefix.'config' //Table
  1104. );
  1105. $db->insert_or_update(
  1106. array('conf_name' => 'o_eve_use_image_server', 'conf_value' => '0'), //Fields
  1107. 'conf_name', //Primary Key
  1108. $db->prefix.'config' //Table
  1109. );
  1110. $db->insert_or_update(
  1111. array('conf_name' => 'o_eve_char_pic_size', 'conf_value' => '128'), //Fields
  1112. 'conf_name', //Primary Key
  1113. $db->prefix.'config' //Table
  1114. );
  1115. if (!function_exists('generate_config_cache')) {
  1116. include(PUN_ROOT.'include/cache.php');
  1117. } //End if.
  1118. generate_config_cache();
  1119. } //End if.
  1120. if (version_compare($cur_eve_version, '1.0.0', '<=')) {
  1121. $db->insert_or_update(
  1122. array('conf_name' => 'o_hide_stats', 'conf_value' => '0'), //Fields
  1123. 'conf_name', //Primary Key
  1124. $db->prefix.'config' //Table
  1125. );
  1126. $db->insert_or_update(
  1127. array('conf_name' => 'o_default_style', 'conf_value' => 'evebbgray'), //Fields
  1128. 'conf_name', //Primary Key
  1129. $db->prefix.'config' //Table
  1130. );
  1131. $db->insert_or_update(
  1132. array('conf_name' => 'o_allow_style', 'conf_value' => '1'), //Fields
  1133. 'conf_name', //Primary Key
  1134. $db->prefix.'config' //Table
  1135. );
  1136. if (!function_exists('generate_config_cache')) {
  1137. include(PUN_ROOT.'include/cache.php');
  1138. } //End if.
  1139. generate_config_cache();
  1140. //Update permissions, this is not a -terrible- thing to have fail, so we'll let it.
  1141. //You can manually do this via the forum page.
  1142. $sql = "SELECT id FROM ".$db->prefix."forums";
  1143. if ($result = $db->query($sql)) {
  1144. while ($row = $db->fetch_row($result)) {
  1145. update_forum_perm($row[0]);
  1146. } //End while loop().
  1147. } //End if.
  1148. } //End if.
  1149. //The version we want to update to.
  1150. $db->insert_or_update(
  1151. array('conf_name' => 'o_cur_eve_version', 'conf_value' => UPDATE_TO_EVEBB), //Fields
  1152. 'conf_name', //Primary Key
  1153. $db->prefix.'config' //Table
  1154. );
  1155. break;
  1156. // Start by updating the database structure
  1157. case 'start':
  1158. $query_str = '?stage=preparse_posts';
  1159. // If we don't need to update the database, skip this stage
  1160. if (isset($pun_config['o_database_revision']) && $pun_config['o_database_revision'] >= UPDATE_TO_DB_REVISION)
  1161. break;
  1162. // Make all email fields VARCHAR(80)
  1163. $db->alter_field('bans', 'email', 'VARCHAR(80)', true) or error('Unable to alter email field', __FILE__, __LINE__, $db->error());
  1164. $db->alter_field('posts', 'poster_email', 'VARCHAR(80)', true) or error('Unable to alter poster_email field', __FILE__, __LINE__, $db->error());
  1165. $db->alter_field('users', 'email', 'VARCHAR(80)', false, '') or error('Unable to alter email field', __FILE__, __LINE__, $db->error());
  1166. $db->alter_field('users', 'jabber', 'VARCHAR(80)', true) or error('Unable to alter jabber field', __FILE__, __LINE__, $db->error());
  1167. $db->alter_field('users', 'msn', 'VARCHAR(80)', true) or error('Unable to alter msn field', __FILE__, __LINE__, $db->error());
  1168. $db->alter_field('users', 'activate_string', 'VARCHAR(80)', true) or error('Unable to alter activate_string field', __FILE__, __LINE__, $db->error());
  1169. // Make all IP fields VARCHAR(39) to support IPv6
  1170. $db->alter_field('posts', 'poster_ip', 'VARCHAR(39)', true) or error('Unable to alter poster_ip field', __FILE__, __LINE__, $db->error());
  1171. $db->alter_field('users', 'registration_ip', 'VARCHAR(39)', false, '0.0.0.0') or error('Unable to alter registration_ip field', __FILE__, __LINE__, $db->error());
  1172. // Make the message field MEDIUMTEXT to allow proper conversion of 65535 character posts to UTF-8
  1173. $db->alter_field('posts', 'message', 'MEDIUMTEXT', true) or error('Unable to alter message field', __FILE__, __LINE__, $db->error());
  1174. // Add the DST option to the users table
  1175. $db->add_field('users', 'dst', 'TINYINT(1)', false, 0, 'timezone') or error('Unable to add dst field', __FILE__, __LINE__, $db->error());
  1176. // Add the last_post field to the online table
  1177. $db->add_field('online', 'last_post', 'INT(10) UNSIGNED', true, null, null) or error('Unable to add last_post field', __FILE__, __LINE__, $db->error());
  1178. // Add the last_search field to the online table
  1179. $db->add_field('online', 'last_search', 'INT(10) UNSIGNED', true, null, null) or error('Unable to add last_search field', __FILE__, __LINE__, $db->error());
  1180. // Add the last_search column to the users table
  1181. $db->add_field('users', 'last_search', 'INT(10) UNSIGNED', true, null, 'last_post') or error('Unable to add last_search field', __FILE__, __LINE__, $db->error());
  1182. // Drop use_avatar column from users table
  1183. $db->drop_field('users', 'use_avatar') or error('Unable to drop use_avatar field', __FILE__, __LINE__, $db->error());
  1184. // Drop save_pass column from users table
  1185. $db->drop_field('users', 'save_pass') or error('Unable to drop save_pass field', __FILE__, __LINE__, $db->error());
  1186. // Drop g_edit_subjects_interval column from groups table
  1187. $db->drop_field('groups', 'g_edit_subjects_interval');
  1188. // Add database revision number
  1189. if (!array_key_exists('o_database_revision', $pun_config))
  1190. $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_database_revision\', \'0\')') or error('Unable to insert config value \'o_database_revision\'', __FILE__, __LINE__, $db->error());
  1191. // Add search index revision number
  1192. if (!array_key_exists('o_searchindex_revision', $pun_config))
  1193. $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_searchindex_revision\', \'0\')') or error('Unable to insert config value \'o_searchindex_revision\'', __FILE__, __LINE__, $db->error());
  1194. // Add parser revision number
  1195. if (!array_key_exists('o_parser_revision', $pun_config))
  1196. $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_parser_revision\', \'0\')') or error('Unable to insert config value \'o_parser_revision\'', __FILE__, __LINE__, $db->error());
  1197. // Add default email setting option
  1198. if (!array_key_exists('o_default_email_setting', $pun_config))
  1199. $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_default_email_setting\', \'1\')') or error('Unable to insert config value \'o_default_email_setting\'', __FILE__, __LINE__, $db->error());
  1200. // Make sure we have o_additional_navlinks (was added in 1.2.1)
  1201. if (!array_key_exists('o_additional_navlinks', $pun_config))
  1202. $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_additional_navlinks\', \'\')') or error('Unable to insert config value \'o_additional_navlinks\'', __FILE__, __LINE__, $db->error());
  1203. // Insert new config option o_topic_views
  1204. if (!array_key_exists('o_topic_views', $pun_config))
  1205. $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_topic_views\', \'1\')') or error('Unable to insert config value \'o_topic_views\'', __FILE__, __LINE__, $db->error());
  1206. // Insert new config option o_signatures
  1207. if (!array_key_exists('o_signatures', $pun_config))
  1208. $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_signatures\', \'1\')') or error('Unable to insert config value \'o_signatures\'', __FILE__, __LINE__, $db->error());
  1209. // Insert new config option o_smtp_ssl
  1210. if (!array_key_exists('o_smtp_ssl', $pun_config))
  1211. $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_smtp_ssl\', \'0\')') or error('Unable to insert config value \'o_smtp_ssl\'', __FILE__, __LINE__, $db->error());
  1212. // Insert new config option o_default_dst
  1213. if (!array_key_exists('o_default_dst', $pun_config))
  1214. $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_default_dst\', \'0\')') or error('Unable to insert config value \'o_default_dst\'', __FILE__, __LINE__, $db->error());
  1215. // Insert new config option o_quote_depth
  1216. if (!array_key_exists('o_quote_depth', $pun_config))
  1217. $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_quote_depth\', \'3\')') or error('Unable to insert config value \'o_quote_depth\'', __FILE__, __LINE__, $db->error());
  1218. // Insert new config option o_feed_type
  1219. if (!array_key_exists('o_feed_type', $pun_config))
  1220. $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_feed_type\', \'2\')') or error('Unable to i…

Large files files are truncated, but you can click here to view the full file