Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 422
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
convertor
0.00% covered (danger)
0.00%
0 / 422
0.00% covered (danger)
0.00%
0 / 11
5852
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
12
 intro
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 1
272
 settings
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 1
56
 convert
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
6
 finish
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
6
 proccess_settings_form
0.00% covered (danger)
0.00%
0 / 93
0.00% covered (danger)
0.00%
0 / 1
756
 render_settings_form
0.00% covered (danger)
0.00%
0 / 77
0.00% covered (danger)
0.00%
0 / 1
20
 render_convert_list
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 1
42
 render_error
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 redirect_to_html
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setup_navigation
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2/**
3 *
4 * This file is part of the phpBB Forum Software package.
5 *
6 * @copyright (c) phpBB Limited <https://www.phpbb.com>
7 * @license GNU General Public License, version 2 (GPL-2.0)
8 *
9 * For full copyright and license information, please see
10 * the docs/CREDITS.txt file.
11 *
12 */
13
14namespace phpbb\convert\controller;
15
16use Doctrine\DBAL\Connection;
17use phpbb\cache\driver\driver_interface;
18use phpbb\db\doctrine\connection_factory;
19use phpbb\exception\http_exception;
20use phpbb\install\controller\helper;
21use phpbb\install\helper\container_factory;
22use phpbb\install\helper\database;
23use phpbb\install\helper\install_helper;
24use phpbb\install\helper\iohandler\factory;
25use phpbb\install\helper\iohandler\iohandler_interface;
26use phpbb\install\helper\navigation\navigation_provider;
27use phpbb\language\language;
28use phpbb\request\request_interface;
29use phpbb\template\template;
30use Symfony\Component\HttpFoundation\StreamedResponse;
31
32/**
33 * Controller for forum convertors
34 *
35 * WARNING: This file did not meant to be present in a production environment, so moving
36 *             this file to a location which is accessible after board installation might
37 *             lead to security issues.
38 */
39class convertor
40{
41    /**
42     * @var driver_interface
43     */
44    protected $cache;
45
46    /**
47     * @var driver_interface
48     */
49    protected $installer_cache;
50
51    /**
52     * @var \phpbb\config\db
53     */
54    protected $config;
55
56    /**
57     * @var \phpbb\config_php_file
58     */
59    protected $config_php_file;
60
61    /**
62     * @var string
63     */
64    protected $config_table;
65
66    /**
67     * @var helper
68     */
69    protected $controller_helper;
70
71    /**
72     * @var database
73     */
74    protected $db_helper;
75
76    /**
77     * @var \phpbb\db\driver\driver_interface
78     */
79    protected $db;
80
81    /**
82     * @var Connection
83     */
84    protected $db_doctrine;
85
86    /**
87     * @var install_helper
88     */
89    protected $install_helper;
90
91    /**
92     * @var iohandler_interface
93     */
94    protected $iohandler;
95
96    /**
97     * @var language
98     */
99    protected $language;
100
101    /**
102     * @var navigation_provider
103     */
104    protected $navigation_provider;
105
106    /**
107     * @var request_interface
108     */
109    protected $request;
110
111    /**
112     * @var string
113     */
114    protected $session_keys_table;
115
116    /**
117     * @var string
118     */
119    protected $session_table;
120
121    /**
122     * @var template
123     */
124    protected $template;
125
126    /**
127     * @var string
128     */
129    protected $phpbb_root_path;
130
131    /**
132     * @var string
133     */
134    protected $php_ext;
135
136    /**
137     * Constructor
138     *
139     * @param driver_interface        $cache
140     * @param container_factory        $container
141     * @param database                $db_helper
142     * @param helper                $controller_helper
143     * @param install_helper        $install_helper
144     * @param factory                $iohandler
145     * @param language                $language
146     * @param navigation_provider    $nav
147     * @param request_interface        $request
148     * @param template                $template
149     * @param string                $phpbb_root_path
150     * @param string                $php_ext
151     */
152    public function __construct(driver_interface $cache, 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)
153    {
154        $this->installer_cache        = $cache;
155        $this->controller_helper    = $controller_helper;
156        $this->db_helper            = $db_helper;
157        $this->install_helper        = $install_helper;
158        $this->language                = $language;
159        $this->navigation_provider    = $nav;
160        $this->request                = $request;
161        $this->template                = $template;
162        $this->phpbb_root_path        = $phpbb_root_path;
163        $this->php_ext                = $php_ext;
164
165        $iohandler->set_environment('ajax');
166        $this->iohandler = $iohandler->get();
167
168        if (!$this->install_helper->is_phpbb_installed() || !defined('IN_INSTALL'))
169        {
170            throw new http_exception(403, 'INSTALL_PHPBB_NOT_INSTALLED');
171        }
172
173        $this->controller_helper->handle_language_select();
174
175        $this->cache            = $container->get('cache.driver');
176        $this->config            = $container->get('config');
177        $this->config_php_file    = new \phpbb\config_php_file($this->phpbb_root_path, $this->php_ext);
178        $this->db                = $container->get('dbal.conn.driver');
179        $this->db_doctrine        = $container->get('dbal.conn.doctrine');
180
181        $this->config_table            = $container->get_parameter('tables.config');
182        $this->session_keys_table    = $container->get_parameter('tables.sessions_keys');
183        $this->session_table        = $container->get_parameter('tables.sessions');
184    }
185
186    /**
187     * Render the intro page
188     *
189     * @param bool|int    $start_new    Whether or not to force to start a new convertor
190     *
191     * @return \Symfony\Component\HttpFoundation\Response
192     */
193    public function intro($start_new)
194    {
195        $this->setup_navigation('intro');
196
197        if ($start_new)
198        {
199            if ($this->request->is_ajax())
200            {
201                $response = new StreamedResponse();
202                $iohandler = $this->iohandler;
203                $url = $this->controller_helper->route('phpbb_convert_intro', array('start_new' => 'new'));
204                $response->setCallback(function() use ($iohandler, $url) {
205                    $iohandler->redirect($url);
206                });
207                $response->headers->set('X-Accel-Buffering', 'no');
208
209                return $response;
210            }
211
212            $this->config['convert_progress'] = '';
213            $this->config['convert_db_server'] = '';
214            $this->config['convert_db_user'] = '';
215            $this->db->sql_query('DELETE FROM ' . $this->config_table . "
216                WHERE config_name = 'convert_progress'
217                    OR config_name = 'convert_db_server'
218                    OR config_name = 'convert_db_user'"
219            );
220        }
221
222        // Let's see if there is a conversion in the works...
223        $options = array();
224        if (!empty($this->config['convert_progress']) &&
225            !empty($this->config['convert_db_server']) &&
226            !empty($this->config['convert_db_user']) &&
227            !empty($this->config['convert_options']))
228        {
229            $options = unserialize($this->config['convert_progress']);
230            $options = array_merge($options,
231                unserialize($this->config['convert_db_server']),
232                unserialize($this->config['convert_db_user']),
233                unserialize($this->config['convert_options'])
234            );
235        }
236
237        // This information should have already been checked once, but do it again for safety
238        if (!empty($options) && !empty($options['tag']) &&
239            isset($options['dbms']) &&
240            isset($options['dbhost']) &&
241            isset($options['dbport']) &&
242            isset($options['dbuser']) &&
243            isset($options['dbpasswd']) &&
244            isset($options['dbname']) &&
245            isset($options['table_prefix']))
246        {
247            $this->template->assign_vars(array(
248                'TITLE'                => $this->language->lang('CONTINUE_CONVERT'),
249                'BODY'                => $this->language->lang('CONTINUE_CONVERT_BODY'),
250                'S_CONTINUE'        => true,
251                'U_NEW_ACTION'        => $this->controller_helper->route('phpbb_convert_intro', array('start_new' => 'new')),
252                'U_CONTINUE_ACTION'    => $this->controller_helper->route('phpbb_convert_convert', array('converter' => $options['tag'])),
253            ));
254
255            return $this->controller_helper->render('installer_convert.html', 'CONTINUE_CONVERT', true);
256        }
257
258        return $this->render_convert_list();
259    }
260
261    /**
262     * Obtain convertor settings
263     *
264     * @param string    $converter    Name of the convertor
265     *
266     * @return \Symfony\Component\HttpFoundation\Response|StreamedResponse
267     */
268    public function settings($converter)
269    {
270        $this->setup_navigation('settings');
271
272        require_once ($this->phpbb_root_path . 'includes/constants.' . $this->php_ext);
273        require_once ($this->phpbb_root_path . 'includes/functions_convert.' . $this->php_ext);
274
275        // Include convertor if available
276        $convertor_file_path = $this->phpbb_root_path . 'install/convertors/convert_' . $converter . '.' . $this->php_ext;
277        if (!file_exists($convertor_file_path))
278        {
279            if ($this->request->is_ajax())
280            {
281                $response = new StreamedResponse();
282                $ref = $this;
283                $response->setCallback(function() use ($ref) {
284                    $ref->render_error('CONVERT_NOT_EXIST');
285                });
286                $response->headers->set('X-Accel-Buffering', 'no');
287
288                return $response;
289            }
290
291            $this->render_error('CONVERT_NOT_EXIST');
292            return $this->controller_helper->render('installer_convert.html', 'STAGE_SETTINGS', true);
293        }
294
295        $get_info = true;
296        $phpbb_root_path = $this->phpbb_root_path; // These globals are required
297        $phpEx = $this->php_ext; // See above
298        include_once ($convertor_file_path);
299
300        // The test_file is a file that should be present in the location of the old board.
301        if (!isset($test_file))
302        {
303            if ($this->request->is_ajax())
304            {
305                $response = new StreamedResponse();
306                $ref = $this;
307                $response->setCallback(function() use ($ref) {
308                    $ref->render_error('DEV_NO_TEST_FILE');
309                });
310                $response->headers->set('X-Accel-Buffering', 'no');
311
312                return $response;
313            }
314
315            $this->render_error('DEV_NO_TEST_FILE');
316            return $this->controller_helper->render('installer_convert.html', 'STAGE_SETTINGS', true);
317        }
318
319        if ($this->request->variable('submit', false))
320        {
321            // It must be an AJAX request at this point
322            $response = new StreamedResponse();
323            $ref = $this;
324            $response->setCallback(function() use ($ref, $converter) {
325                $ref->proccess_settings_form($converter);
326            });
327            $response->headers->set('X-Accel-Buffering', 'no');
328
329            return $response;
330        }
331        else
332        {
333            $this->template->assign_vars(array(
334                'U_ACTION'    => $this->controller_helper->route('phpbb_convert_settings', array(
335                    'converter'    => $converter,
336                ))
337            ));
338
339            if ($this->request->is_ajax())
340            {
341                $response = new StreamedResponse();
342                $ref = $this;
343                $response->setCallback(function() use ($ref) {
344                    $ref->render_settings_form();
345                });
346                $response->headers->set('X-Accel-Buffering', 'no');
347
348                return $response;
349            }
350
351            $this->render_settings_form();
352        }
353
354        return $this->controller_helper->render('installer_convert.html', 'STAGE_SETTINGS', true);
355    }
356
357    /**
358     * Run conversion
359     */
360    public function convert($converter)
361    {
362        $this->setup_navigation('convert');
363
364        if ($this->request->is_ajax())
365        {
366            $route = $this->controller_helper->route('phpbb_convert_convert', array('converter' => $converter));
367            $response = new StreamedResponse();
368            $ref = $this;
369            $response->setCallback(function() use ($ref, $route) {
370                $ref->redirect_to_html($route);
371            });
372            $response->headers->set('X-Accel-Buffering', 'no');
373
374            return $response;
375        }
376
377        $convertor = new \phpbb\convert\convertor($this->template, $this->controller_helper);
378        $convertor->convert_data($converter);
379
380        return $this->controller_helper->render('installer_convert.html', 'STAGE_IN_PROGRESS');
381    }
382
383    /**
384     * Render the final page of the convertor
385     */
386    public function finish()
387    {
388        $this->setup_navigation('finish');
389
390        $this->template->assign_vars(array(
391            'TITLE'        => $this->language->lang('CONVERT_COMPLETE'),
392            'BODY'        => $this->language->lang('CONVERT_COMPLETE_EXPLAIN'),
393        ));
394
395        // If we reached this step (conversion completed) we want to purge the cache and log the user out.
396        // This is for making sure the session get not screwed due to the 3.0.x users table being completely new.
397        $this->cache->purge();
398        $this->installer_cache->purge();
399
400        require_once($this->phpbb_root_path . 'includes/constants.' . $this->php_ext);
401        require_once($this->phpbb_root_path . 'includes/functions_convert.' . $this->php_ext);
402
403        $sql = 'SELECT config_value
404            FROM ' . $this->config_table . '
405            WHERE config_name = \'search_type\'';
406        $result = $this->db->sql_query($sql);
407
408        if ($this->db->sql_fetchfield('config_value') != 'fulltext_mysql')
409        {
410            $this->template->assign_vars(array(
411                'S_ERROR_BOX'    => true,
412                'ERROR_TITLE'    => $this->language->lang('SEARCH_INDEX_UNCONVERTED'),
413                'ERROR_MSG'        => $this->language->lang('SEARCH_INDEX_UNCONVERTED_EXPLAIN'),
414            ));
415        }
416
417        $this->db->sql_freeresult($result);
418
419        $tools_factory = new \phpbb\db\tools\factory();
420        $db_tools = $tools_factory->get($this->db_doctrine);
421
422        $db_tools->sql_truncate_table($this->session_keys_table);
423        $db_tools->sql_truncate_table($this->session_table);
424
425        return $this->controller_helper->render('installer_convert.html', 'CONVERT_COMPLETE');
426    }
427
428    /**
429     * Validates settings form
430     *
431     * @param string    $convertor
432     */
433    public function proccess_settings_form($convertor)
434    {
435        global $phpbb_root_path, $phpEx, $get_info;
436
437        $phpbb_root_path = $this->phpbb_root_path;
438        $phpEx = $this->php_ext;
439        $get_info = true;
440
441        require_once($this->phpbb_root_path . 'includes/constants.' . $this->php_ext);
442        require_once($this->phpbb_root_path . 'includes/functions_convert.' . $this->php_ext);
443
444        // Include convertor if available
445        $convertor_file_path = $this->phpbb_root_path . 'install/convertors/convert_' . $convertor . '.' . $this->php_ext;
446        include ($convertor_file_path);
447
448        // We expect to have an AJAX request here
449        $src_dbms            = $this->request->variable('src_dbms', $convertor_data['dbms']);
450        $src_dbhost            = $this->request->variable('src_dbhost', $convertor_data['dbhost']);
451        $src_dbport            = $this->request->variable('src_dbport', $convertor_data['dbport']);
452        $src_dbuser            = $this->request->variable('src_dbuser', $convertor_data['dbuser']);
453        $src_dbpasswd        = $this->request->variable('src_dbpasswd', $convertor_data['dbpasswd']);
454        $src_dbname            = $this->request->variable('src_dbname', $convertor_data['dbname']);
455        $src_table_prefix    = $this->request->variable('src_table_prefix', $convertor_data['table_prefix']);
456        $forum_path            = $this->request->variable('forum_path', $convertor_data['forum_path']);
457        $refresh            = $this->request->variable('refresh', 1);
458
459        // Default URL of the old board
460        // @todo Are we going to use this for attempting to convert URL references in posts, or should we remove it?
461        //        -> We should convert old urls to the new relative urls format
462        // $src_url = $request->variable('src_url', 'Not in use at the moment');
463
464        // strip trailing slash from old forum path
465        $forum_path = (strlen($forum_path) && $forum_path[strlen($forum_path) - 1] == '/') ? substr($forum_path, 0, -1) : $forum_path;
466
467        $error = array();
468        if (!file_exists($this->phpbb_root_path . $forum_path . '/' . $test_file))
469        {
470            $error[] = $this->language->lang('COULD_NOT_FIND_PATH', $forum_path);
471        }
472
473        $connect_test = false;
474        $available_dbms = $this->db_helper->get_available_dbms(false, true, true);
475        if (!isset($available_dbms[$src_dbms]) || !$available_dbms[$src_dbms]['AVAILABLE'])
476        {
477            $error[] = $this->language->lang('INST_ERR_NO_DB');
478        }
479        else
480        {
481            $connect_test = $this->db_helper->check_database_connection($src_dbms, $src_dbhost, $src_dbport, $src_dbuser, $src_dbpasswd, $src_dbname, $src_table_prefix);
482        }
483
484        extract($this->config_php_file->get_all());
485
486        // The forum prefix of the old and the new forum can only be the same if two different databases are used.
487        if ($src_table_prefix === $table_prefix && $src_dbms === $dbms && $src_dbhost === $dbhost && $src_dbport === $dbport && $src_dbname === $dbname)
488        {
489            $error[] = $this->language->lang('TABLE_PREFIX_SAME', $src_table_prefix);
490        }
491
492        if (!$connect_test)
493        {
494            $error[] = $this->language->lang('INST_ERR_DB_CONNECT');
495        }
496
497        $src_dbms = \phpbb\config_php_file::convert_30_dbms_to_31($src_dbms);
498
499        // Check table prefix
500        if (empty($error))
501        {
502            // initiate database connection to old db if old and new db differ
503            global $src_db, $same_db;
504            $src_db = $same_db = false;
505
506            if ($src_dbms != $dbms || $src_dbhost != $dbhost || $src_dbport != $dbport || $src_dbname != $dbname || $src_dbuser != $dbuser)
507            {
508                /** @var \phpbb\db\driver\driver_interface $src_db */
509                $src_db = new $src_dbms();
510                $src_db->sql_connect($src_dbhost, $src_dbuser, htmlspecialchars_decode($src_dbpasswd, ENT_COMPAT), $src_dbname, $src_dbport, false, true);
511                $src_db_doctrine = connection_factory::get_connection_from_params($src_dbms, $src_dbhost, $src_dbuser, htmlspecialchars_decode($src_dbpasswd, ENT_COMPAT), $src_dbname, $src_dbport);
512                $same_db = false;
513            }
514            else
515            {
516                $src_db = $this->db;
517                $src_db_doctrine = $this->db_doctrine;
518                $same_db = true;
519            }
520
521            $src_db->sql_return_on_error(true);
522            $this->db->sql_return_on_error(true);
523
524            // Try to select one row from the first table to see if the prefix is OK
525            $result = $src_db->sql_query_limit('SELECT * FROM ' . $src_table_prefix . $tables[0], 1);
526
527            if (!$result)
528            {
529                $prefixes = array();
530
531                $db_tools_factory = new \phpbb\db\tools\factory();
532                $db_tools = $db_tools_factory->get($src_db_doctrine);
533                $tables_existing = $db_tools->sql_list_tables();
534                $tables_existing = array_map('strtolower', $tables_existing);
535                foreach ($tables_existing as $table_name)
536                {
537                    compare_table($tables, $table_name, $prefixes);
538                }
539                unset($tables_existing);
540
541                foreach ($prefixes as $prefix => $count)
542                {
543                    if ($count >= count($tables))
544                    {
545                        $possible_prefix = $prefix;
546                        break;
547                    }
548                }
549
550                $msg = '';
551                if (!empty($convertor_data['table_prefix']))
552                {
553                    $msg .= $this->language->lang_array('DEFAULT_PREFIX_IS', array($convertor_data['forum_name'], $convertor_data['table_prefix']));
554                }
555
556                if (!empty($possible_prefix))
557                {
558                    $msg .= '<br />';
559                    $msg .= ($possible_prefix == '*') ? $this->language->lang('BLANK_PREFIX_FOUND') : $this->language->lang_array('PREFIX_FOUND', array($possible_prefix));
560                    $src_table_prefix = ($possible_prefix == '*') ? '' : $possible_prefix;
561                }
562
563                $error[] = $msg;
564            }
565
566            $src_db->sql_freeresult($result);
567            $src_db->sql_return_on_error(false);
568        }
569
570        if (empty($error))
571        {
572            // Save convertor Status
573            $this->config->set('convert_progress', serialize(array(
574                'step'            => '',
575                'table_prefix'    => $src_table_prefix,
576                'tag'            => $convertor,
577            )), false);
578            $this->config->set('convert_db_server', serialize(array(
579                'dbms'            => $src_dbms,
580                'dbhost'        => $src_dbhost,
581                'dbport'        => $src_dbport,
582                'dbname'        => $src_dbname,
583            )), false);
584            $this->config->set('convert_db_user', serialize(array(
585                'dbuser'        => $src_dbuser,
586                'dbpasswd'        => $src_dbpasswd,
587            )), false);
588
589            // Save options
590            $this->config->set('convert_options', serialize(array(
591                'forum_path' => $this->phpbb_root_path . $forum_path,
592                'refresh' => $refresh
593            )), false);
594
595            $url = $this->controller_helper->route('phpbb_convert_convert', array('converter' => $convertor));
596            $this->iohandler->redirect($url);
597            $this->iohandler->send_response(true);
598        }
599        else
600        {
601            $this->render_settings_form($error);
602        }
603    }
604
605    /**
606     * Renders settings form
607     *
608     * @param array    $error    Array of errors
609     */
610    public function render_settings_form($error = array())
611    {
612        foreach ($error as $msg)
613        {
614            $this->iohandler->add_error_message($msg);
615        }
616
617        $dbms_options = array();
618        foreach ($this->db_helper->get_available_dbms() as $dbms_key => $dbms_array)
619        {
620            $dbms_options[] = array(
621                'value'        => $dbms_key,
622                'label'        => 'DB_OPTION_' . strtoupper($dbms_key),
623            );
624        }
625
626        $form_title = 'SPECIFY_OPTIONS';
627        $form_data = array(
628            'src_dbms'    => array(
629                'label'        => 'DBMS',
630                'type'        => 'select',
631                'options'    => $dbms_options,
632            ),
633            'src_dbhost' => array(
634                'label'            => 'DB_HOST',
635                'description'    => 'DB_HOST_EXPLAIN',
636                'type'            => 'text',
637            ),
638            'src_dbport' => array(
639                'label'            => 'DB_PORT',
640                'description'    => 'DB_PORT_EXPLAIN',
641                'type'            => 'text',
642            ),
643            'src_dbname' => array(
644                'label'        => 'DB_NAME',
645                'type'        => 'text',
646            ),
647            'src_dbuser' => array(
648                'label'        => 'DB_USERNAME',
649                'type'        => 'text',
650            ),
651            'src_dbpasswd' => array(
652                'label'    => 'DB_PASSWORD',
653                'type'    => 'password',
654            ),
655            'src_table_prefix' => array(
656                'label'            => 'TABLE_PREFIX',
657                'description'    => 'TABLE_PREFIX_EXPLAIN',
658                'type'            => 'text',
659            ),
660            'forum_path' => array(
661                'label'            => 'FORUM_PATH',
662                'description'    => 'FORUM_PATH_EXPLAIN',
663                'type'            => 'text',
664            ),
665            'refresh' => array(
666                'label'            => 'REFRESH_PAGE',
667                'description'    => 'REFRESH_PAGE_EXPLAIN',
668                'type'            => 'radio',
669                'options'        => array(
670                    array(
671                        'value'        => 0,
672                        'label'        => 'NO',
673                        'selected'    => true,
674                    ),
675                    array(
676                        'value'        => 1,
677                        'label'        => 'YES',
678                        'selected'    => false,
679                    ),
680                ),
681            ),
682            'submit' => array(
683                'label'    => 'SUBMIT',
684                'type'    => 'submit',
685            ),
686        );
687
688        if ($this->request->is_ajax())
689        {
690            $this->iohandler->add_user_form_group($form_title, $form_data);
691            $this->iohandler->send_response(true);
692        }
693        else
694        {
695            $rendered_form = $this->iohandler->generate_form_render_data($form_title, $form_data);
696
697            $this->template->assign_vars(array(
698                'TITLE'        => $this->language->lang('STAGE_SETTINGS'),
699                'CONTENT'    => $rendered_form,
700            ));
701        }
702    }
703
704    /**
705     * Render the list of available convertors
706     *
707     * @return \Symfony\Component\HttpFoundation\Response
708     */
709    protected function render_convert_list()
710    {
711        $this->template->assign_vars(array(
712            'TITLE'        => $this->language->lang('CONVERT_INTRO'),
713            'BODY'        => $this->language->lang('CONVERT_INTRO_BODY'),
714            'S_LIST'    => true,
715        ));
716
717        $convertors = $sort = array();
718        $get_info = true; // Global flag
719
720        $handle = @opendir($this->phpbb_root_path . 'install/convertors/');
721
722        if (!$handle)
723        {
724            die('Unable to access the convertors directory');
725        }
726
727        while ($entry = readdir($handle))
728        {
729            if (preg_match('/^convert_([a-z0-9_]+).' . $this->php_ext . '$/i', $entry, $m))
730            {
731                $phpbb_root_path = $this->phpbb_root_path; // These globals are required
732                $phpEx = $this->php_ext; // See above
733                include_once($this->phpbb_root_path . 'install/convertors/' . $entry);
734                if (isset($convertor_data))
735                {
736                    $sort[strtolower($convertor_data['forum_name'])] = count($convertors);
737
738                    $convertors[] = array(
739                        'tag'            =>    $m[1],
740                        'forum_name'    =>    $convertor_data['forum_name'],
741                        'version'        =>    $convertor_data['version'],
742                        'dbms'            =>    $convertor_data['dbms'],
743                        'dbhost'        =>    $convertor_data['dbhost'],
744                        'dbport'        =>    $convertor_data['dbport'],
745                        'dbuser'        =>    $convertor_data['dbuser'],
746                        'dbpasswd'        =>    $convertor_data['dbpasswd'],
747                        'dbname'        =>    $convertor_data['dbname'],
748                        'table_prefix'    =>    $convertor_data['table_prefix'],
749                        'author'        =>    $convertor_data['author']
750                    );
751                }
752                unset($convertor_data);
753            }
754        }
755        closedir($handle);
756
757        @ksort($sort);
758
759        foreach ($sort as $void => $index)
760        {
761            $this->template->assign_block_vars('convertors', array(
762                'AUTHOR'    => $convertors[$index]['author'],
763                'SOFTWARE'    => $convertors[$index]['forum_name'],
764                'VERSION'    => $convertors[$index]['version'],
765
766                'U_CONVERT'    => $this->controller_helper->route('phpbb_convert_settings', array('converter' => $convertors[$index]['tag'])),
767            ));
768        }
769
770        return $this->controller_helper->render('installer_convert.html', 'SUB_INTRO', true);
771    }
772
773    /**
774     * Renders an error form
775     *
776     * @param string        $msg
777     * @param string|bool    $desc
778     */
779    public function render_error($msg, $desc = false)
780    {
781        if ($this->request->is_ajax())
782        {
783            $this->iohandler->add_error_message($msg, $desc);
784            $this->iohandler->send_response(true);
785        }
786        else
787        {
788            $this->template->assign_vars(array(
789                'S_ERROR_BOX'    => true,
790                'ERROR_TITLE'    => $this->language->lang($msg),
791            ));
792
793            if ($desc)
794            {
795                $this->template->assign_var('ERROR_MSG', $this->language->lang($desc));
796            }
797        }
798    }
799
800    /**
801     * Redirects an AJAX request to a non-JS version
802     *
803     * @param string    $url    URL to redirect to
804     */
805    public function redirect_to_html($url)
806    {
807        $this->iohandler->redirect($url);
808        $this->iohandler->send_response(true);
809    }
810
811    private function setup_navigation($stage)
812    {
813        $active = true;
814        $completed = false;
815
816        switch ($stage)
817        {
818            case 'finish':
819                $this->navigation_provider->set_nav_property(
820                    array('convert', 0, 'finish'),
821                    array(
822                        'selected'    => $active,
823                        'completed'    => $completed,
824                    )
825                );
826
827                $active = false;
828                $completed = true;
829            // no break;
830
831            case 'convert':
832                $this->navigation_provider->set_nav_property(
833                    array('convert', 0, 'convert'),
834                    array(
835                        'selected'    => $active,
836                        'completed'    => $completed,
837                    )
838                );
839
840                $active = false;
841                $completed = true;
842            // no break;
843
844            case 'settings':
845                $this->navigation_provider->set_nav_property(
846                    array('convert', 0, 'settings'),
847                    array(
848                        'selected'    => $active,
849                        'completed'    => $completed,
850                    )
851                );
852
853                $active = false;
854                $completed = true;
855            // no break;
856
857            case 'intro':
858                $this->navigation_provider->set_nav_property(
859                    array('convert', 0, 'intro'),
860                    array(
861                        'selected'    => $active,
862                        'completed'    => $completed,
863                    )
864                );
865            break;
866        }
867    }
868}