1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-04-16 13:52:03 +02:00

[ticket/14262] Move convertor to controller

PHPBB3-14262
This commit is contained in:
Mate Bartus 2015-10-28 15:00:11 +01:00
parent 10756f3f87
commit a649768e17
17 changed files with 3082 additions and 3 deletions

View File

@ -0,0 +1,79 @@
<!-- INCLUDE installer_header.html -->
<!-- IF TITLE --><h1>{TITLE}</h1><!-- ENDIF -->
<!-- IF S_ERROR_BOX -->
<div class="errorbox">
<h3>{ERROR_TITLE}</h3>
<p>{ERROR_MSG}</p>
</div>
<!-- ENDIF -->
<!-- IF BODY --><p>{BODY}</p><!-- ENDIF -->
<!-- IF CONTENT -->{CONTENT}<!-- ENDIF -->
<!-- IF S_CONV_IN_PROGRESS -->
<p class="centered-text"><a href="{U_ACTION}" class="button1<!-- IF S_REFRESH --> disabled<!-- ENDIF -->"<!-- IF S_REFRESH --> onclick="return false;"<!-- ENDIF -->>{L_SUBMIT}</a></p>
<!-- ENDIF -->
<!-- IF S_CONTINUE -->
<div id="download-wrapper" class="download-box">
<p class="centered-text">
<a href="{U_NEW_ACTION}" class="button1">{L_CONVERT_NEW_CONVERSION}</a>
<a href="{U_CONTINUE_ACTION}" class="button1">{L_CONTINUE_OLD_CONVERSION}</a>
</p>
</div>
<!-- ENDIF -->
<!-- IF S_LIST -->
<table class="table1">
<caption>{L_AVAILABLE_CONVERTORS}</caption>
<col class="col1" /><col class="col2" /><col class="col1" /><col class="col2" />
<thead>
<tr>
<th>{L_SOFTWARE}</th>
<th>{L_VERSION}</th>
<th>{L_AUTHOR}</th>
<th>{L_CONVERT_OPTIONS}</th>
</tr>
</thead>
<tbody>
<!-- IF .convertors -->
<!-- BEGIN convertors -->
<tr>
<td>{convertors.SOFTWARE}</td>
<td>{convertors.VERSION}</td>
<td>{convertors.AUTHOR}</td>
<td><a href="{convertors.U_CONVERT}">{L_CONVERT}</a></td>
</tr>
<!-- END convertors -->
<!-- ELSE -->
<tr>
<td>{L_NO_CONVERTORS}</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<!-- ENDIF -->
</tbody>
</table>
<!-- ENDIF -->
<!-- IF .checks -->
<fieldset>
<!-- BEGIN checks -->
<!-- IF checks.S_LEGEND -->
<!-- IF not checks.S_FIRST_ROW -->
</fieldset>
<fieldset>
<!-- ENDIF -->
<legend>{checks.LEGEND}</legend>
<!-- IF checks.LEGEND_EXPLAIN --><p>{checks.LEGEND_EXPLAIN}</p><!-- ENDIF -->
<!-- ELSE -->
<dl>
<dt><label>{checks.TITLE}{L_COLON}</label><!-- IF checks.S_EXPLAIN --><br /><span class="explain">{checks.TITLE_EXPLAIN}</span><!-- ENDIF --></dt>
<dd>{checks.RESULT}</dd>
</dl>
<!-- ENDIF -->
<!-- END checks -->
</fieldset>
<!-- ENDIF -->
<!-- INCLUDEJS {T_ASSETS_PATH}/javascript/installer.js -->
<!-- INCLUDE installer_footer.html -->

View File

@ -0,0 +1,134 @@
<!-- INCLUDE installer_header.html -->
<!-- IF S_NOT_INSTALLED -->
<h1>{TITLE}</h1>
<p>{BODY}</p>
<!-- ELSE -->
<form id="install_convert" method="post" action="{U_ACTION}">
<h1>{TITLE}</h1>
<p>{BODY}</p>
<!-- IF S_ERROR_BOX -->
<div class="errorbox">
<h3>{ERROR_TITLE}</h3>
<p>{ERROR_MSG}</p>
</div>
<!-- ENDIF -->
<!-- IF S_LIST -->
<table class="table1">
<caption>{L_AVAILABLE_CONVERTORS}</caption>
<col class="col1" /><col class="col2" /><col class="col1" /><col class="col2" />
<thead>
<tr>
<th>{L_SOFTWARE}</th>
<th>{L_VERSION}</th>
<th>{L_AUTHOR}</th>
<th>{L_OPTIONS}</th>
</tr>
</thead>
<tbody>
<!-- IF .convertors -->
<!-- BEGIN convertors -->
<tr>
<td>{convertors.SOFTWARE}</td>
<td>{convertors.VERSION}</td>
<td>{convertors.AUTHOR}</td>
<td><a href="{convertors.U_CONVERT}">{L_CONVERT}</a></td>
</tr>
<!-- END convertors -->
<!-- ELSE -->
<tr>
<td>{L_NO_CONVERTORS}</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<!-- ENDIF -->
</tbody>
</table>
<!-- ENDIF -->
<!-- IF S_CONTINUE -->
</form>
<fieldset class="submit-buttons">
<form method="post" action="{U_NEW_ACTION}">
<input class="button1" type="submit" name="submit_new" value="{L_NEW}" />
</form>
<br />
<form method="post" action="{U_CONTINUE_ACTION}">
<input class="button1" type="submit" name="submit_cont" value="{L_CONTINUE}" />
</form>
</fieldset>
<form method="post" action="{U_ACTION}">
<!-- ENDIF -->
<!-- IF .checks -->
<fieldset>
<!-- BEGIN checks -->
<!-- IF checks.S_LEGEND -->
<!-- IF not checks.S_FIRST_ROW -->
</fieldset>
<fieldset>
<!-- ENDIF -->
<legend>{checks.LEGEND}</legend>
<!-- IF checks.LEGEND_EXPLAIN --><p>{checks.LEGEND_EXPLAIN}</p><!-- ENDIF -->
<!-- ELSE -->
<dl>
<dt><label>{checks.TITLE}{L_COLON}</label><!-- IF checks.S_EXPLAIN --><br /><span class="explain">{checks.TITLE_EXPLAIN}</span><!-- ENDIF --></dt>
<dd>{checks.RESULT}</dd>
</dl>
<!-- ENDIF -->
<!-- END checks -->
</fieldset>
<!-- ENDIF -->
<!-- IF .options -->
<fieldset>
<!-- BEGIN options -->
<!-- IF options.S_LEGEND -->
<!-- IF not options.S_FIRST_ROW -->
</fieldset>
<fieldset>
<!-- ENDIF -->
<legend>{options.LEGEND}</legend>
<!-- ELSE -->
<dl>
<dt><label for="{options.KEY}">{options.TITLE}{L_COLON}</label><!-- IF options.S_EXPLAIN --><br /><span class="explain">{options.TITLE_EXPLAIN}</span><!-- ENDIF --></dt>
<dd>{options.CONTENT}</dd>
</dl>
<!-- ENDIF -->
<!-- END options -->
</fieldset>
<!-- ENDIF -->
<!-- IF L_SUBMIT -->
<!-- IF L_MESSAGE --><p>{L_MESSAGE}</p><!-- ENDIF -->
<fieldset class="submit-buttons">
{S_HIDDEN}
<!-- IF L_SUBMIT --><input class="button1<!-- IF S_REFRESH --> disabled<!-- ENDIF -->" type="submit" id="submit" <!-- IF S_REFRESH -->disabled="disabled" <!-- ELSE --> onclick="this.className = 'button1 disabled';" onsubmit="this.disabled = 'disabled';" <!-- ENDIF -->name="submit" value="{L_SUBMIT}" /><!-- ENDIF -->
</fieldset>
<!-- ENDIF -->
</form>
<!-- ENDIF -->
<!-- INCLUDE installer_footer.html -->

View File

@ -236,6 +236,22 @@
}
}
// Redirects user
function redirect(url, use_ajax) {
if (use_ajax) {
resetPolling();
var xhReq = createXhrObject();
xhReq.open('GET', url, true);
xhReq.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhReq.send();
startPolling(xhReq);
} else {
window.location.href = url;
}
}
/**
* Parse messages from the response object
*
@ -302,6 +318,10 @@
if (responseObject.hasOwnProperty('refresh')) {
refreshRequested = true;
}
if (responseObject.hasOwnProperty('redirect')) {
redirect(responseObject.redirect.url, responseObject.redirect.use_ajax);
}
}
/**

View File

@ -49,3 +49,18 @@ services:
class: phpbb\install\controller\archive_download
arguments:
- '@installer.helper.config'
phpbb.installer.controller.convert:
class: phpbb\convert\controller\convertor
arguments:
- '@installer.helper.container_factory'
- '@installer.helper.database'
- '@phpbb.installer.controller.helper'
- '@installer.helper.install_helper'
- '@installer.helper.iohandler_factory'
- '@language'
- '@installer.navigation.provider'
- '@request'
- '@template'
- '%core.root_path%'
- '%core.php_ext%'

View File

@ -33,3 +33,10 @@ services:
tags:
- { name: installer.navigation }
installer.navigation.convertor_navigation:
class: phpbb\install\helper\navigation\convertor_navigation
arguments:
- '@installer.helper.install_helper'
scope: prototype
tags:
- { name: installer.navigation }

View File

@ -35,3 +35,28 @@ phpbb_installer_update_conflict_download:
path: /download/conflict
defaults:
_controller: phpbb.installer.controller.file_downloader:conflict_archive
phpbb_convert_intro:
path: /convert/{start_new}
defaults:
_controller: phpbb.installer.controller.convert:intro
start_new: 0
phpbb_convert_settings:
path: /convert/settings/{convertor}
defaults:
_controller: phpbb.installer.controller.convert:settings
requirements:
converter: "[a-zA-Z0-9_]+"
phpbb_convert_convert:
path: /convert/in_progress/{converter}
defaults:
_controller: phpbb.installer.controller.convert:convert
requirements:
converter: "[a-zA-Z0-9_]+"
phpbb_convert_finish:
path: /convert/finished
defaults:
_controller: phpbb.installer.controller.convert:finish

View File

@ -0,0 +1,871 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\convert\controller;
use phpbb\exception\http_exception;
use phpbb\install\controller\helper;
use phpbb\install\helper\container_factory;
use phpbb\install\helper\database;
use phpbb\install\helper\install_helper;
use phpbb\install\helper\iohandler\factory;
use phpbb\install\helper\iohandler\iohandler_interface;
use phpbb\install\helper\navigation\navigation_provider;
use phpbb\language\language;
use phpbb\request\request_interface;
use phpbb\template\template;
use Symfony\Component\HttpFoundation\StreamedResponse;
/**
* Controller for forum convertors
*
* WARNING: This file did not meant to be present in a production environment, so moving
* this file to a location which is accessible after board installation might
* lead to security issues.
*/
class convertor
{
/**
* @var \phpbb\cache\driver\driver_interface
*/
protected $cache;
/**
* @var \phpbb\config\db
*/
protected $config;
/**
* @var \phpbb\config_php_file
*/
protected $config_php_file;
/**
* @var string
*/
protected $config_table;
/**
* @var helper
*/
protected $controller_helper;
/**
* @var database
*/
protected $db_helper;
/**
* @var \phpbb\db\driver\driver_interface
*/
protected $db;
/**
* @var install_helper
*/
protected $install_helper;
/**
* @var iohandler_interface
*/
protected $iohandler;
/**
* @var language
*/
protected $language;
/**
* @var navigation_provider
*/
protected $navigation_provider;
/**
* @var request_interface
*/
protected $request;
/**
* @var string
*/
protected $session_keys_table;
/**
* @var string
*/
protected $session_table;
/**
* @var template
*/
protected $template;
/**
* @var string
*/
protected $phpbb_root_path;
/**
* @var string
*/
protected $php_ext;
/**
* Constructor
*
* @param container_factory $container
* @param database $db_helper
* @param helper $controller_helper
* @param install_helper $install_helper
* @param factory $iohandler
* @param language $language
* @param navigation_provider $nav
* @param request_interface $request
* @param template $template
* @param string $phpbb_root_path
* @param string $php_ext
*/
public function __construct(container_factory $container, database $db_helper, helper $controller_helper, install_helper $install_helper, factory $iohandler, language $language, navigation_provider $nav, request_interface $request, template $template, $phpbb_root_path, $php_ext)
{
$this->controller_helper = $controller_helper;
$this->db_helper = $db_helper;
$this->install_helper = $install_helper;
$this->language = $language;
$this->navigation_provider = $nav;
$this->request = $request;
$this->template = $template;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
$iohandler->set_environment('ajax');
$this->iohandler = $iohandler->get();
if (!$this->install_helper->is_phpbb_installed() || !defined('IN_INSTALL'))
{
throw new http_exception(403, 'INSTALL_PHPBB_NOT_INSTALLED');
}
$this->controller_helper->handle_language_select();
$this->cache = $container->get('cache.driver');
$this->config = $container->get('config');
$this->config_php_file = new \phpbb\config_php_file($this->phpbb_root_path, $this->php_ext);
$this->db = $container->get('dbal.conn.driver');
$this->config_table = $container->get_parameter('tables.config');
$this->session_keys_table = $container->get_parameter('tables.sessions_keys');
$this->session_table = $container->get_parameter('tables.sessions');
}
/**
* Render the intro page
*
* @param bool|int $start_new Whether or not to force to start a new convertor
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function intro($start_new)
{
$this->setup_navigation('intro');
if ($start_new)
{
if ($this->request->is_ajax())
{
$response = new StreamedResponse();
$iohandler = $this->iohandler;
$url = $this->controller_helper->route('phpbb_convert_intro', array('start_new' => 'new'));
$response->setCallback(function() use ($iohandler, $url) {
$iohandler->redirect($url);
});
$response->headers->set('X-Accel-Buffering', 'no');
return $response;
}
$this->config['convert_progress'] = '';
$this->config['convert_db_server'] = '';
$this->config['convert_db_user'] = '';
$this->db->sql_query('DELETE FROM ' . $this->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($this->config['convert_progress']) &&
!empty($this->config['convert_db_server']) &&
!empty($this->config['convert_db_user']) &&
!empty($this->config['convert_options']))
{
$options = unserialize($this->config['convert_progress']);
$options = array_merge($options,
unserialize($this->config['convert_db_server']),
unserialize($this->config['convert_db_user']),
unserialize($this->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->template->assign_vars(array(
'TITLE' => $this->language->lang('CONTINUE_CONVERT'),
'BODY' => $this->language->lang('CONTINUE_CONVERT_BODY'),
'S_CONTINUE' => true,
'U_NEW_ACTION' => $this->controller_helper->route('phpbb_convert_intro', array('start_new' => 'new')),
'U_CONTINUE_ACTION' => $this->controller_helper->route('phpbb_convert_convert', array('converter' => $options['tag'])),
));
return $this->controller_helper->render('installer_convert.html', 'CONTINUE_CONVERT', true);
}
return $this->render_convert_list();
}
/**
* Obtain convertor settings
*
* @param string $convertor Name of the convertor
*
* @return \Symfony\Component\HttpFoundation\Response|StreamedResponse
*/
public function settings($convertor)
{
$this->setup_navigation('settings');
require_once ($this->phpbb_root_path . 'includes/constants.' . $this->php_ext);
require_once ($this->phpbb_root_path . 'includes/functions_convert.' . $this->php_ext);
// Include convertor if available
$convertor_file_path = $this->phpbb_root_path . 'install/convertors/convert_' . $convertor . '.' . $this->php_ext;
if (!file_exists($convertor_file_path))
{
if ($this->request->is_ajax())
{
$response = new StreamedResponse();
$ref = $this;
$response->setCallback(function() use ($ref) {
$ref->render_error('CONVERT_NOT_EXIST');
});
$response->headers->set('X-Accel-Buffering', 'no');
return $response;
}
$this->render_error('CONVERT_NOT_EXIST');
return $this->controller_helper->render('installer_convert.html', 'STAGE_SETTINGS', true);
}
$get_info = true;
$phpbb_root_path = $this->phpbb_root_path; // These globals are required
$phpEx = $this->php_ext; // See above
include_once ($convertor_file_path);
// The test_file is a file that should be present in the location of the old board.
if (!isset($test_file))
{
if ($this->request->is_ajax())
{
$response = new StreamedResponse();
$ref = $this;
$response->setCallback(function() use ($ref) {
$ref->render_error('DEV_NO_TEST_FILE');
});
$response->headers->set('X-Accel-Buffering', 'no');
return $response;
}
$this->render_error('DEV_NO_TEST_FILE');
return $this->controller_helper->render('installer_convert.html', 'STAGE_SETTINGS', true);
}
if ($this->request->variable('submit', false))
{
// It must be an AJAX request at this point
$response = new StreamedResponse();
$ref = $this;
$response->setCallback(function() use ($ref, $convertor) {
$ref->proccess_settings_form($convertor);
});
$response->headers->set('X-Accel-Buffering', 'no');
return $response;
}
else
{
$this->template->assign_vars(array(
'U_ACTION' => $this->controller_helper->route('phpbb_convert_settings', array(
'convertor' => $convertor,
))
));
if ($this->request->is_ajax())
{
$response = new StreamedResponse();
$ref = $this;
$response->setCallback(function() use ($ref) {
$ref->render_settings_form();
});
$response->headers->set('X-Accel-Buffering', 'no');
return $response;
}
$this->render_settings_form();
}
return $this->controller_helper->render('installer_convert.html', 'STAGE_SETTINGS', true);
}
/**
* Run conversion
*/
public function convert($converter)
{
$this->setup_navigation('convert');
if ($this->request->is_ajax())
{
$route = $this->controller_helper->route('phpbb_convert_convert', array('converter' => $converter));
$response = new StreamedResponse();
$ref = $this;
$response->setCallback(function() use ($ref, $route) {
$ref->redirect_to_html($route);
});
$response->headers->set('X-Accel-Buffering', 'no');
return $response;
}
$convertor = new \phpbb\convert\convertor($this->template, $this->controller_helper);
$convertor->convert_data($converter);
return $this->controller_helper->render('installer_convert.html', 'STAGE_IN_PROGRESS');
}
/**
* Render the final page of the convertor
*/
public function finish()
{
$this->setup_navigation('finish');
$this->template->assign_vars(array(
'TITLE' => $this->language->lang('CONVERT_COMPLETE'),
'BODY' => $this->language->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.
$this->cache->purge();
require_once($this->phpbb_root_path . 'includes/constants.' . $this->php_ext);
require_once($this->phpbb_root_path . 'includes/functions_convert.' . $this->php_ext);
$sql = 'SELECT config_value
FROM ' . $this->config_table . '
WHERE config_name = \'search_type\'';
$result = $this->db->sql_query($sql);
if ($this->db->sql_fetchfield('config_value') != 'fulltext_mysql')
{
$this->template->assign_vars(array(
'S_ERROR_BOX' => true,
'ERROR_TITLE' => $this->language->lang('SEARCH_INDEX_UNCONVERTED'),
'ERROR_MSG' => $this->language->lang('SEARCH_INDEX_UNCONVERTED_EXPLAIN'),
));
}
$this->db->sql_freeresult($result);
switch ($this->db->get_sql_layer())
{
case 'sqlite':
case 'sqlite3':
$this->db->sql_query('DELETE FROM ' . $this->session_keys_table);
$this->db->sql_query('DELETE FROM ' . $this->session_table);
break;
default:
$this->db->sql_query('TRUNCATE TABLE ' . $this->session_keys_table);
$this->db->sql_query('TRUNCATE TABLE ' . $this->session_table);
break;
}
return $this->controller_helper->render('installer_convert.html', 'CONVERT_COMPLETE');
}
/**
* Validates settings form
*
* @param string $convertor
*/
public function proccess_settings_form($convertor)
{
global $phpbb_root_path, $phpEx, $get_info;
$phpbb_root_path = $this->phpbb_root_path;
$phpEx = $this->php_ext;
$get_info = true;
require_once($this->phpbb_root_path . 'includes/constants.' . $this->php_ext);
require_once($this->phpbb_root_path . 'includes/functions_convert.' . $this->php_ext);
// Include convertor if available
$convertor_file_path = $this->phpbb_root_path . 'install/convertors/convert_' . $convertor . '.' . $this->php_ext;
include ($convertor_file_path);
// We expect to have an AJAX request here
$src_dbms = $this->request->variable('src_dbms', $convertor_data['dbms']);
$src_dbhost = $this->request->variable('src_dbhost', $convertor_data['dbhost']);
$src_dbport = $this->request->variable('src_dbport', $convertor_data['dbport']);
$src_dbuser = $this->request->variable('src_dbuser', $convertor_data['dbuser']);
$src_dbpasswd = $this->request->variable('src_dbpasswd', $convertor_data['dbpasswd']);
$src_dbname = $this->request->variable('src_dbname', $convertor_data['dbname']);
$src_table_prefix = $this->request->variable('src_table_prefix', $convertor_data['table_prefix']);
$forum_path = $this->request->variable('forum_path', $convertor_data['forum_path']);
$refresh = $this->request->variable('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->variable('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 (!file_exists($this->phpbb_root_path . $forum_path . '/' . $test_file))
{
$error[] = $this->language->lang('COULD_NOT_FIND_PATH', $forum_path);
}
$connect_test = false;
$available_dbms = $this->db_helper->get_available_dbms(false, true, true);
if (!isset($available_dbms[$src_dbms]) || !$available_dbms[$src_dbms]['AVAILABLE'])
{
$error[] = $this->language->lang('INST_ERR_NO_DB');
}
else
{
$connect_test = $this->db_helper->check_database_connection($src_dbms, $src_dbhost, $src_dbport, $src_dbuser, $src_dbpasswd, $src_dbname, $src_table_prefix);
}
extract($this->config_php_file->get_all());
// 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[] = $this->language->lang('TABLE_PREFIX_SAME', $src_table_prefix);
}
if (!$connect_test)
{
$error[] = $this->language->lang('INST_ERR_DB_CONNECT');
}
$src_dbms = $this->config_php_file->convert_30_dbms_to_31($src_dbms);
// Check table prefix
if (empty($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)
{
/** @var \phpbb\db\driver\driver_interface $src_db */
$src_db = new $src_dbms();
$src_db->sql_connect($src_dbhost, $src_dbuser, htmlspecialchars_decode($src_dbpasswd), $src_dbname, $src_dbport, false, true);
$same_db = false;
}
else
{
$src_db = $this->db;
$same_db = true;
}
$src_db->sql_return_on_error(true);
$this->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();
$db_tools_factory = new \phpbb\db\tools\factory();
$db_tools = $db_tools_factory->get($src_db);
$tables_existing = $db_tools->sql_list_tables();
$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 .= $this->language->lang_array('DEFAULT_PREFIX_IS', array($convertor_data['forum_name'], $convertor_data['table_prefix']));
}
if (!empty($possible_prefix))
{
$msg .= '<br />';
$msg .= ($possible_prefix == '*') ? $this->language->lang('BLANK_PREFIX_FOUND') : $this->language->lang_array('PREFIX_FOUND', array($possible_prefix));
$src_table_prefix = ($possible_prefix == '*') ? '' : $possible_prefix;
}
$error[] = $msg;
}
$src_db->sql_freeresult($result);
$src_db->sql_return_on_error(false);
}
if (empty($error))
{
// Save convertor Status
$this->config->set('convert_progress', serialize(array(
'step' => '',
'table_prefix' => $src_table_prefix,
'tag' => $convertor,
)), false);
$this->config->set('convert_db_server', serialize(array(
'dbms' => $src_dbms,
'dbhost' => $src_dbhost,
'dbport' => $src_dbport,
'dbname' => $src_dbname,
)), false);
$this->config->set('convert_db_user', serialize(array(
'dbuser' => $src_dbuser,
'dbpasswd' => $src_dbpasswd,
)), false);
// Save options
$this->config->set('convert_options', serialize(array(
'forum_path' => $this->phpbb_root_path . $forum_path,
'refresh' => $refresh
)), false);
$url = $this->controller_helper->route('phpbb_convert_convert', array('converter' => $convertor));
$this->iohandler->redirect($url);
$this->iohandler->send_response();
}
else
{
$this->render_settings_form($error);
}
}
/**
* Renders settings form
*
* @param array $error Array of errors
*/
public function render_settings_form($error = array())
{
foreach ($error as $msg)
{
$this->iohandler->add_error_message($msg);
}
$dbms_options = array();
foreach ($this->db_helper->get_available_dbms() as $dbms_key => $dbms_array)
{
$dbms_options[] = array(
'value' => $dbms_key,
'label' => 'DB_OPTION_' . strtoupper($dbms_key),
);
}
$form_title = 'SPECIFY_OPTIONS';
$form_data = array(
'src_dbms' => array(
'label' => 'DBMS',
'type' => 'select',
'options' => $dbms_options,
),
'src_dbhost' => array(
'label' => 'DB_HOST',
'description' => 'DB_HOST_EXPLAIN',
'type' => 'text',
),
'src_dbport' => array(
'label' => 'DB_PORT',
'description' => 'DB_PORT_EXPLAIN',
'type' => 'text',
),
'src_dbname' => array(
'label' => 'DB_NAME',
'type' => 'text',
),
'src_dbuser' => array(
'label' => 'DB_USERNAME',
'type' => 'text',
),
'src_dbpasswd' => array(
'label' => 'DB_PASSWORD',
'type' => 'password',
),
'src_table_prefix' => array(
'label' => 'TABLE_PREFIX',
'description' => 'TABLE_PREFIX_EXPLAIN',
'type' => 'text',
),
'forum_path' => array(
'label' => 'FORUM_PATH',
'description' => 'FORUM_PATH_EXPLAIN',
'type' => 'text',
),
'refresh' => array(
'label' => 'REFRESH_PAGE',
'description' => 'REFRESH_PAGE_EXPLAIN',
'type' => 'radio',
'options' => array(
array(
'value' => 0,
'label' => 'NO',
'selected' => true,
),
array(
'value' => 1,
'label' => 'YES',
'selected' => false,
),
),
),
'submit' => array(
'label' => 'SUBMIT',
'type' => 'submit',
),
);
if ($this->request->is_ajax())
{
$this->iohandler->add_user_form_group($form_title, $form_data);
$this->iohandler->send_response();
}
else
{
$rendered_form = $this->iohandler->generate_form_render_data($form_title, $form_data);
$this->template->assign_vars(array(
'TITLE' => $this->language->lang('STAGE_SETTINGS'),
'CONTENT' => $rendered_form,
));
}
}
/**
* Render the list of available convertors
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function render_convert_list()
{
$this->template->assign_vars(array(
'TITLE' => $this->language->lang('CONVERT_INTRO'),
'BODY' => $this->language->lang('CONVERT_INTRO_BODY'),
'S_LIST' => true,
));
$convertors = $sort = array();
$get_info = true; // Global flag
$handle = @opendir($this->phpbb_root_path . 'install/convertors/');
if (!$handle)
{
die('Unable to access the convertors directory');
}
while ($entry = readdir($handle))
{
if (preg_match('/^convert_([a-z0-9_]+).' . $this->php_ext . '$/i', $entry, $m))
{
$phpbb_root_path = $this->phpbb_root_path; // These globals are required
$phpEx = $this->php_ext; // See above
include_once($this->phpbb_root_path . 'install/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)
{
$this->template->assign_block_vars('convertors', array(
'AUTHOR' => $convertors[$index]['author'],
'SOFTWARE' => $convertors[$index]['forum_name'],
'VERSION' => $convertors[$index]['version'],
'U_CONVERT' => $this->controller_helper->route('phpbb_convert_settings', array('convertor' => $convertors[$index]['tag'])),
));
}
return $this->controller_helper->render('installer_convert.html', 'SUB_INTRO', true);
}
/**
* Renders an error form
*
* @param string $msg
* @param string|bool $desc
*/
public function render_error($msg, $desc = false)
{
if ($this->request->is_ajax())
{
$this->iohandler->add_error_message($msg, $desc);
$this->iohandler->send_response();
}
else
{
$this->template->assign_vars(array(
'S_ERROR_BOX' => true,
'ERROR_TITLE' => $this->language->lang($msg),
));
if ($desc)
{
$this->template->assign_var('ERROR_MSG', $this->language->lang($desc));
}
}
}
/**
* Redirects an AJAX request to a non-JS version
*
* @param string $url URL to redirect to
*/
public function redirect_to_html($url)
{
$this->iohandler->redirect($url);
$this->iohandler->send_response();
}
private function setup_navigation($stage)
{
$active = true;
switch ($stage)
{
case 'finish':
$this->navigation_provider->set_nav_property(
array('convert', 0, 'finish'),
array(
'selected' => $active,
'completed' => false,
)
);
$active = false;
$this->navigation_provider->set_nav_property(
array('convert', 0, 'convert'),
array('completed' => true)
);
// no break;
case 'convert':
$this->navigation_provider->set_nav_property(
array('convert', 0, 'convert'),
array(
'selected' => $active,
'completed' => false,
)
);
$active = false;
$this->navigation_provider->set_nav_property(
array('convert', 0, 'settings'),
array('completed' => true)
);
// no break;
case 'settings':
$this->navigation_provider->set_nav_property(
array('convert', 0, 'settings'),
array(
'selected' => $active,
'completed' => false,
)
);
$active = false;
$this->navigation_provider->set_nav_property(
array('convert', 0, 'intro'),
array(
'selected' => $active,
'completed' => false,
)
);
// no break;
case 'intro':
$this->navigation_provider->set_nav_property(
array('convert', 0, 'intro'),
array(
'selected' => $active,
'completed' => false,
)
);
break;
}
}
}

View File

@ -0,0 +1,60 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\convert;
/**
* Class holding all convertor-specific details.
*
* WARNING: This file did not meant to be present in a production environment, so moving this file to a location which
* is accessible after board installation might lead to security issues.
*/
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;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -101,6 +101,8 @@ $phpbb_class_loader_new = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}
$phpbb_class_loader_new->register();
$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx);
$phpbb_class_loader->register();
$phpbb_class_loader = new \phpbb\class_loader('phpbb\\convert\\', "{$phpbb_root_path}install/convert/", $phpEx);
$phpbb_class_loader->register();
$phpbb_class_loader_ext = new \phpbb\class_loader('\\', "{$phpbb_root_path}ext/", $phpEx);
$phpbb_class_loader_ext->register();

View File

@ -439,3 +439,112 @@ $lang = array_merge($lang, array(
'INLINE_UPDATE_SUCCESSFUL' => 'The database update was successful.',
));
// Converter
$lang = array_merge($lang, array(
// Common converter messages
'CONVERT_NOT_EXIST' => 'The specified convertor does not exist.',
'DEV_NO_TEST_FILE' => 'No value has been specified for the test_file variable in the convertor. If you are a user of this convertor, you should not be seeing this error, please report this message to the convertor author. If you are a convertor author, you must specify the name of a file which exists in the source board to allow the path to it to be verified.',
'COULD_NOT_FIND_PATH' => 'Could not find path to your former board. Please check your settings and try again.<br />» %s was specified as the source path.',
'CONFIG_PHPBB_EMPTY' => 'The phpBB3 config variable for “%s” is empty.',
'MAKE_FOLDER_WRITABLE' => 'Please make sure that this folder exists and is writable by the webserver then try again:<br />»<strong>%s</strong>.',
'MAKE_FOLDERS_WRITABLE' => 'Please make sure that these folders exist and are writable by the webserver then try again:<br />»<strong>%s</strong>.',
'INSTALL_TEST' => 'Test again',
'NO_TABLES_FOUND' => 'No tables found.',
'TABLES_MISSING' => 'Could not find these tables<br />» <strong>%s</strong>.',
'CHECK_TABLE_PREFIX' => 'Please check your table prefix and try again.',
// Conversion in progress
'CONTINUE_CONVERT' => 'Continue conversion',
'CONTINUE_CONVERT_BODY' => 'A previous conversion attempt has been determined. You are now able to choose between starting a new conversion or continuing the conversion.',
'CONVERT_NEW_CONVERSION' => 'New conversion',
'CONTINUE_OLD_CONVERSION' => 'Continue previously started conversion',
// Start conversion
'SUB_INTRO' => 'Introduction',
'CONVERT_INTRO' => 'Welcome to the phpBB Unified Convertor Framework',
'CONVERT_INTRO_BODY' => 'From here, you are able to import data from other (installed) board systems. The list below shows all the conversion modules currently available. If there is no convertor shown in this list for the board software you wish to convert from, please check our website where further conversion modules may be available for download.',
'AVAILABLE_CONVERTORS' => 'Available convertors',
'NO_CONVERTORS' => 'No convertors are available for use.',
'CONVERT_OPTIONS' => 'Options',
'SOFTWARE' => 'Board software',
'VERSION' => 'Version',
'CONVERT' => 'Convert',
// Settings
'STAGE_SETTINGS' => 'Settings',
'TABLE_PREFIX_SAME' => 'The table prefix needs to be the one used by the software you are converting from.<br />» Specified table prefix was %s.',
'DEFAULT_PREFIX_IS' => 'The convertor was not able to find tables with the specified prefix. Please make sure you have entered the correct details for the board you are converting from. The default table prefix for %1$s is <strong>%2$s</strong>.',
'SPECIFY_OPTIONS' => 'Specify conversion options',
'FORUM_PATH' => 'Board path',
'FORUM_PATH_EXPLAIN' => 'This is the <strong>relative</strong> path on disk to your former board from the <strong>root of this phpBB3 installation</strong>.',
'REFRESH_PAGE' => 'Refresh page to continue conversion',
'REFRESH_PAGE_EXPLAIN' => 'If set to yes, the convertor will refresh the page to continue the conversion after having finished a step. If this is your first conversion for testing purposes and to determine any errors in advance, we suggest to set this to No.',
// Conversion
'STAGE_IN_PROGRESS' => 'Conversion in progress',
'AUTHOR_NOTES' => 'Author notes<br />» %s',
'STARTING_CONVERT' => 'Starting conversion process',
'CONFIG_CONVERT' => 'Converting the configuration',
'DONE' => 'Done',
'PREPROCESS_STEP' => 'Executing pre-processing functions/queries',
'FILLING_TABLE' => 'Filling table <strong>%s</strong>',
'FILLING_TABLES' => 'Filling tables',
'DB_ERR_INSERT' => 'Error while processing <code>INSERT</code> query.',
'DB_ERR_LAST' => 'Error while processing <var>query_last</var>.',
'DB_ERR_QUERY_FIRST' => 'Error while executing <var>query_first</var>.',
'DB_ERR_QUERY_FIRST_TABLE' => 'Error while executing <var>query_first</var>, %s (“%s”).',
'DB_ERR_SELECT' => 'Error while running <code>SELECT</code> query.',
'STEP_PERCENT_COMPLETED' => 'Step <strong>%d</strong> of <strong>%d</strong>',
'FINAL_STEP' => 'Process final step',
'SYNC_FORUMS' => 'Starting to synchronise forums',
'SYNC_POST_COUNT' => 'Synchronising post_counts',
'SYNC_POST_COUNT_ID' => 'Synchronising post_counts from <var>entry</var> %1$s to %2$s.',
'SYNC_TOPICS' => 'Starting to synchronise topics',
'SYNC_TOPIC_ID' => 'Synchronising topics from <var>topic_id</var> %1$s to %2$s.',
'PROCESS_LAST' => 'Processing last statements',
'UPDATE_TOPICS_POSTED' => 'Generating topics posted information',
'UPDATE_TOPICS_POSTED_ERR' => 'An error occurred while generating topics posted information. You can retry this step in the ACP after the conversion process is completed.',
'CONTINUE_LAST' => 'Continue last statements',
'CLEAN_VERIFY' => 'Cleaning up and verifying the final structure',
'NOT_UNDERSTAND' => 'Could not understand %s #%d, table %s (“%s”)',
'NAMING_CONFLICT' => 'Naming conflict: %s and %s are both aliases<br /><br />%s',
// Finish conversion
'CONVERT_COMPLETE' => 'Conversion completed',
'CONVERT_COMPLETE_EXPLAIN' => 'You have now successfully converted your board to phpBB 3.2. You can now login and <a href="../">access your board</a>. Please ensure that the settings were transferred correctly before enabling your board by deleting the install directory. Remember that help on using phpBB is available online via the <a href="https://www.phpbb.com/support/docs/en/3.2/ug/">Documentation</a> and the <a href="https://www.phpbb.com/community/viewforum.php?f=466">support forums</a>.',
'CONV_ERROR_ATTACH_FTP_DIR' => 'FTP upload for attachments is enabled at the old board. Please disable the FTP upload option and make sure a valid upload directory is specified, then copy all attachment files to this new web accessible directory. Once you have done this, restart the convertor.',
'CONV_ERROR_CONFIG_EMPTY' => 'There is no configuration information available for the conversion.',
'CONV_ERROR_FORUM_ACCESS' => 'Unable to get forum access information.',
'CONV_ERROR_GET_CATEGORIES' => 'Unable to get categories.',
'CONV_ERROR_GET_CONFIG' => 'Could not retrieve your board configuration.',
'CONV_ERROR_COULD_NOT_READ' => 'Unable to access/read “%s”.',
'CONV_ERROR_GROUP_ACCESS' => 'Unable to get group authentication information.',
'CONV_ERROR_INCONSISTENT_GROUPS' => 'Inconsistency in groups table detected in add_bots() - you need to add all special groups if you do it manually.',
'CONV_ERROR_INSERT_BOT' => 'Unable to insert bot into users table.',
'CONV_ERROR_INSERT_BOTGROUP' => 'Unable to insert bot into bots table.',
'CONV_ERROR_INSERT_USER_GROUP' => 'Unable to insert user into user_group table.',
'CONV_ERROR_MESSAGE_PARSER' => 'Message parser error',
'CONV_ERROR_NO_AVATAR_PATH' => 'Note to developer: you must specify $convertor[\'avatar_path\'] to use %s.',
'CONV_ERROR_NO_FORUM_PATH' => 'The relative path to the source board has not been specified.',
'CONV_ERROR_NO_GALLERY_PATH' => 'Note to developer: you must specify $convertor[\'avatar_gallery_path\'] to use %s.',
'CONV_ERROR_NO_GROUP' => 'Group “%1$s” could not be found in %2$s.',
'CONV_ERROR_NO_RANKS_PATH' => 'Note to developer: you must specify $convertor[\'ranks_path\'] to use %s.',
'CONV_ERROR_NO_SMILIES_PATH' => 'Note to developer: you must specify $convertor[\'smilies_path\'] to use %s.',
'CONV_ERROR_NO_UPLOAD_DIR' => 'Note to developer: you must specify $convertor[\'upload_path\'] to use %s.',
'CONV_ERROR_PERM_SETTING' => 'Unable to insert/update permission setting.',
'CONV_ERROR_PM_COUNT' => 'Unable to select folder pm count.',
'CONV_ERROR_REPLACE_CATEGORY' => 'Unable to insert new forum replacing old category.',
'CONV_ERROR_REPLACE_FORUM' => 'Unable to insert new forum replacing old forum.',
'CONV_ERROR_USER_ACCESS' => 'Unable to get user authentication information.',
'CONV_ERROR_WRONG_GROUP' => 'Wrong group “%1$s” defined in %2$s.',
'CONV_OPTIONS_BODY' => 'This page collects the data required to access the source board. Enter the database details of your former board; the converter will not change anything in the database given below. The source board should be disabled to allow a consistent conversion.',
'CONV_SAVED_MESSAGES' => 'Saved messages',
'PRE_CONVERT_COMPLETE' => 'All pre-conversion steps have successfully been completed. You may now begin the actual conversion process. Please note that you may have to manually do and adjust several things. After conversion, especially check the permissions assigned, rebuild your search index which is not converted and also make sure files got copied correctly, for example avatars and smilies.',
));

View File

@ -160,12 +160,13 @@ class helper
* Returns path from route name
*
* @param string $route_name
* @param array $parameters
*
* @return string
*/
public function route($route_name)
public function route($route_name, $parameters = array())
{
$url = $this->router->generate($route_name);
$url = $this->router->generate($route_name, $parameters);
return $url;
}

View File

@ -71,6 +71,11 @@ class ajax_iohandler extends iohandler_base
*/
protected $download;
/**
* @var array
*/
protected $redirect_url;
/**
* Constructor
*
@ -89,6 +94,7 @@ class ajax_iohandler extends iohandler_base
$this->nav_data = array();
$this->cookies = array();
$this->download = array();
$this->redirect_url = array();
$this->file_status = '';
parent::__construct();
@ -130,6 +136,14 @@ class ajax_iohandler extends iohandler_base
* {@inheritdoc}
*/
public function add_user_form_group($title, $form)
{
$this->form = $this->generate_form_render_data($title, $form);
}
/**
* {@inheritdoc}
*/
public function generate_form_render_data($title, $form)
{
$this->template->assign_block_vars('options', array(
'LEGEND' => $this->language->lang($title),
@ -189,7 +203,7 @@ class ajax_iohandler extends iohandler_base
'form_install' => 'installer_form.html',
));
$this->form = $this->template->assign_display('form_install');
return $this->template->assign_display('form_install');
}
/**
@ -273,6 +287,12 @@ class ajax_iohandler extends iohandler_base
$this->cookies = array();
}
if (!empty($this->redirect_url))
{
$json_array['redirect'] = $this->redirect_url;
$this->redirect_url = array();
}
return $json_array;
}
@ -372,6 +392,15 @@ class ajax_iohandler extends iohandler_base
$this->file_status = $this->template->assign_display('file_status');
}
/**
* {@inheritdoc}
*/
public function redirect($url, $use_ajax = false)
{
$this->redirect_url = array('url' => $url, 'use_ajax' => $use_ajax);
$this->send_response();
}
/**
* Callback function for language replacing
*

View File

@ -289,4 +289,11 @@ class cli_iohandler extends iohandler_base
public function render_update_file_status($status_array)
{
}
/**
* {@inheritdoc}
*/
public function redirect($url, $use_ajax = false)
{
}
}

View File

@ -169,6 +169,14 @@ abstract class iohandler_base implements iohandler_interface
$this->current_task_progress = $this->task_progress_count;
}
/**
* {@inheritdoc}
*/
public function generate_form_render_data($title, $form)
{
return '';
}
/**
* Localize message.
*

View File

@ -123,6 +123,16 @@ interface iohandler_interface
*/
public function add_user_form_group($title, $form);
/**
* Returns the rendering information for the form
*
* @param string $title Language variable with the title of the form
* @param array $form An array describing the required data (options etc)
*
* @return string Information to render the form
*/
public function generate_form_render_data($title, $form);
/**
* Sets the number of tasks belonging to the installer in the current mode.
*
@ -174,6 +184,14 @@ interface iohandler_interface
*/
public function add_download_link($route, $title, $msg = null);
/**
* Redirects the user to a new page
*
* @param string $url URL to redirect to
* @param bool $use_ajax Whether or not to use AJAX redirect
*/
public function redirect($url, $use_ajax = false);
/**
* Renders the status of update files
*

View File

@ -0,0 +1,78 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\install\helper\navigation;
use phpbb\install\helper\install_helper;
class convertor_navigation implements navigation_interface
{
/**
* @var install_helper
*/
private $install_helper;
/**
* Constructor
*
* @param install_helper $install_helper
*/
public function __construct(install_helper $install_helper)
{
$this->install_helper = $install_helper;
}
/**
* {@inheritdoc}
*/
public function get()
{
if (!$this->install_helper->is_phpbb_installed())
{
return array();
}
return array(
'convert' => array(
'label' => 'CONVERT',
'route' => 'phpbb_convert_intro',
'order' => 3,
array(
'intro' => array(
'label' => 'SUB_INTRO',
'stage' => true,
'order' => 0,
),
'settings' => array(
'label' => 'STAGE_SETTINGS',
'stage' => true,
'route' => 'phpbb_convert_settings',
'order' => 1,
),
'convert' => array(
'label' => 'STAGE_IN_PROGRESS',
'stage' => true,
'route' => 'phpbb_convert_convert',
'order' => 2,
),
'finish' => array(
'label' => 'CONVERT_COMPLETE',
'stage' => true,
'route' => 'phpbb_convert_finish',
'order' => 3,
),
),
),
);
}
}