Problem med uppgradering.

Här kan du ställa frågor om problem med och drift av phpBB 3 (3.0.0 eller senare). Det är här du bör skapa en tråd om du har ett problem, vill ställa en fråga och vill ha ett svar. Gäller det något annat, var vänlig bläddra nedåt på sidan.

Moderatorer: Supportgrupp, Moderatorgrupp

Kategoriregler
Här kan du ställa frågor om problem med och drift av phpBB 3 (3.0.0 eller senare). Det är här du bör skapa en tråd om du har ett problem, vill ställa en fråga och vill ha ett svar. Gäller det något annat, var vänlig bläddra nedåt på forumindex.

Klicka här för att se våra allmänna forumregler.
Erik Nilsson
Medlem
Medlem
Inlägg: 16
Blev medlem: 2011-02-26 09:27
Svar: 0

Problem med uppgradering.

Inlägg av Erik Nilsson »

Hej allihopa!
Jag har nyligen tagit över ett forum då tidigare admins har varit inaktiva i några år och då har jag lite planer på att uppgradera forumet.
Tanken är att gå till phpbb3 (från phpbb 2.0.21).
Jag kan påpeka att jag är totalt grön på det här med php/phpbb/mySQL etc etc och har försökt förlita mig på de guider jag hittat, men det har inte fungerat.

Address till ditt forum:
http://www.fjollhoj.se

Vilka teman har du installerade?:
Jag har något som kallas alexis theme om det säger er något? jag är grön som sagt

Vilka MODdar har du installerat?:
Jag antar att det klassas som moddar för forumet ser ju inte ut som en "clean install" så att säga

Har du laddat ner phpBB från något annat ställe än phpBB.com eller phpBB-se.com?:
Kan ej svara på detta då det ej var jag som installerade

Vilken version av phpBB använder du?:
2.0.21

Vilken version av PHP?:
PHP5 enl. one.com

Vilken databasserver använder du och vilken version?:
För okunnig för att kunna svara

Webbhotell/server:
one.com

Installerade någon phpBB åt dig, i så fall vem?:
Tidigare admin (Finnepinnen), ej aktiv ö.h.t. på forumet f.n.

Är detta en uppgradering (t.ex. 3.0.0 till 3.0.3)? I så fall, från vad till vad?:
2.0.21 till 3.0.8 är tanken, har ni bättre tips är jag villig att lyssna

Är det här en konvertering (t.ex. vBulletin X.X.X till phpBB 3.0.x)? I så fall, från vad till vad?:
phpbb2 till 3 om det klassas som konvertering.

Har du sökt angående ditt problem?:
Ja

Om du har sökt, vilka söktermer försökte du med?:
I detta forum:
uppgrader* (i topic)
Google:
uppgradera phpbb2 till 3
import posts phpbb3
Maximum execution time conversion phpbb3
Maximum execution time phpbb3
Maximum execution time conversion phpbb3
install phpbb3 with old posts
med flera


Berätta om ditt problem:
Jag försöker som sagt uppgradera till phpbb3. Jag gör enligt guiden och installationen går bra, men den har ju ett eget prefix så jag antar att det är därför phpbb3an är tom på inlägg osv. När jag sedan gör konverteringen får jag "Fatal error: Maximum execution time of 50 seconds exceeded in /customers/fjollhoj.se/fjollhoj.se/httpd.www/tre/includes/message_parser .php on line 134"
Jag har pratat med one.com och de är inte villiga/kan ej öka max execution time.

Då gjorde jag så att jag kopierade allt från FTPn och gjorde en backup av databasen och la in forumet på min dator (använder xampp) för att försöka göra uppdateringen lokalt och sedan skeppa över allt till domänen igen.
Då får jag detta felmeddelande:
"General Error
SQL ERROR [ mysqli ]

MySQL server has gone away [2006]

SQL

UPDATE phpbb3_config SET config_value = 'a:3:{s:4:\"step\";s:40:\"&current_table=16&skip_rows=9064\";s:12:\"table_prefix\";s:11:\"phpbb_forum\";s:3:\"tag\";s:7:\"phpbb20\";}' WHERE config_name = 'convert_progress'

BACKTRACE

FILE: includes/db/mysqli.php
LINE: 163
CALL: dbal->sql_error()

FILE: includes/functions.php
LINE: 149
CALL: dbal_mysqli->sql_query()

FILE: install/install_convert.php
LINE: 1541
CALL: set_config()

FILE: install/install_convert.php
LINE: 1419
CALL: install_convert->save_convert_progress()

FILE: install/install_convert.php
LINE: 203
CALL: install_convert->convert_data()

FILE: install/index.php
LINE: 409
CALL: install_convert->main()

FILE: install/index.php
LINE: 286
CALL: module->load()"


Jag har försökt återuppta konverteringen flera gånger men den fastnar ändå.

Jag misstänker att det i båda fallen beror på att processen tar för lång tid och att det tar timeout.
Vad beror detta på och hur kommer jag runt det?

Jag är villig att börja om med ett normalt phpBB3 men jag vill behålla inläggen som är postade och användarna (åtminstone de 20 senaste och de 30 med mest inlägg så att de som är färska och eller aktiva får behålla sitt konto)

Stats om forumet:
Antal trådar: 739
Antal inlägg: 101081
Antal användare: 462 (varav max 20 kan anses som aktiva :mrgreen: )


Har du ett testkonto åt oss?: Inte för närvarande, anser ni att ni behöver det kan det väl gå att ordna.
Om du har det, var redo att ge det till oss om någon i Supportgruppen frågar efter det.


Jag är som sagt en total nybörjare så det är fullt möjligt att jag svarat knasigt på någon fråga i mallen, men säg till mig då så ska jag försöka ordna till det :)

Tack på förhand
Mvh Erik Nilsson

Edit: Jag får be om ursäkt om det här hamnade i fel forumdel, men målet är phpbb3 och det är vägen dit som är bekymret
Användarens profilbild
Sinom
Verified
Administratör
Administratör
Inlägg: 11527
Blev medlem: 2010-11-04 21:24
Svar: 14

Re: Problem med uppgradering.

Inlägg av Sinom »

Hej Erik Nilsson!
Erik Nilsson skrev:Jag gör enligt guiden
Vilken guide är det du följer?

Att konvertera från phpBB2 till senaste versionen utav phpBB3 är en enkel process, så detta borde gå smärtfritt.

Det du har just nu är en phpBB2 installation på en phpBB2 databas, det du behöver göra är att installera phpBB3 på en ny databas jämte phpBB2-installationen.

Det du skall göra allra första är att du tar en backup på din databas och dina filer. (Vet du ej hur man gör så skriv bara här så berättar jag)
Efter detta skall du installera senaste versionen utav phpBB3 (3.0.8) som en ny installation jämte din phpBB2-installation. (Vill du ha en snabb beskrivning om hur man gör detta så säg till)

Efter den är färdiginstallerad, så behöver du endast (efter installationen är helt klar) klicka på Convert-fliken, och där fylla i uppgifterna till ditt phpBB2-forum, uppgifterna hittar du i config.php filen som ligger i phpBB2-mappen. Fyll i de, och starta konverteringen.

Den kommer inte att konvertera din phpBB2-databas, utan den läser den och skapar en konverterad version utav den i phpBB3-databasen. Så om det går snett så ska det vanliga forumet fungera som det gjorde förut ändå. Men ta alltid en backup innan du utför någon ändring.

Om allt detta har gått bra så har du konverterat forumet. Om du kommer så här långt så fortsätter vi med efter-fixar :wink:

Lycka till!

Hugs :ugeek:
Bild
Erik Nilsson
Medlem
Medlem
Inlägg: 16
Blev medlem: 2011-02-26 09:27
Svar: 0

Re: Problem med uppgradering.

Inlägg av Erik Nilsson »

Hej!

Det är guiden på phpbb.com jag använder. ( http://www.phpbb.com/community/docs/INS ... ml#convert )

Som jag har förstått det är forumet nu installerat på "root" alltså fjollhoj.se/

Jag gjorde så att jag lade phpbb3 i en separat mapp (fjollhoj.se/tre) och körde installationen där utan problem med databasprefixet "phpbb3_". Efter det gick jag in på fjollhoj.se/tre/install/ och klickade på konvert och knappade in user etc och befintligt databasprefix ("phpbb_forum") och körde igång den. Den gick igenom några steg för att sedan sluta i respektive felmeddelande (beroende på om det var på servern eller på min lokala maskin).

Jag har gjort backup på både databasen och alla filer som ligger på FTPn, så jag bör förhoppningsvis kunna återställa allt som jag ställer till med. (bortsett från inlägg som postas mellan backup och återställning så klart)
Användarens profilbild
Sinom
Verified
Administratör
Administratör
Inlägg: 11527
Blev medlem: 2010-11-04 21:24
Svar: 14

Re: Problem med uppgradering.

Inlägg av Sinom »

Testa med att gå till install/ i phpBB3-mappen och öppna install_convert.php

Lägg till i början utav filen:

Kod: Markera allt

set_time_limit(20);
Fungerar inte 20, så testa ett mindre tal.

Alltså precis under:

Kod: Markera allt

<?php
/**
*
* @package install
* @version $Id$
* @copyright (c) 2006 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/

/**
*/
Testa sedan att konvertera igen.

Hugs :ugeek:
Bild
Erik Nilsson
Medlem
Medlem
Inlägg: 16
Blev medlem: 2011-02-26 09:27
Svar: 0

Re: Problem med uppgradering.

Inlägg av Erik Nilsson »

Då kom jag bara kortare, tyvärr. :(

Direkt när jag öppnar install-sidan får jag detta meddelande:

[phpBB Debug] PHP Notice: in file /install/install_convert.php on line 14: set_time_limit(): Cannot set time limit due to system policy
[phpBB Debug] PHP Notice: in file /install/index.php on line 444: Cannot modify header information - headers already sent by (output started at /includes/functions.php:3706)
[phpBB Debug] PHP Notice: in file /install/index.php on line 445: Cannot modify header information - headers already sent by (output started at /includes/functions.php:3706)
[phpBB Debug] PHP Notice: in file /install/index.php on line 446: Cannot modify header information - headers already sent by (output started at /includes/functions.php:3706)
[phpBB Debug] PHP Notice: in file /install/index.php on line 447: Cannot modify header information - headers already sent by (output started at /includes/functions.php:3706)
Användarens profilbild
Sinom
Verified
Administratör
Administratör
Inlägg: 11527
Blev medlem: 2010-11-04 21:24
Svar: 14

Re: Problem med uppgradering.

Inlägg av Sinom »

Vad använde du för program när du ändrade i den filen?

Hugs :ugeek:
Bild
Erik Nilsson
Medlem
Medlem
Inlägg: 16
Blev medlem: 2011-02-26 09:27
Svar: 0

Re: Problem med uppgradering.

Inlägg av Erik Nilsson »

Context, kan det bli bekymmer för det?
Om ja, vad rekommenderar du?

// Erik
Peetra
Hedersmedlem
Hedersmedlem
Inlägg: 3281
Blev medlem: 2007-06-09 22:38
Svar: 0

Re: Problem med uppgradering.

Inlägg av Peetra »

Både jag och Sinom rekommenderar Notepad++ för windows: http://notepad-plus-plus.org/download

Jag vet inte vad Sinom funderat att kan vara problemet, så det kan ju hända att det inte är nåt som helst fel på Context heller.

Jag har tyvärr ingen erfarenhet av XAMPP, men som alla andra servrar, så borde du kunna ändra på alla tidslimitar på den, det som du tror är problemet alltså. Du har nog en php.ini-fil i XAMPP också. :)

Sen lite OT kanske... Det räcker tyvärr inte alltid på en hemmawindows-dator, så jag föreslår att du installerar Ubuntu som dualboot på din dator, så kan du sätta upp en riktig server på den. :ugeek:
Användarens profilbild
Sinom
Verified
Administratör
Administratör
Inlägg: 11527
Blev medlem: 2010-11-04 21:24
Svar: 14

Re: Problem med uppgradering.

Inlägg av Sinom »

Mycket riktigt Peetra! :wink:

Min första tanke var att du använt vanliga Notepad t.ex eller liknande, Context ska fungera fint, då det liknar Notepad++ väldigt mycket.
(Vanliga Notepad lägger till massa tecken, alltså ändrar formatet, så att filen inte fungerar för phpBB)

Kan du posta din install_convert.php i

Kod: Markera allt

-taggar här?

När du lägger in den koden jag nämnde längst upp i filen, så skall det se ut som följande:
[code]<?php
/**
*
* @package install
* @version $Id$
* @copyright (c) 2006 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/

/**
*/
set_time_limit(20);
if (!defined('IN_INSTALL'))
{
	// Someone has tried to access the file direct. This is not a good idea, so exit
	exit;
}
Samt resten av filen givetvis.

Om det ser ut som ovan bör installationen fungera som förut eller bättre.
(Detta var för att kunna uppgradera direkt på ditt forum hos one.com, då dom inte vill ändra i php.ini-filen)

För att lösa detta på din lokala server kan du gå till C:\xampp\php och öppna php.ini

Hitta:

Kod: Markera allt

; Maximum time (in seconds) for connect timeout. -1 means no limit
; http://php.net/mysql.connect-timeout
mysql.connect_timeout = 60
Ändra 60 till en högre nuffra och testa. :roll:
Peetra skrev:Sen lite OT kanske... Det räcker tyvärr inte alltid på en hemmawindows-dator, så jag föreslår att du installerar Ubuntu som dualboot på din dator, så kan du sätta upp en riktig server på den.
Jag tror han endast använder XAMPP för att testa lokalt. Istället för att ändra direkt på one.com. Men givetvis, alla borde MINST ha en dualboot med linux (gentoo) :wink:

Hugs :ugeek:
Bild
Erik Nilsson
Medlem
Medlem
Inlägg: 16
Blev medlem: 2011-02-26 09:27
Svar: 0

Re: Problem med uppgradering.

Inlägg av Erik Nilsson »

Jag håller på att testa XAMPP-konfigurationen nu och hoppas på det bästa. Får kanske testa det lokala med att begränsa den lokala install_convert.php också.

Så här ser den jag använder på one.com ut:

Kod: Markera allt

<?php
/**
*
* @package install
* @version $Id$
* @copyright (c) 2006 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/

/**
*/
set_time_limit(20);
if (!defined('IN_INSTALL'))
{
   // Someone has tried to access the file direct. This is not a good idea, so exit
   exit;
}

if (!empty($setmodules))
{
	$module[] = array(
		'module_type'		=> 'install',
		'module_title'		=> 'CONVERT',
		'module_filename'	=> substr(basename(__FILE__), 0, -strlen($phpEx)-1),
		'module_order'		=> 20,
		'module_subs'		=> '',
		'module_stages'		=> array('INTRO', 'SETTINGS', 'IN_PROGRESS', 'FINAL'),
		'module_reqs'		=> ''
	);
}

/**
* Class holding all convertor-specific details.
* @package install
*/
class convert
{
	var $options = array();

	var $convertor_tag = '';
	var $src_dbms = '';
	var $src_dbhost = '';
	var $src_dbport = '';
	var $src_dbuser = '';
	var $src_dbpasswd = '';
	var $src_dbname = '';
	var $src_table_prefix = '';

	var $convertor_data = array();
	var $tables = array();
	var $config_schema = array();
	var $convertor = array();
	var $src_truncate_statement = 'DELETE FROM ';
	var $truncate_statement = 'DELETE FROM ';

	var $fulltext_search;

	// Batch size, can be adjusted by the conversion file
	// For big boards a value of 6000 seems to be optimal
	var $batch_size = 2000;
	// Number of rows to be inserted at once (extended insert) if supported
	// For installations having enough memory a value of 60 may be good.
	var $num_wait_rows = 20;

	// Mysqls internal recoding engine messing up with our (better) functions? We at least support more encodings than mysql so should use it in favor.
	var $mysql_convert = false;

	var $p_master;

	function convert(&$p_master)
	{
		$this->p_master = &$p_master;
	}
}

/**
* Convert class for conversions
* @package install
*/
class install_convert extends module
{
	/**
	* Variables used while converting, they are accessible from the global variable $convert
	*/
	function install_convert(&$p_master)
	{
		$this->p_master = &$p_master;
	}

	function main($mode, $sub)
	{
		global $lang, $template, $phpbb_root_path, $phpEx, $cache, $config, $language, $table_prefix;
		global $convert;

		$this->tpl_name = 'install_convert';
		$this->mode = $mode;

		$convert = new convert($this->p_master);

		switch ($sub)
		{
			case 'intro':
				// Try opening config file
				// @todo If phpBB is not installed, we need to do a cut-down installation here
				// For now, we redirect to the installation script instead
				if (@file_exists($phpbb_root_path . 'config.' . $phpEx))
				{
					include($phpbb_root_path . 'config.' . $phpEx);
				}

				if (!defined('PHPBB_INSTALLED'))
				{
					$template->assign_vars(array(
						'S_NOT_INSTALLED'		=> true,
						'TITLE'					=> $lang['BOARD_NOT_INSTALLED'],
						'BODY'					=> sprintf($lang['BOARD_NOT_INSTALLED_EXPLAIN'], append_sid($phpbb_root_path . 'install/index.' . $phpEx, 'mode=install&language=' . $language)),
					));

					return;
				}

				require($phpbb_root_path . 'config.' . $phpEx);
				require($phpbb_root_path . 'includes/constants.' . $phpEx);
				require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
				require($phpbb_root_path . 'includes/functions_convert.' . $phpEx);

				$db = new $sql_db();
				$db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, true);
				unset($dbpasswd);

				// We need to fill the config to let internal functions correctly work
				$sql = 'SELECT *
					FROM ' . CONFIG_TABLE;
				$result = $db->sql_query($sql);

				$config = array();
				while ($row = $db->sql_fetchrow($result))
				{
					$config[$row['config_name']] = $row['config_value'];
				}
				$db->sql_freeresult($result);

				// Detect if there is already a conversion in progress at this point and offer to resume
				// It's quite possible that the user will get disconnected during a large conversion so they need to be able to resume it
				$new_conversion = request_var('new_conv', 0);

				if ($new_conversion)
				{
					$config['convert_progress'] = '';
					$config['convert_db_server'] = '';
					$config['convert_db_user'] = '';
					$db->sql_query('DELETE FROM ' . CONFIG_TABLE . "
						WHERE config_name = 'convert_progress'
							OR config_name = 'convert_db_server'
							OR config_name = 'convert_db_user'"
					);
				}

				// Let's see if there is a conversion in the works...
				$options = array();
				if (!empty($config['convert_progress']) && !empty($config['convert_db_server']) && !empty($config['convert_db_user']) && !empty($config['convert_options']))
				{
					$options = unserialize($config['convert_progress']);
					$options = array_merge($options, unserialize($config['convert_db_server']), unserialize($config['convert_db_user']), unserialize($config['convert_options']));
				}

				// This information should have already been checked once, but do it again for safety
				if (!empty($options) && !empty($options['tag']) &&
					isset($options['dbms']) &&
					isset($options['dbhost']) &&
					isset($options['dbport']) &&
					isset($options['dbuser']) &&
					isset($options['dbpasswd']) &&
					isset($options['dbname']) &&
					isset($options['table_prefix']))
				{
					$this->page_title = $lang['CONTINUE_CONVERT'];

					$template->assign_vars(array(
						'TITLE'			=> $lang['CONTINUE_CONVERT'],
						'BODY'			=> $lang['CONTINUE_CONVERT_BODY'],
						'L_NEW'			=> $lang['CONVERT_NEW_CONVERSION'],
						'L_CONTINUE'	=> $lang['CONTINUE_OLD_CONVERSION'],
						'S_CONTINUE'	=> true,

						'U_NEW_ACTION'		=> $this->p_master->module_url . "?mode={$this->mode}&sub=intro&new_conv=1&language=$language",
						'U_CONTINUE_ACTION'	=> $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag={$options['tag']}{$options['step']}&language=$language",
					));

					return;
				}

				$this->list_convertors($sub);

			break;

			case 'settings':
				$this->get_convert_settings($sub);
			break;

			case 'in_progress':
				$this->convert_data($sub);
			break;

			case 'final':
				$this->page_title = $lang['CONVERT_COMPLETE'];

				$template->assign_vars(array(
					'TITLE'		=> $lang['CONVERT_COMPLETE'],
					'BODY'		=> $lang['CONVERT_COMPLETE_EXPLAIN'],
				));

				// If we reached this step (conversion completed) we want to purge the cache and log the user out.
				// This is for making sure the session get not screwed due to the 3.0.x users table being completely new.
				$cache->purge();

				require($phpbb_root_path . 'config.' . $phpEx);
				require($phpbb_root_path . 'includes/constants.' . $phpEx);
				require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
				require($phpbb_root_path . 'includes/functions_convert.' . $phpEx);

				$db = new $sql_db();
				$db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, true);
				unset($dbpasswd);

				$sql = 'SELECT config_value
					FROM ' . CONFIG_TABLE . '
					WHERE config_name = \'search_type\'';
				$result = $db->sql_query($sql);

				if ($db->sql_fetchfield('config_value') != 'fulltext_mysql')
				{
					$template->assign_vars(array(
						'S_ERROR_BOX'	=> true,
						'ERROR_TITLE'	=> $lang['SEARCH_INDEX_UNCONVERTED'],
						'ERROR_MSG'		=> $lang['SEARCH_INDEX_UNCONVERTED_EXPLAIN'],
					));
				}

				switch ($db->sql_layer)
				{
					case 'sqlite':
					case 'firebird':
						$db->sql_query('DELETE FROM ' . SESSIONS_KEYS_TABLE);
						$db->sql_query('DELETE FROM ' . SESSIONS_TABLE);
					break;

					default:
						$db->sql_query('TRUNCATE TABLE ' . SESSIONS_KEYS_TABLE);
						$db->sql_query('TRUNCATE TABLE ' . SESSIONS_TABLE);
					break;
				}

			break;
		}
	}

	/**
	* Generate a list of all available conversion modules
	*/
	function list_convertors($sub)
	{
		global $lang, $language, $template, $phpbb_root_path, $phpEx;

		$this->page_title = $lang['SUB_INTRO'];

		$template->assign_vars(array(
			'TITLE'		=> $lang['CONVERT_INTRO'],
			'BODY'		=> $lang['CONVERT_INTRO_BODY'],

			'L_AUTHOR'					=> $lang['AUTHOR'],
			'L_AVAILABLE_CONVERTORS'	=> $lang['AVAILABLE_CONVERTORS'],
			'L_CONVERT'					=> $lang['CONVERT'],
			'L_NO_CONVERTORS'			=> $lang['NO_CONVERTORS'],
			'L_OPTIONS'					=> $lang['CONVERT_OPTIONS'],
			'L_SOFTWARE'				=> $lang['SOFTWARE'],
			'L_VERSION'					=> $lang['VERSION'],

			'S_LIST'	=> true,
		));

		$convertors = $sort = array();
		$get_info = true;

		$handle = @opendir('./convertors/');

		if (!$handle)
		{
			$this->error('Unable to access the convertors directory', __LINE__, __FILE__);
		}

		while ($entry = readdir($handle))
		{
			if (preg_match('/^convert_([a-z0-9_]+).' . $phpEx . '$/i', $entry, $m))
			{
				include('./convertors/' . $entry);
				if (isset($convertor_data))
				{
					$sort[strtolower($convertor_data['forum_name'])] = sizeof($convertors);

					$convertors[] = array(
						'tag'			=>	$m[1],
						'forum_name'	=>	$convertor_data['forum_name'],
						'version'		=>	$convertor_data['version'],
						'dbms'			=>	$convertor_data['dbms'],
						'dbhost'		=>	$convertor_data['dbhost'],
						'dbport'		=>	$convertor_data['dbport'],
						'dbuser'		=>	$convertor_data['dbuser'],
						'dbpasswd'		=>	$convertor_data['dbpasswd'],
						'dbname'		=>	$convertor_data['dbname'],
						'table_prefix'	=>	$convertor_data['table_prefix'],
						'author'		=>	$convertor_data['author']
					);
				}
				unset($convertor_data);
			}
		}
		closedir($handle);

		@ksort($sort);

		foreach ($sort as $void => $index)
		{
			$template->assign_block_vars('convertors', array(
				'AUTHOR'	=> $convertors[$index]['author'],
				'SOFTWARE'	=> $convertors[$index]['forum_name'],
				'VERSION'	=> $convertors[$index]['version'],

				'U_CONVERT'	=> $this->p_master->module_url . "?mode={$this->mode}&language=$language&sub=settings&tag=" . $convertors[$index]['tag'],
			));
		}
	}

	/**
	*/
	function get_convert_settings($sub)
	{
		global $lang, $language, $template, $db, $phpbb_root_path, $phpEx, $config, $cache;

		require($phpbb_root_path . 'config.' . $phpEx);
		require($phpbb_root_path . 'includes/constants.' . $phpEx);
		require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
		require($phpbb_root_path . 'includes/functions_convert.' . $phpEx);

		$db = new $sql_db();
		$db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, true);
		unset($dbpasswd);

		$this->page_title = $lang['STAGE_SETTINGS'];

		// We need to fill the config to let internal functions correctly work
		$sql = 'SELECT *
			FROM ' . CONFIG_TABLE;
		$result = $db->sql_query($sql);

		$config = array();
		while ($row = $db->sql_fetchrow($result))
		{
			$config[$row['config_name']] = $row['config_value'];
		}
		$db->sql_freeresult($result);

		$convertor_tag = request_var('tag', '');

		if (empty($convertor_tag))
		{
			$this->p_master->error($lang['NO_CONVERT_SPECIFIED'], __LINE__, __FILE__);
		}
		$get_info = true;

		// check security implications of direct inclusion
		$convertor_tag = basename($convertor_tag);
		if (!file_exists('./convertors/convert_' . $convertor_tag . '.' . $phpEx))
		{
			$this->p_master->error($lang['CONVERT_NOT_EXIST'], __LINE__, __FILE__);
		}

		include('./convertors/convert_' . $convertor_tag . '.' . $phpEx);

		// The test_file is a file that should be present in the location of the old board.
		if (!isset($test_file))
		{
			$this->p_master->error($lang['DEV_NO_TEST_FILE'], __LINE__, __FILE__);
		}

		$submit = (isset($_POST['submit'])) ? true : false;

		$src_dbms			= request_var('src_dbms', $convertor_data['dbms']);
		$src_dbhost			= request_var('src_dbhost', $convertor_data['dbhost']);
		$src_dbport			= request_var('src_dbport', $convertor_data['dbport']);
		$src_dbuser			= request_var('src_dbuser', $convertor_data['dbuser']);
		$src_dbpasswd		= request_var('src_dbpasswd', $convertor_data['dbpasswd']);
		$src_dbname			= request_var('src_dbname', $convertor_data['dbname']);
		$src_table_prefix	= request_var('src_table_prefix', $convertor_data['table_prefix']);
		$forum_path			= request_var('forum_path', $convertor_data['forum_path']);
		$refresh			= request_var('refresh', 1);

		// Default URL of the old board
		// @todo Are we going to use this for attempting to convert URL references in posts, or should we remove it?
		//		-> We should convert old urls to the new relative urls format
		// $src_url = request_var('src_url', 'Not in use at the moment');

		// strip trailing slash from old forum path
		$forum_path = (strlen($forum_path) && $forum_path[strlen($forum_path) - 1] == '/') ? substr($forum_path, 0, -1) : $forum_path;

		$error = array();
		if ($submit)
		{
			if (!@file_exists('./../' . $forum_path . '/' . $test_file))
			{
				$error[] = sprintf($lang['COULD_NOT_FIND_PATH'], $forum_path);
			}

			$connect_test = false;
			$available_dbms = get_available_dbms(false, true, true);

			if (!isset($available_dbms[$src_dbms]) || !$available_dbms[$src_dbms]['AVAILABLE'])
			{
				$error['db'][] = $lang['INST_ERR_NO_DB'];
				$connect_test = false;
			}
			else
			{
				$connect_test = connect_check_db(true, $error, $available_dbms[$src_dbms], $src_table_prefix, $src_dbhost, $src_dbuser, htmlspecialchars_decode($src_dbpasswd), $src_dbname, $src_dbport, true, ($src_dbms == $dbms) ? false : true, false);
			}

			// The forum prefix of the old and the new forum can only be the same if two different databases are used.
			if ($src_table_prefix == $table_prefix && $src_dbms == $dbms && $src_dbhost == $dbhost && $src_dbport == $dbport && $src_dbname == $dbname)
			{
				$error[] = sprintf($lang['TABLE_PREFIX_SAME'], $src_table_prefix);
			}

			// Check table prefix
			if (!sizeof($error))
			{
				// initiate database connection to old db if old and new db differ
				global $src_db, $same_db;
				$src_db = $same_db = false;

				if ($src_dbms != $dbms || $src_dbhost != $dbhost || $src_dbport != $dbport || $src_dbname != $dbname || $src_dbuser != $dbuser)
				{
					$sql_db = 'dbal_' . $src_dbms;
					$src_db = new $sql_db();
					$src_db->sql_connect($src_dbhost, $src_dbuser, htmlspecialchars_decode($src_dbpasswd), $src_dbname, $src_dbport, false, true);
					$same_db = false;
				}
				else
				{
					$src_db = $db;
					$same_db = true;
				}

				$src_db->sql_return_on_error(true);
				$db->sql_return_on_error(true);

				// Try to select one row from the first table to see if the prefix is OK
				$result = $src_db->sql_query_limit('SELECT * FROM ' . $src_table_prefix . $tables[0], 1);

				if (!$result)
				{
					$prefixes = array();

					$tables_existing = get_tables($src_db);
					$tables_existing = array_map('strtolower', $tables_existing);
					foreach ($tables_existing as $table_name)
					{
						compare_table($tables, $table_name, $prefixes);
					}
					unset($tables_existing);

					foreach ($prefixes as $prefix => $count)
					{
						if ($count >= sizeof($tables))
						{
							$possible_prefix = $prefix;
							break;
						}
					}

					$msg = '';
					if (!empty($convertor_data['table_prefix']))
					{
						$msg .= sprintf($lang['DEFAULT_PREFIX_IS'], $convertor_data['forum_name'], $convertor_data['table_prefix']);
					}

					if (!empty($possible_prefix))
					{
						$msg .= '<br />';
						$msg .= ($possible_prefix == '*') ? $lang['BLANK_PREFIX_FOUND'] : sprintf($lang['PREFIX_FOUND'], $possible_prefix);
						$src_table_prefix = ($possible_prefix == '*') ? '' : $possible_prefix;
					}

					$error[] = $msg;
				}
				$src_db->sql_freeresult($result);
				$src_db->sql_return_on_error(false);
			}

			if (!sizeof($error))
			{
				// Save convertor Status
				set_config('convert_progress', serialize(array(
					'step'			=> '',
					'table_prefix'	=> $src_table_prefix,
					'tag'			=> $convertor_tag,
				)), true);
				set_config('convert_db_server', serialize(array(
					'dbms'			=> $src_dbms,
					'dbhost'		=> $src_dbhost,
					'dbport'		=> $src_dbport,
					'dbname'		=> $src_dbname,
				)), true);
				set_config('convert_db_user', serialize(array(
					'dbuser'		=> $src_dbuser,
					'dbpasswd'		=> $src_dbpasswd,
				)), true);

				// Save options
				set_config('convert_options', serialize(array('forum_path' => './../' . $forum_path, 'refresh' => $refresh)), true);

				$template->assign_block_vars('checks', array(
					'TITLE'		=> $lang['VERIFY_OPTIONS'],
					'RESULT'	=> $lang['CONVERT_SETTINGS_VERIFIED'],
				));

				$template->assign_vars(array(
					'L_SUBMIT'	=> $lang['BEGIN_CONVERT'],
//					'S_HIDDEN'	=> $s_hidden_fields,
					'U_ACTION'	=> $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag=$convertor_tag&language=$language",
				));

				return;
			}
			else
			{
				$template->assign_block_vars('checks', array(
					'TITLE'		=> $lang['VERIFY_OPTIONS'],
					'RESULT'	=> '<b style="color:red">' . implode('<br />', $error) . '</b>',
				));
			}
		} // end submit

		foreach ($this->convert_options as $config_key => $vars)
		{
			if (!is_array($vars) && strpos($config_key, 'legend') === false)
			{
				continue;
			}

			if (strpos($config_key, 'legend') !== false)
			{
				$template->assign_block_vars('options', array(
					'S_LEGEND'		=> true,
					'LEGEND'		=> $lang[$vars])
				);

				continue;
			}

			$options = isset($vars['options']) ? $vars['options'] : '';

			$template->assign_block_vars('options', array(
				'KEY'			=> $config_key,
				'TITLE'			=> $lang[$vars['lang']],
				'S_EXPLAIN'		=> $vars['explain'],
				'S_LEGEND'		=> false,
				'TITLE_EXPLAIN'	=> ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '',
				'CONTENT'		=> $this->p_master->input_field($config_key, $vars['type'], $$config_key, $options),
				)
			);
		}

		$template->assign_vars(array(
			'TITLE'		=> $lang['STAGE_SETTINGS'],
			'BODY'		=> $lang['CONV_OPTIONS_BODY'],
			'L_SUBMIT'	=> $lang['BEGIN_CONVERT'],
			'U_ACTION'	=> $this->p_master->module_url . "?mode={$this->mode}&sub=settings&tag=$convertor_tag&language=$language",
		));
	}

	/**
	* The function which does the actual work (or dispatches it to the relevant places)
	*/
	function convert_data($sub)
	{
		global $template, $user, $phpbb_root_path, $phpEx, $db, $lang, $config, $cache;
		global $convert, $convert_row, $message_parser, $skip_rows, $language;

		require($phpbb_root_path . 'config.' . $phpEx);
		require($phpbb_root_path . 'includes/constants.' . $phpEx);
		require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
		require($phpbb_root_path . 'includes/functions_convert.' . $phpEx);

		$db = new $sql_db();
		$db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, true);
		unset($dbpasswd);

		$sql = 'SELECT *
			FROM ' . CONFIG_TABLE;
		$result = $db->sql_query($sql);

		$config = array();
		while ($row = $db->sql_fetchrow($result))
		{
			$config[$row['config_name']] = $row['config_value'];
		}
		$db->sql_freeresult($result);

		// Override a couple of config variables for the duration
		$config['max_quote_depth'] = 0;

		// @todo Need to confirm that max post length in source is <= max post length in destination or there may be interesting formatting issues
		$config['max_post_chars'] = $config['min_post_chars'] = 0;

		// Set up a user as well. We _should_ have enough of a database here at this point to do this
		// and it helps for any core code we call
		$user->session_begin();
		$user->page = $user->extract_current_page($phpbb_root_path);

		// This is a little bit of a fudge, but it allows the language entries to be available to the
		// core code without us loading them again
		$user->lang = &$lang;

		$this->page_title = $user->lang['STAGE_IN_PROGRESS'];

		$convert->options = array();
		if (isset($config['convert_progress']))
		{
			$convert->options = unserialize($config['convert_progress']);
			$convert->options = array_merge($convert->options, unserialize($config['convert_db_server']), unserialize($config['convert_db_user']), unserialize($config['convert_options']));
		}

		// This information should have already been checked once, but do it again for safety
		if (empty($convert->options) || empty($convert->options['tag']) ||
			!isset($convert->options['dbms']) ||
			!isset($convert->options['dbhost']) ||
			!isset($convert->options['dbport']) ||
			!isset($convert->options['dbuser']) ||
			!isset($convert->options['dbpasswd']) ||
			!isset($convert->options['dbname']) ||
			!isset($convert->options['table_prefix']))
		{
			$this->p_master->error($user->lang['NO_CONVERT_SPECIFIED'], __LINE__, __FILE__);
		}

		// Make some short variables accessible, for easier referencing
		$convert->convertor_tag = basename($convert->options['tag']);
		$convert->src_dbms = $convert->options['dbms'];
		$convert->src_dbhost = $convert->options['dbhost'];
		$convert->src_dbport = $convert->options['dbport'];
		$convert->src_dbuser = $convert->options['dbuser'];
		$convert->src_dbpasswd = $convert->options['dbpasswd'];
		$convert->src_dbname = $convert->options['dbname'];
		$convert->src_table_prefix = $convert->options['table_prefix'];

		// initiate database connection to old db if old and new db differ
		global $src_db, $same_db;
		$src_db = $same_db = null;
		if ($convert->src_dbms != $dbms || $convert->src_dbhost != $dbhost || $convert->src_dbport != $dbport || $convert->src_dbname != $dbname || $convert->src_dbuser != $dbuser)
		{
			if ($convert->src_dbms != $dbms)
			{
				require($phpbb_root_path . 'includes/db/' . $convert->src_dbms . '.' . $phpEx);
			}
			$sql_db = 'dbal_' . $convert->src_dbms;
			$src_db = new $sql_db();
			$src_db->sql_connect($convert->src_dbhost, $convert->src_dbuser, htmlspecialchars_decode($convert->src_dbpasswd), $convert->src_dbname, $convert->src_dbport, false, true);
			$same_db = false;
		}
		else
		{
			$src_db = $db;
			$same_db = true;
		}

		$convert->mysql_convert = false;
		switch ($src_db->sql_layer)
		{
			case 'sqlite':
			case 'firebird':
				$convert->src_truncate_statement = 'DELETE FROM ';
			break;

			// Thanks MySQL, for silently converting...
			case 'mysql':
			case 'mysql4':
				if (version_compare($src_db->sql_server_info(true, false), '4.1.3', '>='))
				{
					$convert->mysql_convert = true;
				}
				$convert->src_truncate_statement = 'TRUNCATE TABLE ';
			break;

			case 'mysqli':
				$convert->mysql_convert = true;
				$convert->src_truncate_statement = 'TRUNCATE TABLE ';
			break;

			default:
				$convert->src_truncate_statement = 'TRUNCATE TABLE ';
			break;
		}

		if ($convert->mysql_convert && !$same_db)
		{
			$src_db->sql_query("SET NAMES 'binary'");
		}

		switch ($db->sql_layer)
		{
			case 'sqlite':
			case 'firebird':
				$convert->truncate_statement = 'DELETE FROM ';
			break;

			default:
				$convert->truncate_statement = 'TRUNCATE TABLE ';
			break;
		}

		$get_info = false;

		// check security implications of direct inclusion
		if (!file_exists('./convertors/convert_' . $convert->convertor_tag . '.' . $phpEx))
		{
			$this->p_master->error($user->lang['CONVERT_NOT_EXIST'], __LINE__, __FILE__);
		}

		if (file_exists('./convertors/functions_' . $convert->convertor_tag . '.' . $phpEx))
		{
			include('./convertors/functions_' . $convert->convertor_tag . '.' . $phpEx);
		}

		$get_info = true;
		include('./convertors/convert_' . $convert->convertor_tag . '.' . $phpEx);

		// Map some variables...
		$convert->convertor_data = $convertor_data;
		$convert->tables = $tables;
		$convert->config_schema = $config_schema;

		// Now include the real data
		$get_info = false;
		include('./convertors/convert_' . $convert->convertor_tag . '.' . $phpEx);

		$convert->convertor_data = $convertor_data;
		$convert->tables = $tables;
		$convert->config_schema = $config_schema;
		$convert->convertor = $convertor;

		// The test_file is a file that should be present in the location of the old board.
		if (!file_exists($convert->options['forum_path'] . '/' . $test_file))
		{
			$this->p_master->error(sprintf($user->lang['COULD_NOT_FIND_PATH'], $convert->options['forum_path']), __LINE__, __FILE__);
		}

		$search_type = basename(trim($config['search_type']));

		// For conversions we are a bit less strict and set to a search backend we know exist...
		if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx))
		{
			$search_type = 'fulltext_native';
			set_config('search_type', $search_type);
		}

		if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx))
		{
			trigger_error('NO_SUCH_SEARCH_MODULE');
		}

		require($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx);

		$error = false;
		$convert->fulltext_search = new $search_type($error);

		if ($error)
		{
			trigger_error($error);
		}

		include($phpbb_root_path . 'includes/message_parser.' . $phpEx);
		$message_parser = new parse_message();

		$jump = request_var('jump', 0);
		$final_jump = request_var('final_jump', 0);
		$sync_batch = request_var('sync_batch', -1);
		$last_statement = request_var('last', 0);

		// We are running sync...
		if ($sync_batch >= 0)
		{
			$this->sync_forums($sync_batch);
			return;
		}

		if ($jump)
		{
			$this->jump($jump, $last_statement);
			return;
		}

		if ($final_jump)
		{
			$this->final_jump($final_jump);
			return;
		}

		$current_table = request_var('current_table', 0);
		$old_current_table = min(-1, $current_table - 1);
		$skip_rows = request_var('skip_rows', 0);

		if (!$current_table && !$skip_rows)
		{
			if (empty($_REQUEST['confirm']))
			{
				// If avatars / ranks / smilies folders are specified make sure they are writable
				$bad_folders = array();

				$local_paths = array(
					'avatar_path'			=> path($config['avatar_path']),
					'avatar_gallery_path'	=> path($config['avatar_gallery_path']),
					'icons_path'			=> path($config['icons_path']),
					'ranks_path'			=> path($config['ranks_path']),
					'smilies_path'			=> path($config['smilies_path'])
				);

				foreach ($local_paths as $folder => $local_path)
				{
					if (isset($convert->convertor[$folder]))
					{
						if (empty($convert->convertor['test_file']))
						{
							// test_file is mandantory at the moment so this should never be reached, but just in case...
							$this->p_master->error($user->lang['DEV_NO_TEST_FILE'], __LINE__, __FILE__);
						}

						if (!$local_path || !phpbb_is_writable($phpbb_root_path . $local_path))
						{
							if (!$local_path)
							{
								$bad_folders[] = sprintf($user->lang['CONFIG_PHPBB_EMPTY'], $folder);
							}
							else
							{
								$bad_folders[] = $local_path;
							}
						}
					}
				}

				if (sizeof($bad_folders))
				{
					$msg = (sizeof($bad_folders) == 1) ? $user->lang['MAKE_FOLDER_WRITABLE'] : $user->lang['MAKE_FOLDERS_WRITABLE'];
					sort($bad_folders);
					$this->p_master->error(sprintf($msg, implode('<br />', $bad_folders)), __LINE__, __FILE__, true);

					$template->assign_vars(array(
						'L_SUBMIT'	=> $user->lang['INSTALL_TEST'],
						'U_ACTION'	=> $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag={$convert->convertor_tag}&language=$language",
					));
					return;
				}

				// Grab all the tables used in convertor
				$missing_tables = $tables_list = $aliases = array();

				foreach ($convert->convertor['schema'] as $schema)
				{
					// Skip those not used (because of addons/plugins not detected)
					if (!$schema['target'])
					{
						continue;
					}

					foreach ($schema as $key => $val)
					{
						// we're dealing with an array like:
						// array('forum_status',			'forums.forum_status',				'is_item_locked')
						if (is_int($key) && !empty($val[1]))
						{
							$temp_data = $val[1];
							if (!is_array($temp_data))
							{
								$temp_data = array($temp_data);
							}

							foreach ($temp_data as $val)
							{
								if (preg_match('/([a-z0-9_]+)\.([a-z0-9_]+)\)* ?A?S? ?([a-z0-9_]*?)\.?([a-z0-9_]*)$/i', $val, $m))
								{
									$table = $convert->src_table_prefix . $m[1];
									$tables_list[$table] = $table;

									if (!empty($m[3]))
									{
										$aliases[] = $convert->src_table_prefix . $m[3];
									}
								}
							}
						}
						// 'left_join'		=> 'topics LEFT JOIN vote_desc ON topics.topic_id = vote_desc.topic_id AND topics.topic_vote = 1'
						else if ($key == 'left_join')
						{
							// Convert the value if it wasn't an array already.
							if (!is_array($val))
							{
								$val = array($val);
							}

							for ($j = 0; $j < sizeof($val); ++$j)
							{
								if (preg_match('/LEFT JOIN ([a-z0-9_]+) AS ([a-z0-9_]+)/i', $val[$j], $m))
								{
									$table = $convert->src_table_prefix . $m[1];
									$tables_list[$table] = $table;

									if (!empty($m[2]))
									{
										$aliases[] = $convert->src_table_prefix . $m[2];
									}
								}
							}
						}
					}
				}

				// Remove aliased tables from $tables_list
				foreach ($aliases as $alias)
				{
					unset($tables_list[$alias]);
				}

				// Check if the tables that we need exist
				$src_db->sql_return_on_error(true);
				foreach ($tables_list as $table => $null)
				{
					$sql = 'SELECT 1 FROM ' . $table;
					$_result = $src_db->sql_query_limit($sql, 1);

					if (!$_result)
					{
						$missing_tables[] = $table;
					}
					$src_db->sql_freeresult($_result);
				}
				$src_db->sql_return_on_error(false);

				// Throw an error if some tables are missing
				// We used to do some guessing here, but since we have a suggestion of possible values earlier, I don't see it adding anything here to do it again

				if (sizeof($missing_tables) == sizeof($tables_list))
				{
					$this->p_master->error($user->lang['NO_TABLES_FOUND'] . ' ' . $user->lang['CHECK_TABLE_PREFIX'], __LINE__, __FILE__);
				}
				else if (sizeof($missing_tables))
				{
					$this->p_master->error(sprintf($user->lang['TABLES_MISSING'], implode(', ', $missing_tables)) . '<br /><br />' . $user->lang['CHECK_TABLE_PREFIX'], __LINE__, __FILE__);
				}

				$url = $this->save_convert_progress('&confirm=1');
				$msg = $user->lang['PRE_CONVERT_COMPLETE'];

				if ($convert->convertor_data['author_notes'])
				{
					$msg .= '</p><p>' . sprintf($user->lang['AUTHOR_NOTES'], $convert->convertor_data['author_notes']);
				}

				$template->assign_vars(array(
					'L_SUBMIT'		=> $user->lang['CONTINUE_CONVERT'],
					'L_MESSAGE'		=> $msg,
					'U_ACTION'		=> $url,
				));

				return;
			} // if (empty($_REQUEST['confirm']))

			$template->assign_block_vars('checks', array(
				'S_LEGEND'		=> true,
				'LEGEND'		=> $user->lang['STARTING_CONVERT'],
			));

			// Convert the config table and load the settings of the old board
			if (!empty($convert->config_schema))
			{
				restore_config($convert->config_schema);

				// Override a couple of config variables for the duration
				$config['max_quote_depth'] = 0;

				// @todo Need to confirm that max post length in source is <= max post length in destination or there may be interesting formatting issues
				$config['max_post_chars'] = $config['min_post_chars'] = 0;
			}

			$template->assign_block_vars('checks', array(
				'TITLE'		=> $user->lang['CONFIG_CONVERT'],
				'RESULT'	=> $user->lang['DONE'],
			));

			// Now process queries and execute functions that have to be executed prior to the conversion
			if (!empty($convert->convertor['execute_first']))
			{
				eval($convert->convertor['execute_first']);
			}

			if (!empty($convert->convertor['query_first']))
			{
				if (!is_array($convert->convertor['query_first']))
				{
					$convert->convertor['query_first'] = array('target', array($convert->convertor['query_first']));
				}
				else if (!is_array($convert->convertor['query_first'][0]))
				{
					$convert->convertor['query_first'] = array(array($convert->convertor['query_first'][0], $convert->convertor['query_first'][1]));
				}

				foreach ($convert->convertor['query_first'] as $query_first)
				{
					if ($query_first[0] == 'src')
					{
						if ($convert->mysql_convert && $same_db)
						{
							$src_db->sql_query("SET NAMES 'binary'");
						}

						$src_db->sql_query($query_first[1]);

						if ($convert->mysql_convert && $same_db)
						{
							$src_db->sql_query("SET NAMES 'utf8'");
						}
					}
					else
					{
						$db->sql_query($query_first[1]);
					}
				}
			}

			$template->assign_block_vars('checks', array(
				'TITLE'		=> $user->lang['PREPROCESS_STEP'],
				'RESULT'	=> $user->lang['DONE'],
			));
		} // if (!$current_table && !$skip_rows)

		$template->assign_block_vars('checks', array(
			'S_LEGEND'		=> true,
			'LEGEND'		=> $user->lang['FILLING_TABLES'],
		));

		// This loop takes one target table and processes it
		while ($current_table < sizeof($convert->convertor['schema']))
		{
			$schema = $convert->convertor['schema'][$current_table];

			// The target table isn't set, this can be because a module (for example the attachement mod) is taking care of this.
			if (empty($schema['target']))
			{
				$current_table++;
				continue;
			}

			$template->assign_block_vars('checks', array(
				'TITLE'	=> sprintf($user->lang['FILLING_TABLE'], $schema['target']),
			));

			// This is only the case when we first start working on the tables.
			if (!$skip_rows)
			{
				// process execute_first and query_first for this table...
				if (!empty($schema['execute_first']))
				{
					eval($schema['execute_first']);
				}

				if (!empty($schema['query_first']))
				{
					if (!is_array($schema['query_first']))
					{
						$schema['query_first'] = array('target', array($schema['query_first']));
					}
					else if (!is_array($schema['query_first'][0]))
					{
						$schema['query_first'] = array(array($schema['query_first'][0], $schema['query_first'][1]));
					}

					foreach ($schema['query_first'] as $query_first)
					{
						if ($query_first[0] == 'src')
						{
							if ($convert->mysql_convert && $same_db)
							{
								$src_db->sql_query("SET NAMES 'binary'");
							}
							$src_db->sql_query($query_first[1]);
							if ($convert->mysql_convert && $same_db)
							{
								$src_db->sql_query("SET NAMES 'utf8'");
							}
						}
						else
						{
							$db->sql_query($query_first[1]);
						}
					}
				}

				if (!empty($schema['autoincrement']))
				{
					switch ($db->sql_layer)
					{
						case 'postgres':
							$db->sql_query("SELECT SETVAL('" . $schema['target'] . "_seq',(select case when max(" . $schema['autoincrement'] . ")>0 then max(" . $schema['autoincrement'] . ")+1 else 1 end from " . $schema['target'] . '));');
						break;

						case 'oracle':
							$result = $db->sql_query('SELECT MAX(' . $schema['autoincrement'] . ') as max_id FROM ' . $schema['target']);
							$row = $db->sql_fetchrow($result);
							$db->sql_freeresult($result);

							$largest_id = (int) $row['max_id'];

							if ($largest_id)
							{
								$db->sql_query('DROP SEQUENCE ' . $schema['target'] . '_seq');
								$db->sql_query('CREATE SEQUENCE ' . $schema['target'] . '_seq START WITH ' . ($largest_id + 1));
							}
						break;
					}
				}
			}

			// Process execute_always for this table
			// This is for code which needs to be executed on every pass of this table if
			// it gets split because of time restrictions
			if (!empty($schema['execute_always']))
			{
				eval($schema['execute_always']);
			}

			//
			// Set up some variables
			//
			// $waiting_rows	holds rows for multirows insertion (MySQL only)
			// $src_tables		holds unique tables with aliases to select from
			// $src_fields		will quickly refer source fields (or aliases) corresponding to the current index
			// $select_fields	holds the names of the fields to retrieve
			//

			$sql_data = array(
				'source_fields'		=> array(),
				'target_fields'		=> array(),
				'source_tables'		=> array(),
				'select_fields'		=> array(),
			);

			// This statement is building the keys for later insertion.
			$insert_query = $this->build_insert_query($schema, $sql_data, $current_table);

			// If no source table is affected, we skip the table
			if (empty($sql_data['source_tables']))
			{
				$skip_rows = 0;
				$current_table++;
				continue;
			}

			$distinct = (!empty($schema['distinct'])) ? 'DISTINCT ' : '';

			$sql = 'SELECT ' . $distinct . implode(', ', $sql_data['select_fields']) . " \nFROM " . implode(', ', $sql_data['source_tables']);

			// Where
			$sql .= (!empty($schema['where'])) ? "\nWHERE (" . $schema['where'] . ')' : '';

			// Group By
			if (!empty($schema['group_by']))
			{
				$schema['group_by'] = array($schema['group_by']);
				foreach ($sql_data['select_fields'] as $select)
				{
					$alias = strpos(strtolower($select), ' as ');
					$select = ($alias) ? substr($select, 0, $alias) : $select;
					if (!in_array($select, $schema['group_by']))
					{
						$schema['group_by'][] = $select;
					}
				}
			}
			$sql .= (!empty($schema['group_by'])) ? "\nGROUP BY " . implode(', ', $schema['group_by']) : '';

			// Having
			$sql .= (!empty($schema['having'])) ? "\nHAVING " . $schema['having'] : '';

			// Order By
			if (empty($schema['order_by']) && !empty($schema['primary']))
			{
				$schema['order_by'] = $schema['primary'];
			}
			$sql .= (!empty($schema['order_by'])) ? "\nORDER BY " . $schema['order_by'] : '';

			// Counting basically holds the amount of rows processed.
			$counting = -1;
			$batch_time = 0;

			while ($counting === -1 || ($counting >= $convert->batch_size && still_on_time()))
			{
				$old_current_table = $current_table;

				$rows = '';
				$waiting_rows = array();

				if (!empty($batch_time))
				{
					$mtime = explode(' ', microtime());
					$mtime = $mtime[0] + $mtime[1];
					$rows = ceil($counting/($mtime - $batch_time)) . " rows/s ($counting rows) | ";
				}

				$template->assign_block_vars('checks', array(
					'TITLE'		=> "skip_rows = $skip_rows",
					'RESULT'	=> $rows . ((defined('DEBUG_EXTRA') && function_exists('memory_get_usage')) ? ceil(memory_get_usage()/1024) . ' ' . $user->lang['KIB'] : ''),
				));

				$mtime = explode(' ', microtime());
				$batch_time = $mtime[0] + $mtime[1];

				if ($convert->mysql_convert && $same_db)
				{
					$src_db->sql_query("SET NAMES 'binary'");
				}

				// Take skip rows into account and only fetch batch_size amount of rows
				$___result = $src_db->sql_query_limit($sql, $convert->batch_size, $skip_rows);

				if ($convert->mysql_convert && $same_db)
				{
					$src_db->sql_query("SET NAMES 'utf8'");
				}

				// This loop processes each row
				$counting = 0;

				$convert->row = $convert_row = array();

				if (!empty($schema['autoincrement']))
				{
					switch ($db->sql_layer)
					{
						case 'mssql':
						case 'mssql_odbc':
						case 'mssqlnative':
							$db->sql_query('SET IDENTITY_INSERT ' . $schema['target'] . ' ON');
						break;
					}
				}

				// Now handle the rows until time is over or no more rows to process...
				while ($counting === 0 || still_on_time())
				{
					$convert_row = $src_db->sql_fetchrow($___result);

					if (!$convert_row)
					{
						// move to the next batch or table
						break;
					}

					// With this we are able to always save the last state
					$convert->row = $convert_row;

					// Increment the counting variable, it stores the number of rows we have processed
					$counting++;

					$insert_values = array();

					$sql_flag = $this->process_row($schema, $sql_data, $insert_values);

					if ($sql_flag === true)
					{
						switch ($db->sql_layer)
						{
							// If MySQL, we'll wait to have num_wait_rows rows to submit at once
							case 'mysql':
							case 'mysql4':
							case 'mysqli':
								$waiting_rows[] = '(' . implode(', ', $insert_values) . ')';

								if (sizeof($waiting_rows) >= $convert->num_wait_rows)
								{
									$errored = false;

									$db->sql_return_on_error(true);

									if (!$db->sql_query($insert_query . implode(', ', $waiting_rows)))
									{
										$errored = true;
									}
									$db->sql_return_on_error(false);

									if ($errored)
									{
										$db->sql_return_on_error(true);

										// Because it errored out we will try to insert the rows one by one... most of the time this
										// is caused by duplicate entries - but we also do not want to miss one...
										foreach ($waiting_rows as $waiting_sql)
										{
											if (!$db->sql_query($insert_query . $waiting_sql))
											{
												$this->p_master->db_error($user->lang['DB_ERR_INSERT'], htmlspecialchars($insert_query . $waiting_sql) . '<br /><br />' . htmlspecialchars(print_r($db->_sql_error(), true)), __LINE__, __FILE__, true);
											}
										}

										$db->sql_return_on_error(false);
									}

									$waiting_rows = array();
								}

							break;

							default:
								$insert_sql = $insert_query . '(' . implode(', ', $insert_values) . ')';

								$db->sql_return_on_error(true);

								if (!$db->sql_query($insert_sql))
								{
									$this->p_master->db_error($user->lang['DB_ERR_INSERT'], htmlspecialchars($insert_sql) . '<br /><br />' . htmlspecialchars(print_r($db->_sql_error(), true)), __LINE__, __FILE__, true);
								}
								$db->sql_return_on_error(false);

								$waiting_rows = array();

							break;
						}
					}

					$skip_rows++;
				}
				$src_db->sql_freeresult($___result);

				// We might still have some rows waiting
				if (sizeof($waiting_rows))
				{
					$errored = false;
					$db->sql_return_on_error(true);

					if (!$db->sql_query($insert_query . implode(', ', $waiting_rows)))
					{
						$errored = true;
					}
					$db->sql_return_on_error(false);

					if ($errored)
					{
						$db->sql_return_on_error(true);

						// Because it errored out we will try to insert the rows one by one... most of the time this
						// is caused by duplicate entries - but we also do not want to miss one...
						foreach ($waiting_rows as $waiting_sql)
						{
							$db->sql_query($insert_query . $waiting_sql);
							$this->p_master->db_error($user->lang['DB_ERR_INSERT'], htmlspecialchars($insert_query . $waiting_sql) . '<br /><br />' . htmlspecialchars(print_r($db->_sql_error(), true)), __LINE__, __FILE__, true);
						}

						$db->sql_return_on_error(false);
					}

					$waiting_rows = array();
				}

				if (!empty($schema['autoincrement']))
				{
					switch ($db->sql_layer)
					{
						case 'mssql':
						case 'mssql_odbc':
						case 'mssqlnative':
							$db->sql_query('SET IDENTITY_INSERT ' . $schema['target'] . ' OFF');
						break;

						case 'postgres':
							$db->sql_query("SELECT SETVAL('" . $schema['target'] . "_seq',(select case when max(" . $schema['autoincrement'] . ")>0 then max(" . $schema['autoincrement'] . ")+1 else 1 end from " . $schema['target'] . '));');
						break;

						case 'oracle':
							$result = $db->sql_query('SELECT MAX(' . $schema['autoincrement'] . ') as max_id FROM ' . $schema['target']);
							$row = $db->sql_fetchrow($result);
							$db->sql_freeresult($result);

							$largest_id = (int) $row['max_id'];

							if ($largest_id)
							{
								$db->sql_query('DROP SEQUENCE ' . $schema['target'] . '_seq');
								$db->sql_query('CREATE SEQUENCE ' . $schema['target'] . '_seq START WITH ' . ($largest_id + 1));
							}
						break;
					}
				}
			}

			// When we reach this point, either the current table has been processed or we're running out of time.
			if (still_on_time() && $counting < $convert->batch_size/* && !defined('DEBUG_EXTRA')*/)
			{
				$skip_rows = 0;
				$current_table++;
			}
			else
			{/*
				if (still_on_time() && $counting < $convert->batch_size)
				{
					$skip_rows = 0;
					$current_table++;
				}*/

				// Looks like we ran out of time.
				$url = $this->save_convert_progress('&current_table=' . $current_table . '&skip_rows=' . $skip_rows);

				$current_table++;
//				$percentage = ($skip_rows == 0) ? 0 : floor(100 / ($total_rows / $skip_rows));

				$msg = sprintf($user->lang['STEP_PERCENT_COMPLETED'], $current_table, sizeof($convert->convertor['schema']));

				$template->assign_vars(array(
					'L_MESSAGE'		=> $msg,
					'L_SUBMIT'		=> $user->lang['CONTINUE_CONVERT'],
					'U_ACTION'		=> $url,
				));

				$this->meta_refresh($url);
				return;
			}
		}

		// Process execute_last then we'll be done
		$url = $this->save_convert_progress('&jump=1');

		$template->assign_vars(array(
			'L_SUBMIT'		=> $user->lang['FINAL_STEP'],
			'U_ACTION'		=> $url,
		));

		$this->meta_refresh($url);
		return;
	}

	
Tyvärr rymdes inte allt i ett inlägg så fortsättningen kommer i nästa.
Erik Nilsson
Medlem
Medlem
Inlägg: 16
Blev medlem: 2011-02-26 09:27
Svar: 0

Re: Problem med uppgradering.

Inlägg av Erik Nilsson »

Fortsättningen:

Kod: Markera allt

/**
	* Sync function being executed at the middle, some functions need to be executed after a successful sync.
	*/
	function sync_forums($sync_batch)
	{
		global $template, $user, $db, $phpbb_root_path, $phpEx, $config, $cache;
		global $convert;

		$template->assign_block_vars('checks', array(
			'S_LEGEND'	=> true,
			'LEGEND'	=> $user->lang['SYNC_TOPICS'],
		));

		$batch_size = $convert->batch_size;

		$sql = 'SELECT MIN(topic_id) as min_value, MAX(topic_id) AS max_value
			FROM ' . TOPICS_TABLE;
		$result = $db->sql_query($sql);
		$row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);

		// Set values of minimum/maximum primary value for this table.
		$primary_min = $row['min_value'];
		$primary_max = $row['max_value'];

		if ($sync_batch == 0)
		{
			$sync_batch = (int) $primary_min;
		}

		if ($sync_batch == 0)
		{
			$sync_batch = 1;
		}

		// Fetch a batch of rows, process and insert them.
		while ($sync_batch <= $primary_max && still_on_time())
		{
			$end = ($sync_batch + $batch_size - 1);

			// Sync all topics in batch mode...
			sync('topic_approved', 'range', 'topic_id BETWEEN ' . $sync_batch . ' AND ' . $end, true, false);
			sync('topic', 'range', 'topic_id BETWEEN ' . $sync_batch . ' AND ' . $end, true, true);

			$template->assign_block_vars('checks', array(
				'TITLE'		=> sprintf($user->lang['SYNC_TOPIC_ID'], $sync_batch, ($sync_batch + $batch_size)) . ((defined('DEBUG_EXTRA') && function_exists('memory_get_usage')) ? ' [' . ceil(memory_get_usage()/1024) . ' ' . $user->lang['KIB'] . ']' : ''),
				'RESULT'	=> $user->lang['DONE'],
			));

			$sync_batch += $batch_size;
		}

		if ($sync_batch >= $primary_max)
		{
			$url = $this->save_convert_progress('&final_jump=1');

			$template->assign_vars(array(
				'L_SUBMIT'		=> $user->lang['CONTINUE_CONVERT'],
				'U_ACTION'		=> $url,
			));

			$this->meta_refresh($url);
			return;
		}
		else
		{
			$sync_batch--;
		}

		$url = $this->save_convert_progress('&sync_batch=' . $sync_batch);

		$template->assign_vars(array(
			'L_SUBMIT'		=> $user->lang['CONTINUE_CONVERT'],
			'U_ACTION'		=> $url,
		));

		$this->meta_refresh($url);
		return;
	}

	/**
	* Save the convertor status
	*/
	function save_convert_progress($step)
	{
		global $convert, $language;

		// Save convertor Status
		set_config('convert_progress', serialize(array(
			'step'			=> $step,
			'table_prefix'	=> $convert->src_table_prefix,
			'tag'			=> $convert->convertor_tag,
		)), true);

		set_config('convert_db_server', serialize(array(
			'dbms'			=> $convert->src_dbms,
			'dbhost'		=> $convert->src_dbhost,
			'dbport'		=> $convert->src_dbport,
			'dbname'		=> $convert->src_dbname,
		)), true);

		set_config('convert_db_user', serialize(array(
			'dbuser'		=> $convert->src_dbuser,
			'dbpasswd'		=> $convert->src_dbpasswd,
		)), true);

		return $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag={$convert->convertor_tag}$step&language=$language";
	}

	/**
	* Finish conversion, the last function to be called.
	*/
	function finish_conversion()
	{
		global $db, $phpbb_root_path, $phpEx, $convert, $config, $language, $user, $template;

		$db->sql_query('DELETE FROM ' . CONFIG_TABLE . "
			WHERE config_name = 'convert_progress'
				OR config_name = 'convert_options'
				OR config_name = 'convert_db_server'
				OR config_name = 'convert_db_user'");
		$db->sql_query('DELETE FROM ' . SESSIONS_TABLE);

		@unlink($phpbb_root_path . 'cache/data_global.' . $phpEx);
		cache_moderators();

		// And finally, add a note to the log
		add_log('admin', 'LOG_INSTALL_CONVERTED', $convert->convertor_data['forum_name'], $config['version']);

		$url = $this->p_master->module_url . "?mode={$this->mode}&sub=final&language=$language";

		$template->assign_vars(array(
			'L_SUBMIT'		=> $user->lang['FINAL_STEP'],
			'U_ACTION'		=> $url,
		));

		$this->meta_refresh($url);
		return;
	}

	/**
	* This function marks the steps after syncing
	*/
	function final_jump($final_jump)
	{
		global $template, $user, $src_db, $same_db, $db, $phpbb_root_path, $phpEx, $config, $cache;
		global $convert;

		$template->assign_block_vars('checks', array(
			'S_LEGEND'	=> true,
			'LEGEND'	=> $user->lang['PROCESS_LAST'],
		));

		if ($final_jump == 1)
		{
			$db->sql_return_on_error(true);

			update_topics_posted();

			$template->assign_block_vars('checks', array(
				'TITLE'		=> $user->lang['UPDATE_TOPICS_POSTED'],
				'RESULT'	=> $user->lang['DONE'],
			));

			if ($db->sql_error_triggered)
			{
				$template->assign_vars(array(
					'S_ERROR_BOX'	=> true,
					'ERROR_TITLE'	=> $user->lang['UPDATE_TOPICS_POSTED'],
					'ERROR_MSG'		=> $user->lang['UPDATE_TOPICS_POSTED_ERR'],
				));
			}
			$db->sql_return_on_error(false);

			$this->finish_conversion();
			return;
		}
	}

	/**
	* This function marks the steps before syncing (jump=1)
	*/
	function jump($jump, $last_statement)
	{
		global $template, $user, $src_db, $same_db, $db, $phpbb_root_path, $phpEx, $config, $cache;
		global $convert;

		$template->assign_block_vars('checks', array(
			'S_LEGEND'	=> true,
			'LEGEND'	=> $user->lang['PROCESS_LAST'],
		));

		if ($jump == 1)
		{
			// Execute 'last' statements/queries
			if (!empty($convert->convertor['execute_last']))
			{
				if (!is_array($convert->convertor['execute_last']))
				{
					eval($convert->convertor['execute_last']);
				}
				else
				{
					while ($last_statement < sizeof($convert->convertor['execute_last']))
					{
						eval($convert->convertor['execute_last'][$last_statement]);

						$template->assign_block_vars('checks', array(
							'TITLE'		=> $convert->convertor['execute_last'][$last_statement],
							'RESULT'	=> $user->lang['DONE'],
						));

						$last_statement++;
						$url = $this->save_convert_progress('&jump=1&last=' . $last_statement);

						$percentage = ($last_statement == 0) ? 0 : floor(100 / (sizeof($convert->convertor['execute_last']) / $last_statement));
						$msg = sprintf($user->lang['STEP_PERCENT_COMPLETED'], $last_statement, sizeof($convert->convertor['execute_last']), $percentage);

						$template->assign_vars(array(
							'L_SUBMIT'		=> $user->lang['CONTINUE_LAST'],
							'L_MESSAGE'		=> $msg,
							'U_ACTION'		=> $url,
						));

						$this->meta_refresh($url);
						return;
					}
				}
			}

			if (!empty($convert->convertor['query_last']))
			{
				if (!is_array($convert->convertor['query_last']))
				{
					$convert->convertor['query_last'] = array('target', array($convert->convertor['query_last']));
				}
				else if (!is_array($convert->convertor['query_last'][0]))
				{
					$convert->convertor['query_last'] = array(array($convert->convertor['query_last'][0], $convert->convertor['query_last'][1]));
				}

				foreach ($convert->convertor['query_last'] as $query_last)
				{
					if ($query_last[0] == 'src')
					{
						if ($convert->mysql_convert && $same_db)
						{
							$src_db->sql_query("SET NAMES 'binary'");
						}

						$src_db->sql_query($query_last[1]);

						if ($convert->mysql_convert && $same_db)
						{
							$src_db->sql_query("SET NAMES 'utf8'");
						}
					}
					else
					{
						$db->sql_query($query_last[1]);
					}
				}
			}

			// Sanity check
			$db->sql_return_on_error(false);
			$src_db->sql_return_on_error(false);

			fix_empty_primary_groups();

			if (!isset($config['board_startdate']))
			{
				$sql = 'SELECT MIN(user_regdate) AS board_startdate
					FROM ' . USERS_TABLE;
				$result = $db->sql_query($sql);
				$row = $db->sql_fetchrow($result);
				$db->sql_freeresult($result);

				if (($row['board_startdate'] < $config['board_startdate'] && $row['board_startdate'] > 0) || !isset($config['board_startdate']))
				{
					set_config('board_startdate', $row['board_startdate']);
					$db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_regdate = ' . $row['board_startdate'] . ' WHERE user_id = ' . ANONYMOUS);
				}
			}

			update_dynamic_config();

			$template->assign_block_vars('checks', array(
				'TITLE'		=> $user->lang['CLEAN_VERIFY'],
				'RESULT'	=> $user->lang['DONE'],
			));

			$url = $this->save_convert_progress('&jump=2');

			$template->assign_vars(array(
				'L_SUBMIT'		=> $user->lang['CONTINUE_CONVERT'],
				'U_ACTION'		=> $url,
			));

			$this->meta_refresh($url);
			return;
		}

		if ($jump == 2)
		{
			$db->sql_query('UPDATE ' . USERS_TABLE . " SET user_permissions = ''");

			// TODO: sync() is likely going to bomb out on forums with a considerable amount of topics.
			// TODO: the sync function is able to handle FROM-TO values, we should use them here (batch processing)
			sync('forum', '', '', false, true);
			$cache->destroy('sql', FORUMS_TABLE);

			$template->assign_block_vars('checks', array(
				'TITLE'		=> $user->lang['SYNC_FORUMS'],
				'RESULT'	=> $user->lang['DONE'],
			));

			// Continue with synchronizing the forums...
			$url = $this->save_convert_progress('&sync_batch=0');

			$template->assign_vars(array(
				'L_SUBMIT'		=> $user->lang['CONTINUE_CONVERT'],
				'U_ACTION'		=> $url,
			));

			$this->meta_refresh($url);
			return;
		}
	}

	function build_insert_query(&$schema, &$sql_data, $current_table)
	{
		global $db, $user;
		global $convert;

		// Can we use IGNORE with this DBMS?
		$sql_ignore = (strpos($db->sql_layer, 'mysql') === 0 && !defined('DEBUG_EXTRA')) ? 'IGNORE ' : '';
		$insert_query = 'INSERT ' . $sql_ignore . 'INTO ' . $schema['target'] . ' (';

		$aliases = array();

		$sql_data = array(
			'source_fields'		=> array(),
			'target_fields'		=> array(),
			'source_tables'		=> array(),
			'select_fields'		=> array(),
		);

		foreach ($schema as $key => $val)
		{
			// Example: array('group_name',				'extension_groups.group_name',		'htmlspecialchars'),
			if (is_int($key))
			{
				if (!empty($val[0]))
				{
					// Target fields
					$sql_data['target_fields'][$val[0]] = $key;
					$insert_query .= $val[0] . ', ';
				}

				if (!is_array($val[1]))
				{
					$val[1] = array($val[1]);
				}

				foreach ($val[1] as $valkey => $value_1)
				{
					// This should cover about any case:
					//
					// table.field					=> SELECT table.field				FROM table
					// table.field AS alias			=> SELECT table.field	AS alias	FROM table
					// table.field AS table2.alias	=> SELECT table2.field	AS alias	FROM table table2
					// table.field AS table2.field	=> SELECT table2.field				FROM table table2
					//
					if (preg_match('/^([a-z0-9_]+)\.([a-z0-9_]+)( +AS +(([a-z0-9_]+?)\.)?([a-z0-9_]+))?$/i', $value_1, $m))
					{
						// There is 'AS ...' in the field names
						if (!empty($m[3]))
						{
							$value_1 = ($m[2] == $m[6]) ? $m[1] . '.' . $m[2] : $m[1] . '.' . $m[2] . ' AS ' . $m[6];

							// Table alias: store it then replace the source table with it
							if (!empty($m[5]) && $m[5] != $m[1])
							{
								$aliases[$m[5]] = $m[1];
								$value_1 = str_replace($m[1] . '.' . $m[2], $m[5] . '.' . $m[2], $value_1);
							}
						}
						else
						{
							// No table alias
							$sql_data['source_tables'][$m[1]] = (empty($convert->src_table_prefix)) ? $m[1] : $convert->src_table_prefix . $m[1] . ' ' . $m[1];
						}

						$sql_data['select_fields'][$value_1] = $value_1;
						$sql_data['source_fields'][$key][$valkey] = (!empty($m[6])) ? $m[6] : $m[2];
					}
				}
			}
			else if ($key == 'where' || $key == 'group_by' || $key == 'order_by' || $key == 'having')
			{
				if (@preg_match_all('/([a-z0-9_]+)\.([a-z0-9_]+)/i', $val, $m))
				{
					foreach ($m[1] as $value)
					{
						$sql_data['source_tables'][$value] = (empty($convert->src_table_prefix)) ? $value : $convert->src_table_prefix . $value . ' ' . $value;
					}
				}
			}
		}

		// Add the aliases to the list of tables
		foreach ($aliases as $alias => $table)
		{
			$sql_data['source_tables'][$alias] = $convert->src_table_prefix . $table . ' ' . $alias;
		}

		// 'left_join'		=> 'forums LEFT JOIN forum_prune ON forums.forum_id = forum_prune.forum_id',
		if (!empty($schema['left_join']))
		{
			if (!is_array($schema['left_join']))
			{
				$schema['left_join'] = array($schema['left_join']);
			}

			foreach ($schema['left_join'] as $left_join)
			{
				// This won't handle concatened LEFT JOINs
				if (!preg_match('/([a-z0-9_]+) LEFT JOIN ([a-z0-9_]+) A?S? ?([a-z0-9_]*?) ?(ON|USING)(.*)/i', $left_join, $m))
				{
					$this->p_master->error(sprintf($user->lang['NOT_UNDERSTAND'], 'LEFT JOIN', $left_join, $current_table, $schema['target']), __LINE__, __FILE__);
				}

				if (!empty($aliases[$m[2]]))
				{
					if (!empty($m[3]))
					{
						$this->p_master->error(sprintf($user->lang['NAMING_CONFLICT'], $m[2], $m[3], $schema['left_join']), __LINE__, __FILE__);
					}

					$m[2] = $aliases[$m[2]];
					$m[3] = $m[2];
				}

				$right_table = $convert->src_table_prefix . $m[2];
				if (!empty($m[3]))
				{
					unset($sql_data['source_tables'][$m[3]]);
				}
				else if ($m[2] != $m[1])
				{
					unset($sql_data['source_tables'][$m[2]]);
				}

				if (strpos($sql_data['source_tables'][$m[1]], "\nLEFT JOIN") !== false)
				{
					$sql_data['source_tables'][$m[1]] = '(' . $sql_data['source_tables'][$m[1]] . ")\nLEFT JOIN $right_table";
				}
				else
				{
					$sql_data['source_tables'][$m[1]] .= "\nLEFT JOIN $right_table";
				}

				if (!empty($m[3]))
				{
					unset($sql_data['source_tables'][$m[3]]);
					$sql_data['source_tables'][$m[1]] .= ' AS ' . $m[3];
				}
				else if (!empty($convert->src_table_prefix))
				{
					$sql_data['source_tables'][$m[1]] .= ' AS ' . $m[2];
				}
				$sql_data['source_tables'][$m[1]] .= ' ' . $m[4] . $m[5];
			}
		}

		// Remove ", " from the end of the insert query
		$insert_query = substr($insert_query, 0, -2) . ') VALUES ';

		return $insert_query;
	}

	/**
	* Function for processing the currently handled row
	*/
	function process_row(&$schema, &$sql_data, &$insert_values)
	{
		global $template, $user, $phpbb_root_path, $phpEx, $db, $lang, $config, $cache;
		global $convert, $convert_row;

		$sql_flag = false;

		foreach ($schema as $key => $fields)
		{
			// We are only interested in the lines with:
			// array('comment', 'attachments_desc.comment', 'htmlspecialchars'),
			if (is_int($key))
			{
				if (!is_array($fields[1]))
				{
					$fields[1] = array($fields[1]);
				}

				$firstkey_set = false;
				$firstkey = 0;

				foreach ($fields[1] as $inner_key => $inner_value)
				{
					if (!$firstkey_set)
					{
						$firstkey = $inner_key;
						$firstkey_set = true;
					}

					$src_field = isset($sql_data['source_fields'][$key][$inner_key]) ? $sql_data['source_fields'][$key][$inner_key] : '';

					if (!empty($src_field))
					{
						$fields[1][$inner_key] = $convert->row[$src_field];
					}
				}

				if (!empty($fields[0]))
				{
					// We have a target field, if we haven't set $sql_flag yet it will be set to TRUE.
					// If a function has already set it to FALSE it won't change it.
					if ($sql_flag === false)
					{
						$sql_flag = true;
					}

					// No function assigned?
					if (empty($fields[2]))
					{
						$value = $fields[1][$firstkey];
					}
					else if (is_array($fields[2]))
					{
						// Execute complex function/eval/typecast
						$value = $fields[1];

						foreach ($fields[2] as $type => $execution)
						{
							if (strpos($type, 'typecast') === 0)
							{
								if (!is_array($value))
								{
									$value = array($value);
								}
								$value = $value[0];
								settype($value, $execution);
							}
							else if (strpos($type, 'function') === 0)
							{
								if (!is_array($value))
								{
									$value = array($value);
								}

								$value = call_user_func_array($execution, $value);
							}
							else if (strpos($type, 'execute') === 0)
							{
								if (!is_array($value))
								{
									$value = array($value);
								}

								$execution = str_replace('{RESULT}', '$value', $execution);
								$execution = str_replace('{VALUE}', '$value', $execution);
								eval($execution);
							}
						}
					}
					else
					{
						$value = call_user_func_array($fields[2], $fields[1]);
					}

					if (is_null($value))
					{
						$value = '';
					}

					$insert_values[] = $db->_sql_validate_value($value);
				}
				else if (!empty($fields[2]))
				{
					if (is_array($fields[2]))
					{
						// Execute complex function/eval/typecast
						$value = '';

						foreach ($fields[2] as $type => $execution)
						{
							if (strpos($type, 'typecast') === 0)
							{
								$value = settype($value, $execution);
							}
							else if (strpos($type, 'function') === 0)
							{
								if (!is_array($value))
								{
									$value = array($value);
								}

								$value = call_user_func_array($execution, $value);
							}
							else if (strpos($type, 'execute') === 0)
							{
								if (!is_array($value))
								{
									$value = array($value);
								}

								$execution = str_replace('{RESULT}', '$value', $execution);
								$execution = str_replace('{VALUE}', '$value', $execution);
								eval($execution);
							}
						}
					}
					else
					{
						call_user_func_array($fields[2], $fields[1]);
					}
				}
			}
		}

		return $sql_flag;
	}

	/**
	* Own meta refresh function to be able to change the global time used
	*/
	function meta_refresh($url)
	{
		global $convert, $template;

		if ($convert->options['refresh'])
		{
			// Because we should not rely on correct settings, we simply use the relative path here directly.
			$template->assign_vars(array(
				'S_REFRESH'	=> true,
				'META'		=> '<meta http-equiv="refresh" content="5;url=' . $url . '" />')
			);
		}
	}

	/**
	* The information below will be used to build the input fields presented to the user
	*/
	var $convert_options = array(
		'legend1'			=> 'SPECIFY_OPTIONS',
		'src_dbms'			=> array('lang' => 'DBMS',			'type' => 'select', 'options' => 'dbms_select(\'{VALUE}\', true)', 'explain' => false),
		'src_dbhost'		=> array('lang' => 'DB_HOST',		'type' => 'text:25:100', 'explain' => true),
		'src_dbport'		=> array('lang' => 'DB_PORT',		'type' => 'text:25:100', 'explain' => true),
		'src_dbname'		=> array('lang' => 'DB_NAME',		'type' => 'text:25:100', 'explain' => false),
		'src_dbuser'		=> array('lang' => 'DB_USERNAME',	'type' => 'text:25:100', 'explain' => false),
		'src_dbpasswd'		=> array('lang' => 'DB_PASSWORD',	'type' => 'password:25:100', 'explain' => false),
		'src_table_prefix'	=> array('lang' => 'TABLE_PREFIX',	'type' => 'text:25:100', 'explain' => false),
		//'src_url'			=> array('lang' => 'FORUM_ADDRESS',	'type' => 'text:50:100', 'explain' => true),
		'forum_path'		=> array('lang' => 'FORUM_PATH',	'type' => 'text:25:100', 'explain' => true),
		'refresh'			=> array('lang' => 'REFRESH_PAGE',	'type' => 'radio:yes_no', 'explain' => true),
	);
}

?>
Kan även meddela att jag fick "General Error" trots mysql.connect_timeout = 600 istället för 60


// Erik :)
Peetra
Hedersmedlem
Hedersmedlem
Inlägg: 3281
Blev medlem: 2007-06-09 22:38
Svar: 0

Re: Problem med uppgradering.

Inlägg av Peetra »

Eftersom du har möjlighet att konvertera off-site hemma, så tror jag det är en bättre lösning i det här fallet. Samtidigt lär du dig lite om XAMPP också, vilket alltid kan vara behändigt att kunna. :D
Erik Nilsson
Medlem
Medlem
Inlägg: 16
Blev medlem: 2011-02-26 09:27
Svar: 0

Re: Problem med uppgradering.

Inlägg av Erik Nilsson »

Peetra skrev:Eftersom du har möjlighet att konvertera off-site hemma, så tror jag det är en bättre lösning i det här fallet. Samtidigt lär du dig lite om XAMPP också, vilket alltid kan vara behändigt att kunna. :D
Tyvärr skiter det sig här hemma med trots att jag testat "mysql.connect_timeout = 6000"

Måste databasen tolkas om för att passa i phpbb3 eller kan man sno inläggen från nuvarande phpbb2 och göra en ny installation av phpbb3 och importera?
Om någon förstår vad mitt babbel menar hehe :mrgreen:
Användarens profilbild
Sinom
Verified
Administratör
Administratör
Inlägg: 11527
Blev medlem: 2010-11-04 21:24
Svar: 14

Re: Problem med uppgradering.

Inlägg av Sinom »

Erik Nilsson skrev:Måste databasen tolkas om för att passa i phpbb3 eller kan man sno inläggen från nuvarande phpbb2 och göra en ny installation av phpbb3 och importera?
phpBB2-databasen måste konverteras för att kunna användas till phpBB3. (Det funkar alltså inte att ta senaste veckornas inlägg och lägga in rakt av)

Testa följande:

1 ) Gå till C:\xampp\mysql\bin och öppna my.ini

Hitta:

Kod: Markera allt

innodb_lock_wait_timeout        = 50
Öka värdet och testa konvertera.

2 ) Öppna install_convert.php igen och hitta:

Kod: Markera allt

<?php
/** 
*
* @package install
* @version $Id: install_convert.php,v 1.50 2007/07/16 01:06:34 davidmj Exp $
* @copyright (c) 2006 phpBB Group 
* @license http://opensource.org/licenses/gpl-license.php GNU Public License 
*
*/

/**
*/
Lägg till nedanför:

Kod: Markera allt

@set_time_limit(0);
@ini_set('memory_limit', '256M');
@ini_set('upload_max_filesize', '128M');
@ini_set('post_max_size', '256M');
@ini_set('max_input_time', '-1');
@ini_set('max_execution_time', '-1');
@ini_set('expect.timeout', '-1');
@ini_set('default_socket_timeout', '-1');
Hitta:

Kod: Markera allt

	var $batch_size = 2000;
Ändra till:

Kod: Markera allt

var $batch_size = 6000;
Vet du utifall du har någon medlem med "®" eller liknande tecken i namnet?

Lycka till!

Hugs :ugeek:
Bild
Erik Nilsson
Medlem
Medlem
Inlägg: 16
Blev medlem: 2011-02-26 09:27
Svar: 0

Re: Problem med uppgradering.

Inlägg av Erik Nilsson »

Jag ska genast testa tipsen!
Jag har XAMPP installerat på annan plats än föreskriven, kan det vara bekymmer? Nu antar jag att det inte är ett problem men det är lika bra att höra.

Dessa tecken (bortsett från siffror och bokstäver) förkommer i medlemmarnas användarnamn:
^ ! _ - @ $ . :

Hur så?

På tal om användare, finns det något enkelt sett att plocka bort användare som inte postat ett enda inlägg? Gärna om man skicka ett mail till dessa användare innan.
Skriv svar

Vilka är online

Användare som besöker denna kategori: 1 och 0 gäst