1 | <?php
|
---|
2 | /**
|
---|
3 | *
|
---|
4 | * @package install
|
---|
5 | * @version $Id: install_convert.php 8814 2008-09-04 12:01:47Z acydburn $
|
---|
6 | * @copyright (c) 2006 phpBB Group
|
---|
7 | * @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
---|
8 | *
|
---|
9 | */
|
---|
10 |
|
---|
11 | /**
|
---|
12 | */
|
---|
13 |
|
---|
14 | if (!defined('IN_INSTALL'))
|
---|
15 | {
|
---|
16 | // Someone has tried to access the file direct. This is not a good idea, so exit
|
---|
17 | exit;
|
---|
18 | }
|
---|
19 |
|
---|
20 | if (!empty($setmodules))
|
---|
21 | {
|
---|
22 | $module[] = array(
|
---|
23 | 'module_type' => 'install',
|
---|
24 | 'module_title' => 'CONVERT',
|
---|
25 | 'module_filename' => substr(basename(__FILE__), 0, -strlen($phpEx)-1),
|
---|
26 | 'module_order' => 20,
|
---|
27 | 'module_subs' => '',
|
---|
28 | 'module_stages' => array('INTRO', 'SETTINGS', 'IN_PROGRESS', 'FINAL'),
|
---|
29 | 'module_reqs' => ''
|
---|
30 | );
|
---|
31 | }
|
---|
32 |
|
---|
33 | /**
|
---|
34 | * Class holding all convertor-specific details.
|
---|
35 | * @package install
|
---|
36 | */
|
---|
37 | class convert
|
---|
38 | {
|
---|
39 | var $options = array();
|
---|
40 |
|
---|
41 | var $convertor_tag = '';
|
---|
42 | var $src_dbms = '';
|
---|
43 | var $src_dbhost = '';
|
---|
44 | var $src_dbport = '';
|
---|
45 | var $src_dbuser = '';
|
---|
46 | var $src_dbpasswd = '';
|
---|
47 | var $src_dbname = '';
|
---|
48 | var $src_table_prefix = '';
|
---|
49 |
|
---|
50 | var $convertor_data = array();
|
---|
51 | var $tables = array();
|
---|
52 | var $config_schema = array();
|
---|
53 | var $convertor = array();
|
---|
54 | var $src_truncate_statement = 'DELETE FROM ';
|
---|
55 | var $truncate_statement = 'DELETE FROM ';
|
---|
56 |
|
---|
57 | var $fulltext_search;
|
---|
58 |
|
---|
59 | // Batch size, can be adjusted by the conversion file
|
---|
60 | // For big boards a value of 6000 seems to be optimal
|
---|
61 | var $batch_size = 2000;
|
---|
62 | // Number of rows to be inserted at once (extended insert) if supported
|
---|
63 | // For installations having enough memory a value of 60 may be good.
|
---|
64 | var $num_wait_rows = 20;
|
---|
65 |
|
---|
66 | // Mysqls internal recoding engine messing up with our (better) functions? We at least support more encodings than mysql so should use it in favor.
|
---|
67 | var $mysql_convert = false;
|
---|
68 |
|
---|
69 | var $p_master;
|
---|
70 |
|
---|
71 | function convert(&$p_master)
|
---|
72 | {
|
---|
73 | $this->p_master = &$p_master;
|
---|
74 | }
|
---|
75 | }
|
---|
76 |
|
---|
77 | /**
|
---|
78 | * Convert class for conversions
|
---|
79 | * @package install
|
---|
80 | */
|
---|
81 | class install_convert extends module
|
---|
82 | {
|
---|
83 | /**
|
---|
84 | * Variables used while converting, they are accessible from the global variable $convert
|
---|
85 | */
|
---|
86 | function install_convert(&$p_master)
|
---|
87 | {
|
---|
88 | $this->p_master = &$p_master;
|
---|
89 | }
|
---|
90 |
|
---|
91 | function main($mode, $sub)
|
---|
92 | {
|
---|
93 | global $lang, $template, $phpbb_root_path, $phpEx, $cache, $config, $language, $table_prefix;
|
---|
94 | global $convert;
|
---|
95 |
|
---|
96 | $this->tpl_name = 'install_convert';
|
---|
97 | $this->mode = $mode;
|
---|
98 |
|
---|
99 | $convert = new convert($this->p_master);
|
---|
100 |
|
---|
101 | switch ($sub)
|
---|
102 | {
|
---|
103 | case 'intro':
|
---|
104 | // Try opening config file
|
---|
105 | // @todo If phpBB is not installed, we need to do a cut-down installation here
|
---|
106 | // For now, we redirect to the installation script instead
|
---|
107 | if (@file_exists($phpbb_root_path . 'config.' . $phpEx))
|
---|
108 | {
|
---|
109 | include($phpbb_root_path . 'config.' . $phpEx);
|
---|
110 | }
|
---|
111 |
|
---|
112 | if (!defined('PHPBB_INSTALLED'))
|
---|
113 | {
|
---|
114 | $template->assign_vars(array(
|
---|
115 | 'S_NOT_INSTALLED' => true,
|
---|
116 | 'TITLE' => $lang['BOARD_NOT_INSTALLED'],
|
---|
117 | 'BODY' => sprintf($lang['BOARD_NOT_INSTALLED_EXPLAIN'], append_sid($phpbb_root_path . 'install/index.' . $phpEx, 'mode=install&language=' . $language)),
|
---|
118 | ));
|
---|
119 |
|
---|
120 | return;
|
---|
121 | }
|
---|
122 |
|
---|
123 | require($phpbb_root_path . 'config.' . $phpEx);
|
---|
124 | require($phpbb_root_path . 'includes/constants.' . $phpEx);
|
---|
125 | require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
|
---|
126 | require($phpbb_root_path . 'includes/functions_convert.' . $phpEx);
|
---|
127 |
|
---|
128 | $db = new $sql_db();
|
---|
129 | $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, true);
|
---|
130 | unset($dbpasswd);
|
---|
131 |
|
---|
132 | // We need to fill the config to let internal functions correctly work
|
---|
133 | $sql = 'SELECT *
|
---|
134 | FROM ' . CONFIG_TABLE;
|
---|
135 | $result = $db->sql_query($sql);
|
---|
136 |
|
---|
137 | $config = array();
|
---|
138 | while ($row = $db->sql_fetchrow($result))
|
---|
139 | {
|
---|
140 | $config[$row['config_name']] = $row['config_value'];
|
---|
141 | }
|
---|
142 | $db->sql_freeresult($result);
|
---|
143 |
|
---|
144 | // Detect if there is already a conversion in progress at this point and offer to resume
|
---|
145 | // It's quite possible that the user will get disconnected during a large conversion so they need to be able to resume it
|
---|
146 | $new_conversion = request_var('new_conv', 0);
|
---|
147 |
|
---|
148 | if ($new_conversion)
|
---|
149 | {
|
---|
150 | $config['convert_progress'] = '';
|
---|
151 | $config['convert_db_server'] = '';
|
---|
152 | $config['convert_db_user'] = '';
|
---|
153 | $db->sql_query('DELETE FROM ' . CONFIG_TABLE . "
|
---|
154 | WHERE config_name = 'convert_progress'
|
---|
155 | OR config_name = 'convert_db_server'
|
---|
156 | OR config_name = 'convert_db_user'"
|
---|
157 | );
|
---|
158 | }
|
---|
159 |
|
---|
160 | // Let's see if there is a conversion in the works...
|
---|
161 | $options = array();
|
---|
162 | if (!empty($config['convert_progress']) && !empty($config['convert_db_server']) && !empty($config['convert_db_user']) && !empty($config['convert_options']))
|
---|
163 | {
|
---|
164 | $options = unserialize($config['convert_progress']);
|
---|
165 | $options = array_merge($options, unserialize($config['convert_db_server']), unserialize($config['convert_db_user']), unserialize($config['convert_options']));
|
---|
166 | }
|
---|
167 |
|
---|
168 | // This information should have already been checked once, but do it again for safety
|
---|
169 | if (!empty($options) && !empty($options['tag']) &&
|
---|
170 | isset($options['dbms']) &&
|
---|
171 | isset($options['dbhost']) &&
|
---|
172 | isset($options['dbport']) &&
|
---|
173 | isset($options['dbuser']) &&
|
---|
174 | isset($options['dbpasswd']) &&
|
---|
175 | isset($options['dbname']) &&
|
---|
176 | isset($options['table_prefix']))
|
---|
177 | {
|
---|
178 | $this->page_title = $lang['CONTINUE_CONVERT'];
|
---|
179 |
|
---|
180 | $template->assign_vars(array(
|
---|
181 | 'TITLE' => $lang['CONTINUE_CONVERT'],
|
---|
182 | 'BODY' => $lang['CONTINUE_CONVERT_BODY'],
|
---|
183 | 'L_NEW' => $lang['CONVERT_NEW_CONVERSION'],
|
---|
184 | 'L_CONTINUE' => $lang['CONTINUE_OLD_CONVERSION'],
|
---|
185 | 'S_CONTINUE' => true,
|
---|
186 |
|
---|
187 | 'U_NEW_ACTION' => $this->p_master->module_url . "?mode={$this->mode}&sub=intro&new_conv=1&language=$language",
|
---|
188 | 'U_CONTINUE_ACTION' => $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag={$options['tag']}{$options['step']}&language=$language",
|
---|
189 | ));
|
---|
190 |
|
---|
191 | return;
|
---|
192 | }
|
---|
193 |
|
---|
194 | $this->list_convertors($sub);
|
---|
195 |
|
---|
196 | break;
|
---|
197 |
|
---|
198 | case 'settings':
|
---|
199 | $this->get_convert_settings($sub);
|
---|
200 | break;
|
---|
201 |
|
---|
202 | case 'in_progress':
|
---|
203 | $this->convert_data($sub);
|
---|
204 | break;
|
---|
205 |
|
---|
206 | case 'final':
|
---|
207 | $this->page_title = $lang['CONVERT_COMPLETE'];
|
---|
208 |
|
---|
209 | $template->assign_vars(array(
|
---|
210 | 'TITLE' => $lang['CONVERT_COMPLETE'],
|
---|
211 | 'BODY' => $lang['CONVERT_COMPLETE_EXPLAIN'],
|
---|
212 | ));
|
---|
213 |
|
---|
214 | // If we reached this step (conversion completed) we want to purge the cache and log the user out.
|
---|
215 | // This is for making sure the session get not screwed due to the 3.0.x users table being completely new.
|
---|
216 | $cache->purge();
|
---|
217 |
|
---|
218 | require($phpbb_root_path . 'config.' . $phpEx);
|
---|
219 | require($phpbb_root_path . 'includes/constants.' . $phpEx);
|
---|
220 | require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
|
---|
221 | require($phpbb_root_path . 'includes/functions_convert.' . $phpEx);
|
---|
222 |
|
---|
223 | $db = new $sql_db();
|
---|
224 | $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, true);
|
---|
225 | unset($dbpasswd);
|
---|
226 |
|
---|
227 | $sql = 'SELECT config_value
|
---|
228 | FROM ' . CONFIG_TABLE . '
|
---|
229 | WHERE config_name = \'search_type\'';
|
---|
230 | $result = $db->sql_query($sql);
|
---|
231 |
|
---|
232 | if ($db->sql_fetchfield('config_value') != 'fulltext_mysql')
|
---|
233 | {
|
---|
234 | $template->assign_vars(array(
|
---|
235 | 'S_ERROR_BOX' => true,
|
---|
236 | 'ERROR_TITLE' => $lang['SEARCH_INDEX_UNCONVERTED'],
|
---|
237 | 'ERROR_MSG' => $lang['SEARCH_INDEX_UNCONVERTED_EXPLAIN'],
|
---|
238 | ));
|
---|
239 | }
|
---|
240 |
|
---|
241 | switch ($db->sql_layer)
|
---|
242 | {
|
---|
243 | case 'sqlite':
|
---|
244 | case 'firebird':
|
---|
245 | $db->sql_query('DELETE FROM ' . SESSIONS_KEYS_TABLE);
|
---|
246 | $db->sql_query('DELETE FROM ' . SESSIONS_TABLE);
|
---|
247 | break;
|
---|
248 |
|
---|
249 | default:
|
---|
250 | $db->sql_query('TRUNCATE TABLE ' . SESSIONS_KEYS_TABLE);
|
---|
251 | $db->sql_query('TRUNCATE TABLE ' . SESSIONS_TABLE);
|
---|
252 | break;
|
---|
253 | }
|
---|
254 |
|
---|
255 | break;
|
---|
256 | }
|
---|
257 | }
|
---|
258 |
|
---|
259 | /**
|
---|
260 | * Generate a list of all available conversion modules
|
---|
261 | */
|
---|
262 | function list_convertors($sub)
|
---|
263 | {
|
---|
264 | global $lang, $language, $template, $phpbb_root_path, $phpEx;
|
---|
265 |
|
---|
266 | $this->page_title = $lang['SUB_INTRO'];
|
---|
267 |
|
---|
268 | $template->assign_vars(array(
|
---|
269 | 'TITLE' => $lang['CONVERT_INTRO'],
|
---|
270 | 'BODY' => $lang['CONVERT_INTRO_BODY'],
|
---|
271 |
|
---|
272 | 'L_AUTHOR' => $lang['AUTHOR'],
|
---|
273 | 'L_AVAILABLE_CONVERTORS' => $lang['AVAILABLE_CONVERTORS'],
|
---|
274 | 'L_CONVERT' => $lang['CONVERT'],
|
---|
275 | 'L_NO_CONVERTORS' => $lang['NO_CONVERTORS'],
|
---|
276 | 'L_OPTIONS' => $lang['CONVERT_OPTIONS'],
|
---|
277 | 'L_SOFTWARE' => $lang['SOFTWARE'],
|
---|
278 | 'L_VERSION' => $lang['VERSION'],
|
---|
279 |
|
---|
280 | 'S_LIST' => true,
|
---|
281 | ));
|
---|
282 |
|
---|
283 | $convertors = $sort = array();
|
---|
284 | $get_info = true;
|
---|
285 |
|
---|
286 | $handle = @opendir('./convertors/');
|
---|
287 |
|
---|
288 | if (!$handle)
|
---|
289 | {
|
---|
290 | $this->error('Unable to access the convertors directory', __LINE__, __FILE__);
|
---|
291 | }
|
---|
292 |
|
---|
293 | while ($entry = readdir($handle))
|
---|
294 | {
|
---|
295 | if (preg_match('/^convert_([a-z0-9_]+).' . $phpEx . '$/i', $entry, $m))
|
---|
296 | {
|
---|
297 | include('./convertors/' . $entry);
|
---|
298 | if (isset($convertor_data))
|
---|
299 | {
|
---|
300 | $sort[strtolower($convertor_data['forum_name'])] = sizeof($convertors);
|
---|
301 |
|
---|
302 | $convertors[] = array(
|
---|
303 | 'tag' => $m[1],
|
---|
304 | 'forum_name' => $convertor_data['forum_name'],
|
---|
305 | 'version' => $convertor_data['version'],
|
---|
306 | 'dbms' => $convertor_data['dbms'],
|
---|
307 | 'dbhost' => $convertor_data['dbhost'],
|
---|
308 | 'dbport' => $convertor_data['dbport'],
|
---|
309 | 'dbuser' => $convertor_data['dbuser'],
|
---|
310 | 'dbpasswd' => $convertor_data['dbpasswd'],
|
---|
311 | 'dbname' => $convertor_data['dbname'],
|
---|
312 | 'table_prefix' => $convertor_data['table_prefix'],
|
---|
313 | 'author' => $convertor_data['author']
|
---|
314 | );
|
---|
315 | }
|
---|
316 | unset($convertor_data);
|
---|
317 | }
|
---|
318 | }
|
---|
319 | closedir($handle);
|
---|
320 |
|
---|
321 | @ksort($sort);
|
---|
322 |
|
---|
323 | foreach ($sort as $void => $index)
|
---|
324 | {
|
---|
325 | $template->assign_block_vars('convertors', array(
|
---|
326 | 'AUTHOR' => $convertors[$index]['author'],
|
---|
327 | 'SOFTWARE' => $convertors[$index]['forum_name'],
|
---|
328 | 'VERSION' => $convertors[$index]['version'],
|
---|
329 |
|
---|
330 | 'U_CONVERT' => $this->p_master->module_url . "?mode={$this->mode}&language=$language&sub=settings&tag=" . $convertors[$index]['tag'],
|
---|
331 | ));
|
---|
332 | }
|
---|
333 | }
|
---|
334 |
|
---|
335 | /**
|
---|
336 | */
|
---|
337 | function get_convert_settings($sub)
|
---|
338 | {
|
---|
339 | global $lang, $language, $template, $db, $phpbb_root_path, $phpEx, $config, $cache;
|
---|
340 |
|
---|
341 | require($phpbb_root_path . 'config.' . $phpEx);
|
---|
342 | require($phpbb_root_path . 'includes/constants.' . $phpEx);
|
---|
343 | require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
|
---|
344 | require($phpbb_root_path . 'includes/functions_convert.' . $phpEx);
|
---|
345 |
|
---|
346 | $db = new $sql_db();
|
---|
347 | $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, true);
|
---|
348 | unset($dbpasswd);
|
---|
349 |
|
---|
350 | $this->page_title = $lang['STAGE_SETTINGS'];
|
---|
351 |
|
---|
352 | // We need to fill the config to let internal functions correctly work
|
---|
353 | $sql = 'SELECT *
|
---|
354 | FROM ' . CONFIG_TABLE;
|
---|
355 | $result = $db->sql_query($sql);
|
---|
356 |
|
---|
357 | $config = array();
|
---|
358 | while ($row = $db->sql_fetchrow($result))
|
---|
359 | {
|
---|
360 | $config[$row['config_name']] = $row['config_value'];
|
---|
361 | }
|
---|
362 | $db->sql_freeresult($result);
|
---|
363 |
|
---|
364 | $convertor_tag = request_var('tag', '');
|
---|
365 |
|
---|
366 | if (empty($convertor_tag))
|
---|
367 | {
|
---|
368 | $this->p_master->error($lang['NO_CONVERT_SPECIFIED'], __LINE__, __FILE__);
|
---|
369 | }
|
---|
370 | $get_info = true;
|
---|
371 |
|
---|
372 | // check security implications of direct inclusion
|
---|
373 | $convertor_tag = basename($convertor_tag);
|
---|
374 | if (!file_exists('./convertors/convert_' . $convertor_tag . '.' . $phpEx))
|
---|
375 | {
|
---|
376 | $this->p_master->error($lang['CONVERT_NOT_EXIST'], __LINE__, __FILE__);
|
---|
377 | }
|
---|
378 |
|
---|
379 | include('./convertors/convert_' . $convertor_tag . '.' . $phpEx);
|
---|
380 |
|
---|
381 | // The test_file is a file that should be present in the location of the old board.
|
---|
382 | if (!isset($test_file))
|
---|
383 | {
|
---|
384 | $this->p_master->error($lang['DEV_NO_TEST_FILE'], __LINE__, __FILE__);
|
---|
385 | }
|
---|
386 |
|
---|
387 | $submit = (isset($_POST['submit'])) ? true : false;
|
---|
388 |
|
---|
389 | $src_dbms = request_var('src_dbms', $convertor_data['dbms']);
|
---|
390 | $src_dbhost = request_var('src_dbhost', $convertor_data['dbhost']);
|
---|
391 | $src_dbport = request_var('src_dbport', $convertor_data['dbport']);
|
---|
392 | $src_dbuser = request_var('src_dbuser', $convertor_data['dbuser']);
|
---|
393 | $src_dbpasswd = request_var('src_dbpasswd', $convertor_data['dbpasswd']);
|
---|
394 | $src_dbname = request_var('src_dbname', $convertor_data['dbname']);
|
---|
395 | $src_table_prefix = request_var('src_table_prefix', $convertor_data['table_prefix']);
|
---|
396 | $forum_path = request_var('forum_path', $convertor_data['forum_path']);
|
---|
397 | $refresh = request_var('refresh', 1);
|
---|
398 |
|
---|
399 | // Default URL of the old board
|
---|
400 | // @todo Are we going to use this for attempting to convert URL references in posts, or should we remove it?
|
---|
401 | // -> We should convert old urls to the new relative urls format
|
---|
402 | // $src_url = request_var('src_url', 'Not in use at the moment');
|
---|
403 |
|
---|
404 | // strip trailing slash from old forum path
|
---|
405 | $forum_path = (strlen($forum_path) && $forum_path[strlen($forum_path) - 1] == '/') ? substr($forum_path, 0, -1) : $forum_path;
|
---|
406 |
|
---|
407 | $error = array();
|
---|
408 | if ($submit)
|
---|
409 | {
|
---|
410 | if (!@file_exists('./../' . $forum_path . '/' . $test_file))
|
---|
411 | {
|
---|
412 | $error[] = sprintf($lang['COULD_NOT_FIND_PATH'], $forum_path);
|
---|
413 | }
|
---|
414 |
|
---|
415 | $connect_test = false;
|
---|
416 | $available_dbms = get_available_dbms(false, true, true);
|
---|
417 |
|
---|
418 | if (!isset($available_dbms[$src_dbms]) || !$available_dbms[$src_dbms]['AVAILABLE'])
|
---|
419 | {
|
---|
420 | $error['db'][] = $lang['INST_ERR_NO_DB'];
|
---|
421 | $connect_test = false;
|
---|
422 | }
|
---|
423 | else
|
---|
424 | {
|
---|
425 | $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);
|
---|
426 | }
|
---|
427 |
|
---|
428 | // The forum prefix of the old and the new forum can only be the same if two different databases are used.
|
---|
429 | if ($src_table_prefix == $table_prefix && $src_dbms == $dbms && $src_dbhost == $dbhost && $src_dbport == $dbport && $src_dbname == $dbname)
|
---|
430 | {
|
---|
431 | $error[] = sprintf($lang['TABLE_PREFIX_SAME'], $src_table_prefix);
|
---|
432 | }
|
---|
433 |
|
---|
434 | // Check table prefix
|
---|
435 | if (!sizeof($error))
|
---|
436 | {
|
---|
437 | // initiate database connection to old db if old and new db differ
|
---|
438 | global $src_db, $same_db;
|
---|
439 | $src_db = $same_db = false;
|
---|
440 |
|
---|
441 | if ($src_dbms != $dbms || $src_dbhost != $dbhost || $src_dbport != $dbport || $src_dbname != $dbname || $src_dbuser != $dbuser)
|
---|
442 | {
|
---|
443 | $sql_db = 'dbal_' . $src_dbms;
|
---|
444 | $src_db = new $sql_db();
|
---|
445 | $src_db->sql_connect($src_dbhost, $src_dbuser, htmlspecialchars_decode($src_dbpasswd), $src_dbname, $src_dbport, false, true);
|
---|
446 | $same_db = false;
|
---|
447 | }
|
---|
448 | else
|
---|
449 | {
|
---|
450 | $src_db = $db;
|
---|
451 | $same_db = true;
|
---|
452 | }
|
---|
453 |
|
---|
454 | $src_db->sql_return_on_error(true);
|
---|
455 | $db->sql_return_on_error(true);
|
---|
456 |
|
---|
457 | // Try to select one row from the first table to see if the prefix is OK
|
---|
458 | $result = $src_db->sql_query_limit('SELECT * FROM ' . $src_table_prefix . $tables[0], 1);
|
---|
459 |
|
---|
460 | if (!$result)
|
---|
461 | {
|
---|
462 | $prefixes = array();
|
---|
463 |
|
---|
464 | $tables_existing = get_tables($src_db);
|
---|
465 | $tables_existing = array_map('strtolower', $tables_existing);
|
---|
466 | foreach ($tables_existing as $table_name)
|
---|
467 | {
|
---|
468 | compare_table($tables, $table_name, $prefixes);
|
---|
469 | }
|
---|
470 | unset($tables_existing);
|
---|
471 |
|
---|
472 | foreach ($prefixes as $prefix => $count)
|
---|
473 | {
|
---|
474 | if ($count >= sizeof($tables))
|
---|
475 | {
|
---|
476 | $possible_prefix = $prefix;
|
---|
477 | break;
|
---|
478 | }
|
---|
479 | }
|
---|
480 |
|
---|
481 | $msg = '';
|
---|
482 | if (!empty($convertor_data['table_prefix']))
|
---|
483 | {
|
---|
484 | $msg .= sprintf($lang['DEFAULT_PREFIX_IS'], $convertor_data['forum_name'], $convertor_data['table_prefix']);
|
---|
485 | }
|
---|
486 |
|
---|
487 | if (!empty($possible_prefix))
|
---|
488 | {
|
---|
489 | $msg .= '<br />';
|
---|
490 | $msg .= ($possible_prefix == '*') ? $lang['BLANK_PREFIX_FOUND'] : sprintf($lang['PREFIX_FOUND'], $possible_prefix);
|
---|
491 | $src_table_prefix = ($possible_prefix == '*') ? '' : $possible_prefix;
|
---|
492 | }
|
---|
493 |
|
---|
494 | $error[] = $msg;
|
---|
495 | }
|
---|
496 | $src_db->sql_freeresult($result);
|
---|
497 | $src_db->sql_return_on_error(false);
|
---|
498 | }
|
---|
499 |
|
---|
500 | if (!sizeof($error))
|
---|
501 | {
|
---|
502 | // Save convertor Status
|
---|
503 | set_config('convert_progress', serialize(array(
|
---|
504 | 'step' => '',
|
---|
505 | 'table_prefix' => $src_table_prefix,
|
---|
506 | 'tag' => $convertor_tag,
|
---|
507 | )), true);
|
---|
508 | set_config('convert_db_server', serialize(array(
|
---|
509 | 'dbms' => $src_dbms,
|
---|
510 | 'dbhost' => $src_dbhost,
|
---|
511 | 'dbport' => $src_dbport,
|
---|
512 | 'dbname' => $src_dbname,
|
---|
513 | )), true);
|
---|
514 | set_config('convert_db_user', serialize(array(
|
---|
515 | 'dbuser' => $src_dbuser,
|
---|
516 | 'dbpasswd' => $src_dbpasswd,
|
---|
517 | )), true);
|
---|
518 |
|
---|
519 | // Save options
|
---|
520 | set_config('convert_options', serialize(array('forum_path' => './../' . $forum_path, 'refresh' => $refresh)), true);
|
---|
521 |
|
---|
522 | $template->assign_block_vars('checks', array(
|
---|
523 | 'TITLE' => $lang['VERIFY_OPTIONS'],
|
---|
524 | 'RESULT' => $lang['CONVERT_SETTINGS_VERIFIED'],
|
---|
525 | ));
|
---|
526 |
|
---|
527 | $template->assign_vars(array(
|
---|
528 | 'L_SUBMIT' => $lang['BEGIN_CONVERT'],
|
---|
529 | // 'S_HIDDEN' => $s_hidden_fields,
|
---|
530 | 'U_ACTION' => $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag=$convertor_tag&language=$language",
|
---|
531 | ));
|
---|
532 |
|
---|
533 | return;
|
---|
534 | }
|
---|
535 | else
|
---|
536 | {
|
---|
537 | $template->assign_block_vars('checks', array(
|
---|
538 | 'TITLE' => $lang['VERIFY_OPTIONS'],
|
---|
539 | 'RESULT' => '<b style="color:red">' . implode('<br />', $error) . '</b>',
|
---|
540 | ));
|
---|
541 | }
|
---|
542 | } // end submit
|
---|
543 |
|
---|
544 | foreach ($this->convert_options as $config_key => $vars)
|
---|
545 | {
|
---|
546 | if (!is_array($vars) && strpos($config_key, 'legend') === false)
|
---|
547 | {
|
---|
548 | continue;
|
---|
549 | }
|
---|
550 |
|
---|
551 | if (strpos($config_key, 'legend') !== false)
|
---|
552 | {
|
---|
553 | $template->assign_block_vars('options', array(
|
---|
554 | 'S_LEGEND' => true,
|
---|
555 | 'LEGEND' => $lang[$vars])
|
---|
556 | );
|
---|
557 |
|
---|
558 | continue;
|
---|
559 | }
|
---|
560 |
|
---|
561 | $options = isset($vars['options']) ? $vars['options'] : '';
|
---|
562 |
|
---|
563 | $template->assign_block_vars('options', array(
|
---|
564 | 'KEY' => $config_key,
|
---|
565 | 'TITLE' => $lang[$vars['lang']],
|
---|
566 | 'S_EXPLAIN' => $vars['explain'],
|
---|
567 | 'S_LEGEND' => false,
|
---|
568 | 'TITLE_EXPLAIN' => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '',
|
---|
569 | 'CONTENT' => $this->p_master->input_field($config_key, $vars['type'], $$config_key, $options),
|
---|
570 | )
|
---|
571 | );
|
---|
572 | }
|
---|
573 |
|
---|
574 | $template->assign_vars(array(
|
---|
575 | 'TITLE' => $lang['STAGE_SETTINGS'],
|
---|
576 | 'BODY' => $lang['CONV_OPTIONS_BODY'],
|
---|
577 | 'L_SUBMIT' => $lang['BEGIN_CONVERT'],
|
---|
578 | 'U_ACTION' => $this->p_master->module_url . "?mode={$this->mode}&sub=settings&tag=$convertor_tag&language=$language",
|
---|
579 | ));
|
---|
580 | }
|
---|
581 |
|
---|
582 | /**
|
---|
583 | * The function which does the actual work (or dispatches it to the relevant places)
|
---|
584 | */
|
---|
585 | function convert_data($sub)
|
---|
586 | {
|
---|
587 | global $template, $user, $phpbb_root_path, $phpEx, $db, $lang, $config, $cache;
|
---|
588 | global $convert, $convert_row, $message_parser, $skip_rows, $language;
|
---|
589 |
|
---|
590 | require($phpbb_root_path . 'config.' . $phpEx);
|
---|
591 | require($phpbb_root_path . 'includes/constants.' . $phpEx);
|
---|
592 | require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
|
---|
593 | require($phpbb_root_path . 'includes/functions_convert.' . $phpEx);
|
---|
594 |
|
---|
595 | $db = new $sql_db();
|
---|
596 | $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, true);
|
---|
597 | unset($dbpasswd);
|
---|
598 |
|
---|
599 | $sql = 'SELECT *
|
---|
600 | FROM ' . CONFIG_TABLE;
|
---|
601 | $result = $db->sql_query($sql);
|
---|
602 |
|
---|
603 | $config = array();
|
---|
604 | while ($row = $db->sql_fetchrow($result))
|
---|
605 | {
|
---|
606 | $config[$row['config_name']] = $row['config_value'];
|
---|
607 | }
|
---|
608 | $db->sql_freeresult($result);
|
---|
609 |
|
---|
610 | // Override a couple of config variables for the duration
|
---|
611 | $config['max_quote_depth'] = 0;
|
---|
612 |
|
---|
613 | // @todo Need to confirm that max post length in source is <= max post length in destination or there may be interesting formatting issues
|
---|
614 | $config['max_post_chars'] = 0;
|
---|
615 |
|
---|
616 | // Set up a user as well. We _should_ have enough of a database here at this point to do this
|
---|
617 | // and it helps for any core code we call
|
---|
618 | $user->session_begin();
|
---|
619 | $user->page = $user->extract_current_page($phpbb_root_path);
|
---|
620 |
|
---|
621 | // This is a little bit of a fudge, but it allows the language entries to be available to the
|
---|
622 | // core code without us loading them again
|
---|
623 | $user->lang = &$lang;
|
---|
624 |
|
---|
625 | $this->page_title = $user->lang['STAGE_IN_PROGRESS'];
|
---|
626 |
|
---|
627 | $convert->options = array();
|
---|
628 | if (isset($config['convert_progress']))
|
---|
629 | {
|
---|
630 | $convert->options = unserialize($config['convert_progress']);
|
---|
631 | $convert->options = array_merge($convert->options, unserialize($config['convert_db_server']), unserialize($config['convert_db_user']), unserialize($config['convert_options']));
|
---|
632 | }
|
---|
633 |
|
---|
634 | // This information should have already been checked once, but do it again for safety
|
---|
635 | if (empty($convert->options) || empty($convert->options['tag']) ||
|
---|
636 | !isset($convert->options['dbms']) ||
|
---|
637 | !isset($convert->options['dbhost']) ||
|
---|
638 | !isset($convert->options['dbport']) ||
|
---|
639 | !isset($convert->options['dbuser']) ||
|
---|
640 | !isset($convert->options['dbpasswd']) ||
|
---|
641 | !isset($convert->options['dbname']) ||
|
---|
642 | !isset($convert->options['table_prefix']))
|
---|
643 | {
|
---|
644 | $this->p_master->error($user->lang['NO_CONVERT_SPECIFIED'], __LINE__, __FILE__);
|
---|
645 | }
|
---|
646 |
|
---|
647 | // Make some short variables accessible, for easier referencing
|
---|
648 | $convert->convertor_tag = basename($convert->options['tag']);
|
---|
649 | $convert->src_dbms = $convert->options['dbms'];
|
---|
650 | $convert->src_dbhost = $convert->options['dbhost'];
|
---|
651 | $convert->src_dbport = $convert->options['dbport'];
|
---|
652 | $convert->src_dbuser = $convert->options['dbuser'];
|
---|
653 | $convert->src_dbpasswd = $convert->options['dbpasswd'];
|
---|
654 | $convert->src_dbname = $convert->options['dbname'];
|
---|
655 | $convert->src_table_prefix = $convert->options['table_prefix'];
|
---|
656 |
|
---|
657 | // initiate database connection to old db if old and new db differ
|
---|
658 | global $src_db, $same_db;
|
---|
659 | $src_db = $same_db = null;
|
---|
660 | if ($convert->src_dbms != $dbms || $convert->src_dbhost != $dbhost || $convert->src_dbport != $dbport || $convert->src_dbname != $dbname || $convert->src_dbuser != $dbuser)
|
---|
661 | {
|
---|
662 | if ($convert->src_dbms != $dbms)
|
---|
663 | {
|
---|
664 | require($phpbb_root_path . 'includes/db/' . $convert->src_dbms . '.' . $phpEx);
|
---|
665 | }
|
---|
666 | $sql_db = 'dbal_' . $convert->src_dbms;
|
---|
667 | $src_db = new $sql_db();
|
---|
668 | $src_db->sql_connect($convert->src_dbhost, $convert->src_dbuser, htmlspecialchars_decode($convert->src_dbpasswd), $convert->src_dbname, $convert->src_dbport, false, true);
|
---|
669 | $same_db = false;
|
---|
670 | }
|
---|
671 | else
|
---|
672 | {
|
---|
673 | $src_db = $db;
|
---|
674 | $same_db = true;
|
---|
675 | }
|
---|
676 |
|
---|
677 | $convert->mysql_convert = false;
|
---|
678 | switch ($src_db->sql_layer)
|
---|
679 | {
|
---|
680 | case 'sqlite':
|
---|
681 | case 'firebird':
|
---|
682 | $convert->src_truncate_statement = 'DELETE FROM ';
|
---|
683 | break;
|
---|
684 |
|
---|
685 | // Thanks MySQL, for silently converting...
|
---|
686 | case 'mysql':
|
---|
687 | case 'mysql4':
|
---|
688 | if (version_compare($src_db->sql_server_info(true), '4.1.3', '>='))
|
---|
689 | {
|
---|
690 | $convert->mysql_convert = true;
|
---|
691 | }
|
---|
692 | $convert->src_truncate_statement = 'TRUNCATE TABLE ';
|
---|
693 | break;
|
---|
694 |
|
---|
695 | case 'mysqli':
|
---|
696 | $convert->mysql_convert = true;
|
---|
697 | $convert->src_truncate_statement = 'TRUNCATE TABLE ';
|
---|
698 | break;
|
---|
699 |
|
---|
700 | default:
|
---|
701 | $convert->src_truncate_statement = 'TRUNCATE TABLE ';
|
---|
702 | break;
|
---|
703 | }
|
---|
704 |
|
---|
705 | if ($convert->mysql_convert && !$same_db)
|
---|
706 | {
|
---|
707 | $src_db->sql_query("SET NAMES 'binary'");
|
---|
708 | }
|
---|
709 |
|
---|
710 | switch ($db->sql_layer)
|
---|
711 | {
|
---|
712 | case 'sqlite':
|
---|
713 | case 'firebird':
|
---|
714 | $convert->truncate_statement = 'DELETE FROM ';
|
---|
715 | break;
|
---|
716 |
|
---|
717 | default:
|
---|
718 | $convert->truncate_statement = 'TRUNCATE TABLE ';
|
---|
719 | break;
|
---|
720 | }
|
---|
721 |
|
---|
722 | $get_info = false;
|
---|
723 |
|
---|
724 | // check security implications of direct inclusion
|
---|
725 | if (!file_exists('./convertors/convert_' . $convert->convertor_tag . '.' . $phpEx))
|
---|
726 | {
|
---|
727 | $this->p_master->error($user->lang['CONVERT_NOT_EXIST'], __LINE__, __FILE__);
|
---|
728 | }
|
---|
729 |
|
---|
730 | if (file_exists('./convertors/functions_' . $convert->convertor_tag . '.' . $phpEx))
|
---|
731 | {
|
---|
732 | include('./convertors/functions_' . $convert->convertor_tag . '.' . $phpEx);
|
---|
733 | }
|
---|
734 |
|
---|
735 | $get_info = true;
|
---|
736 | include('./convertors/convert_' . $convert->convertor_tag . '.' . $phpEx);
|
---|
737 |
|
---|
738 | // Map some variables...
|
---|
739 | $convert->convertor_data = $convertor_data;
|
---|
740 | $convert->tables = $tables;
|
---|
741 | $convert->config_schema = $config_schema;
|
---|
742 |
|
---|
743 | // Now include the real data
|
---|
744 | $get_info = false;
|
---|
745 | include('./convertors/convert_' . $convert->convertor_tag . '.' . $phpEx);
|
---|
746 |
|
---|
747 | $convert->convertor_data = $convertor_data;
|
---|
748 | $convert->tables = $tables;
|
---|
749 | $convert->config_schema = $config_schema;
|
---|
750 | $convert->convertor = $convertor;
|
---|
751 |
|
---|
752 | // The test_file is a file that should be present in the location of the old board.
|
---|
753 | if (!file_exists($convert->options['forum_path'] . '/' . $test_file))
|
---|
754 | {
|
---|
755 | $this->p_master->error(sprintf($user->lang['COULD_NOT_FIND_PATH'], $convert->options['forum_path']), __LINE__, __FILE__);
|
---|
756 | }
|
---|
757 |
|
---|
758 | $search_type = basename(trim($config['search_type']));
|
---|
759 |
|
---|
760 | // For conversions we are a bit less strict and set to a search backend we know exist...
|
---|
761 | if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx))
|
---|
762 | {
|
---|
763 | $search_type = 'fulltext_native';
|
---|
764 | set_config('search_type', $search_type);
|
---|
765 | }
|
---|
766 |
|
---|
767 | if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx))
|
---|
768 | {
|
---|
769 | trigger_error('NO_SUCH_SEARCH_MODULE');
|
---|
770 | }
|
---|
771 |
|
---|
772 | require($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx);
|
---|
773 |
|
---|
774 | $error = false;
|
---|
775 | $convert->fulltext_search = new $search_type($error);
|
---|
776 |
|
---|
777 | if ($error)
|
---|
778 | {
|
---|
779 | trigger_error($error);
|
---|
780 | }
|
---|
781 |
|
---|
782 | include($phpbb_root_path . 'includes/message_parser.' . $phpEx);
|
---|
783 | $message_parser = new parse_message();
|
---|
784 |
|
---|
785 | $jump = request_var('jump', 0);
|
---|
786 | $final_jump = request_var('final_jump', 0);
|
---|
787 | $sync_batch = request_var('sync_batch', -1);
|
---|
788 | $last_statement = request_var('last', 0);
|
---|
789 |
|
---|
790 | // We are running sync...
|
---|
791 | if ($sync_batch >= 0)
|
---|
792 | {
|
---|
793 | $this->sync_forums($sync_batch);
|
---|
794 | return;
|
---|
795 | }
|
---|
796 |
|
---|
797 | if ($jump)
|
---|
798 | {
|
---|
799 | $this->jump($jump, $last_statement);
|
---|
800 | return;
|
---|
801 | }
|
---|
802 |
|
---|
803 | if ($final_jump)
|
---|
804 | {
|
---|
805 | $this->final_jump($final_jump);
|
---|
806 | return;
|
---|
807 | }
|
---|
808 |
|
---|
809 | $current_table = request_var('current_table', 0);
|
---|
810 | $old_current_table = min(-1, $current_table - 1);
|
---|
811 | $skip_rows = request_var('skip_rows', 0);
|
---|
812 |
|
---|
813 | if (!$current_table && !$skip_rows)
|
---|
814 | {
|
---|
815 | if (empty($_REQUEST['confirm']))
|
---|
816 | {
|
---|
817 | // If avatars / ranks / smilies folders are specified make sure they are writable
|
---|
818 | $bad_folders = array();
|
---|
819 |
|
---|
820 | $local_paths = array(
|
---|
821 | 'avatar_path' => path($config['avatar_path']),
|
---|
822 | 'avatar_gallery_path' => path($config['avatar_gallery_path']),
|
---|
823 | 'icons_path' => path($config['icons_path']),
|
---|
824 | 'ranks_path' => path($config['ranks_path']),
|
---|
825 | 'smilies_path' => path($config['smilies_path'])
|
---|
826 | );
|
---|
827 |
|
---|
828 | foreach ($local_paths as $folder => $local_path)
|
---|
829 | {
|
---|
830 | if (isset($convert->convertor[$folder]))
|
---|
831 | {
|
---|
832 | if (empty($convert->convertor['test_file']))
|
---|
833 | {
|
---|
834 | // test_file is mandantory at the moment so this should never be reached, but just in case...
|
---|
835 | $this->p_master->error($user->lang['DEV_NO_TEST_FILE'], __LINE__, __FILE__);
|
---|
836 | }
|
---|
837 |
|
---|
838 | if (!$local_path || !@is_writable($phpbb_root_path . $local_path))
|
---|
839 | {
|
---|
840 | if (!$local_path)
|
---|
841 | {
|
---|
842 | $bad_folders[] = sprintf($user->lang['CONFIG_PHPBB_EMPTY'], $folder);
|
---|
843 | }
|
---|
844 | else
|
---|
845 | {
|
---|
846 | $bad_folders[] = $local_path;
|
---|
847 | }
|
---|
848 | }
|
---|
849 | }
|
---|
850 | }
|
---|
851 |
|
---|
852 | if (sizeof($bad_folders))
|
---|
853 | {
|
---|
854 | $msg = (sizeof($bad_folders) == 1) ? $user->lang['MAKE_FOLDER_WRITABLE'] : $user->lang['MAKE_FOLDERS_WRITABLE'];
|
---|
855 | sort($bad_folders);
|
---|
856 | $this->p_master->error(sprintf($msg, implode('<br />', $bad_folders)), __LINE__, __FILE__, true);
|
---|
857 |
|
---|
858 | $template->assign_vars(array(
|
---|
859 | 'L_SUBMIT' => $user->lang['INSTALL_TEST'],
|
---|
860 | 'U_ACTION' => $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag={$convert->convertor_tag}&language=$language",
|
---|
861 | ));
|
---|
862 | return;
|
---|
863 | }
|
---|
864 |
|
---|
865 | // Grab all the tables used in convertor
|
---|
866 | $missing_tables = $tables_list = $aliases = array();
|
---|
867 |
|
---|
868 | foreach ($convert->convertor['schema'] as $schema)
|
---|
869 | {
|
---|
870 | // Skip those not used (because of addons/plugins not detected)
|
---|
871 | if (!$schema['target'])
|
---|
872 | {
|
---|
873 | continue;
|
---|
874 | }
|
---|
875 |
|
---|
876 | foreach ($schema as $key => $val)
|
---|
877 | {
|
---|
878 | // we're dealing with an array like:
|
---|
879 | // array('forum_status', 'forums.forum_status', 'is_item_locked')
|
---|
880 | if (is_int($key) && !empty($val[1]))
|
---|
881 | {
|
---|
882 | $temp_data = $val[1];
|
---|
883 | if (!is_array($temp_data))
|
---|
884 | {
|
---|
885 | $temp_data = array($temp_data);
|
---|
886 | }
|
---|
887 |
|
---|
888 | foreach ($temp_data as $val)
|
---|
889 | {
|
---|
890 | if (preg_match('/([a-z0-9_]+)\.([a-z0-9_]+)\)* ?A?S? ?([a-z0-9_]*?)\.?([a-z0-9_]*)$/i', $val, $m))
|
---|
891 | {
|
---|
892 | $table = $convert->src_table_prefix . $m[1];
|
---|
893 | $tables_list[$table] = $table;
|
---|
894 |
|
---|
895 | if (!empty($m[3]))
|
---|
896 | {
|
---|
897 | $aliases[] = $convert->src_table_prefix . $m[3];
|
---|
898 | }
|
---|
899 | }
|
---|
900 | }
|
---|
901 | }
|
---|
902 | // 'left_join' => 'topics LEFT JOIN vote_desc ON topics.topic_id = vote_desc.topic_id AND topics.topic_vote = 1'
|
---|
903 | else if ($key == 'left_join')
|
---|
904 | {
|
---|
905 | // Convert the value if it wasn't an array already.
|
---|
906 | if (!is_array($val))
|
---|
907 | {
|
---|
908 | $val = array($val);
|
---|
909 | }
|
---|
910 |
|
---|
911 | for ($j = 0; $j < sizeof($val); ++$j)
|
---|
912 | {
|
---|
913 | if (preg_match('/LEFT JOIN ([a-z0-9_]+) AS ([a-z0-9_]+)/i', $val[$j], $m))
|
---|
914 | {
|
---|
915 | $table = $convert->src_table_prefix . $m[1];
|
---|
916 | $tables_list[$table] = $table;
|
---|
917 |
|
---|
918 | if (!empty($m[2]))
|
---|
919 | {
|
---|
920 | $aliases[] = $convert->src_table_prefix . $m[2];
|
---|
921 | }
|
---|
922 | }
|
---|
923 | }
|
---|
924 | }
|
---|
925 | }
|
---|
926 | }
|
---|
927 |
|
---|
928 | // Remove aliased tables from $tables_list
|
---|
929 | foreach ($aliases as $alias)
|
---|
930 | {
|
---|
931 | unset($tables_list[$alias]);
|
---|
932 | }
|
---|
933 |
|
---|
934 | // Check if the tables that we need exist
|
---|
935 | $src_db->sql_return_on_error(true);
|
---|
936 | foreach ($tables_list as $table => $null)
|
---|
937 | {
|
---|
938 | $sql = 'SELECT 1 FROM ' . $table;
|
---|
939 | $_result = $src_db->sql_query_limit($sql, 1);
|
---|
940 |
|
---|
941 | if (!$_result)
|
---|
942 | {
|
---|
943 | $missing_tables[] = $table;
|
---|
944 | }
|
---|
945 | $src_db->sql_freeresult($_result);
|
---|
946 | }
|
---|
947 | $src_db->sql_return_on_error(false);
|
---|
948 |
|
---|
949 | // Throw an error if some tables are missing
|
---|
950 | // 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
|
---|
951 |
|
---|
952 | if (sizeof($missing_tables) == sizeof($tables_list))
|
---|
953 | {
|
---|
954 | $this->p_master->error($user->lang['NO_TABLES_FOUND'] . ' ' . $user->lang['CHECK_TABLE_PREFIX'], __LINE__, __FILE__);
|
---|
955 | }
|
---|
956 | else if (sizeof($missing_tables))
|
---|
957 | {
|
---|
958 | $this->p_master->error(sprintf($user->lang['TABLES_MISSING'], implode(', ', $missing_tables)) . '<br /><br />' . $user->lang['CHECK_TABLE_PREFIX'], __LINE__, __FILE__);
|
---|
959 | }
|
---|
960 |
|
---|
961 | $url = $this->save_convert_progress('&confirm=1');
|
---|
962 | $msg = $user->lang['PRE_CONVERT_COMPLETE'];
|
---|
963 |
|
---|
964 | if ($convert->convertor_data['author_notes'])
|
---|
965 | {
|
---|
966 | $msg .= '</p><p>' . sprintf($user->lang['AUTHOR_NOTES'], $convert->convertor_data['author_notes']);
|
---|
967 | }
|
---|
968 |
|
---|
969 | $template->assign_vars(array(
|
---|
970 | 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'],
|
---|
971 | 'L_MESSAGE' => $msg,
|
---|
972 | 'U_ACTION' => $url,
|
---|
973 | ));
|
---|
974 |
|
---|
975 | return;
|
---|
976 | } // if (empty($_REQUEST['confirm']))
|
---|
977 |
|
---|
978 | $template->assign_block_vars('checks', array(
|
---|
979 | 'S_LEGEND' => true,
|
---|
980 | 'LEGEND' => $user->lang['STARTING_CONVERT'],
|
---|
981 | ));
|
---|
982 |
|
---|
983 | // Convert the config table and load the settings of the old board
|
---|
984 | if (!empty($convert->config_schema))
|
---|
985 | {
|
---|
986 | restore_config($convert->config_schema);
|
---|
987 |
|
---|
988 | // Override a couple of config variables for the duration
|
---|
989 | $config['max_quote_depth'] = 0;
|
---|
990 |
|
---|
991 | // @todo Need to confirm that max post length in source is <= max post length in destination or there may be interesting formatting issues
|
---|
992 | $config['max_post_chars'] = 0;
|
---|
993 | }
|
---|
994 |
|
---|
995 | $template->assign_block_vars('checks', array(
|
---|
996 | 'TITLE' => $user->lang['CONFIG_CONVERT'],
|
---|
997 | 'RESULT' => $user->lang['DONE'],
|
---|
998 | ));
|
---|
999 |
|
---|
1000 | // Now process queries and execute functions that have to be executed prior to the conversion
|
---|
1001 | if (!empty($convert->convertor['execute_first']))
|
---|
1002 | {
|
---|
1003 | eval($convert->convertor['execute_first']);
|
---|
1004 | }
|
---|
1005 |
|
---|
1006 | if (!empty($convert->convertor['query_first']))
|
---|
1007 | {
|
---|
1008 | if (!is_array($convert->convertor['query_first']))
|
---|
1009 | {
|
---|
1010 | $convert->convertor['query_first'] = array('target', array($convert->convertor['query_first']));
|
---|
1011 | }
|
---|
1012 | else if (!is_array($convert->convertor['query_first'][0]))
|
---|
1013 | {
|
---|
1014 | $convert->convertor['query_first'] = array(array($convert->convertor['query_first'][0], $convert->convertor['query_first'][1]));
|
---|
1015 | }
|
---|
1016 |
|
---|
1017 | foreach ($convert->convertor['query_first'] as $query_first)
|
---|
1018 | {
|
---|
1019 | if ($query_first[0] == 'src')
|
---|
1020 | {
|
---|
1021 | if ($convert->mysql_convert && $same_db)
|
---|
1022 | {
|
---|
1023 | $src_db->sql_query("SET NAMES 'binary'");
|
---|
1024 | }
|
---|
1025 |
|
---|
1026 | $src_db->sql_query($query_first[1]);
|
---|
1027 |
|
---|
1028 | if ($convert->mysql_convert && $same_db)
|
---|
1029 | {
|
---|
1030 | $src_db->sql_query("SET NAMES 'utf8'");
|
---|
1031 | }
|
---|
1032 | }
|
---|
1033 | else
|
---|
1034 | {
|
---|
1035 | $db->sql_query($query_first[1]);
|
---|
1036 | }
|
---|
1037 | }
|
---|
1038 | }
|
---|
1039 |
|
---|
1040 | $template->assign_block_vars('checks', array(
|
---|
1041 | 'TITLE' => $user->lang['PREPROCESS_STEP'],
|
---|
1042 | 'RESULT' => $user->lang['DONE'],
|
---|
1043 | ));
|
---|
1044 | } // if (!$current_table && !$skip_rows)
|
---|
1045 |
|
---|
1046 | $template->assign_block_vars('checks', array(
|
---|
1047 | 'S_LEGEND' => true,
|
---|
1048 | 'LEGEND' => $user->lang['FILLING_TABLES'],
|
---|
1049 | ));
|
---|
1050 |
|
---|
1051 | // This loop takes one target table and processes it
|
---|
1052 | while ($current_table < sizeof($convert->convertor['schema']))
|
---|
1053 | {
|
---|
1054 | $schema = $convert->convertor['schema'][$current_table];
|
---|
1055 |
|
---|
1056 | // The target table isn't set, this can be because a module (for example the attachement mod) is taking care of this.
|
---|
1057 | if (empty($schema['target']))
|
---|
1058 | {
|
---|
1059 | $current_table++;
|
---|
1060 | continue;
|
---|
1061 | }
|
---|
1062 |
|
---|
1063 | $template->assign_block_vars('checks', array(
|
---|
1064 | 'TITLE' => sprintf($user->lang['FILLING_TABLE'], $schema['target']),
|
---|
1065 | ));
|
---|
1066 |
|
---|
1067 | // This is only the case when we first start working on the tables.
|
---|
1068 | if (!$skip_rows)
|
---|
1069 | {
|
---|
1070 | // process execute_first and query_first for this table...
|
---|
1071 | if (!empty($schema['execute_first']))
|
---|
1072 | {
|
---|
1073 | eval($schema['execute_first']);
|
---|
1074 | }
|
---|
1075 |
|
---|
1076 | if (!empty($schema['query_first']))
|
---|
1077 | {
|
---|
1078 | if (!is_array($schema['query_first']))
|
---|
1079 | {
|
---|
1080 | $schema['query_first'] = array('target', array($schema['query_first']));
|
---|
1081 | }
|
---|
1082 | else if (!is_array($schema['query_first'][0]))
|
---|
1083 | {
|
---|
1084 | $schema['query_first'] = array(array($schema['query_first'][0], $schema['query_first'][1]));
|
---|
1085 | }
|
---|
1086 |
|
---|
1087 | foreach ($schema['query_first'] as $query_first)
|
---|
1088 | {
|
---|
1089 | if ($query_first[0] == 'src')
|
---|
1090 | {
|
---|
1091 | if ($convert->mysql_convert && $same_db)
|
---|
1092 | {
|
---|
1093 | $src_db->sql_query("SET NAMES 'binary'");
|
---|
1094 | }
|
---|
1095 | $src_db->sql_query($query_first[1]);
|
---|
1096 | if ($convert->mysql_convert && $same_db)
|
---|
1097 | {
|
---|
1098 | $src_db->sql_query("SET NAMES 'utf8'");
|
---|
1099 | }
|
---|
1100 | }
|
---|
1101 | else
|
---|
1102 | {
|
---|
1103 | $db->sql_query($query_first[1]);
|
---|
1104 | }
|
---|
1105 | }
|
---|
1106 | }
|
---|
1107 |
|
---|
1108 | if (!empty($schema['autoincrement']))
|
---|
1109 | {
|
---|
1110 | switch ($db->sql_layer)
|
---|
1111 | {
|
---|
1112 | case 'postgres':
|
---|
1113 | $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'] . '));');
|
---|
1114 | break;
|
---|
1115 |
|
---|
1116 | case 'oracle':
|
---|
1117 | $result = $db->sql_query('SELECT MAX(' . $schema['autoincrement'] . ') as max_id FROM ' . $schema['target']);
|
---|
1118 | $row = $db->sql_fetchrow($result);
|
---|
1119 | $db->sql_freeresult($result);
|
---|
1120 |
|
---|
1121 | $largest_id = (int) $row['max_id'];
|
---|
1122 |
|
---|
1123 | if ($largest_id)
|
---|
1124 | {
|
---|
1125 | $db->sql_query('DROP SEQUENCE ' . $schema['target'] . '_seq');
|
---|
1126 | $db->sql_query('CREATE SEQUENCE ' . $schema['target'] . '_seq START WITH ' . ($largest_id + 1));
|
---|
1127 | }
|
---|
1128 | break;
|
---|
1129 | }
|
---|
1130 | }
|
---|
1131 | }
|
---|
1132 |
|
---|
1133 | // Process execute_always for this table
|
---|
1134 | // This is for code which needs to be executed on every pass of this table if
|
---|
1135 | // it gets split because of time restrictions
|
---|
1136 | if (!empty($schema['execute_always']))
|
---|
1137 | {
|
---|
1138 | eval($schema['execute_always']);
|
---|
1139 | }
|
---|
1140 |
|
---|
1141 | //
|
---|
1142 | // Set up some variables
|
---|
1143 | //
|
---|
1144 | // $waiting_rows holds rows for multirows insertion (MySQL only)
|
---|
1145 | // $src_tables holds unique tables with aliases to select from
|
---|
1146 | // $src_fields will quickly refer source fields (or aliases) corresponding to the current index
|
---|
1147 | // $select_fields holds the names of the fields to retrieve
|
---|
1148 | //
|
---|
1149 |
|
---|
1150 | $sql_data = array(
|
---|
1151 | 'source_fields' => array(),
|
---|
1152 | 'target_fields' => array(),
|
---|
1153 | 'source_tables' => array(),
|
---|
1154 | 'select_fields' => array(),
|
---|
1155 | );
|
---|
1156 |
|
---|
1157 | // This statement is building the keys for later insertion.
|
---|
1158 | $insert_query = $this->build_insert_query($schema, $sql_data, $current_table);
|
---|
1159 |
|
---|
1160 | // If no source table is affected, we skip the table
|
---|
1161 | if (empty($sql_data['source_tables']))
|
---|
1162 | {
|
---|
1163 | $skip_rows = 0;
|
---|
1164 | $current_table++;
|
---|
1165 | continue;
|
---|
1166 | }
|
---|
1167 |
|
---|
1168 | $distinct = (!empty($schema['distinct'])) ? 'DISTINCT ' : '';
|
---|
1169 |
|
---|
1170 | $sql = 'SELECT ' . $distinct . implode(', ', $sql_data['select_fields']) . " \nFROM " . implode(', ', $sql_data['source_tables']);
|
---|
1171 |
|
---|
1172 | // Where
|
---|
1173 | $sql .= (!empty($schema['where'])) ? "\nWHERE (" . $schema['where'] . ')' : '';
|
---|
1174 |
|
---|
1175 | // Group By
|
---|
1176 | if (!empty($schema['group_by']))
|
---|
1177 | {
|
---|
1178 | $schema['group_by'] = array($schema['group_by']);
|
---|
1179 | foreach ($sql_data['select_fields'] as $select)
|
---|
1180 | {
|
---|
1181 | $alias = strpos(strtolower($select), ' as ');
|
---|
1182 | $select = ($alias) ? substr($select, 0, $alias) : $select;
|
---|
1183 | if (!in_array($select, $schema['group_by']))
|
---|
1184 | {
|
---|
1185 | $schema['group_by'][] = $select;
|
---|
1186 | }
|
---|
1187 | }
|
---|
1188 | }
|
---|
1189 | $sql .= (!empty($schema['group_by'])) ? "\nGROUP BY " . implode(', ', $schema['group_by']) : '';
|
---|
1190 |
|
---|
1191 | // Having
|
---|
1192 | $sql .= (!empty($schema['having'])) ? "\nHAVING " . $schema['having'] : '';
|
---|
1193 |
|
---|
1194 | // Order By
|
---|
1195 | if (empty($schema['order_by']) && !empty($schema['primary']))
|
---|
1196 | {
|
---|
1197 | $schema['order_by'] = $schema['primary'];
|
---|
1198 | }
|
---|
1199 | $sql .= (!empty($schema['order_by'])) ? "\nORDER BY " . $schema['order_by'] : '';
|
---|
1200 |
|
---|
1201 | // Counting basically holds the amount of rows processed.
|
---|
1202 | $counting = -1;
|
---|
1203 | $batch_time = 0;
|
---|
1204 |
|
---|
1205 | while ($counting === -1 || ($counting >= $convert->batch_size && still_on_time()))
|
---|
1206 | {
|
---|
1207 | $old_current_table = $current_table;
|
---|
1208 |
|
---|
1209 | $rows = '';
|
---|
1210 | $waiting_rows = array();
|
---|
1211 |
|
---|
1212 | if (!empty($batch_time))
|
---|
1213 | {
|
---|
1214 | $mtime = explode(' ', microtime());
|
---|
1215 | $mtime = $mtime[0] + $mtime[1];
|
---|
1216 | $rows = ceil($counting/($mtime - $batch_time)) . " rows/s ($counting rows) | ";
|
---|
1217 | }
|
---|
1218 |
|
---|
1219 | $template->assign_block_vars('checks', array(
|
---|
1220 | 'TITLE' => "skip_rows = $skip_rows",
|
---|
1221 | 'RESULT' => $rows . ((defined('DEBUG_EXTRA') && function_exists('memory_get_usage')) ? ceil(memory_get_usage()/1024) . ' ' . $user->lang['KIB'] : ''),
|
---|
1222 | ));
|
---|
1223 |
|
---|
1224 | $mtime = explode(' ', microtime());
|
---|
1225 | $batch_time = $mtime[0] + $mtime[1];
|
---|
1226 |
|
---|
1227 | if ($convert->mysql_convert && $same_db)
|
---|
1228 | {
|
---|
1229 | $src_db->sql_query("SET NAMES 'binary'");
|
---|
1230 | }
|
---|
1231 |
|
---|
1232 | // Take skip rows into account and only fetch batch_size amount of rows
|
---|
1233 | $___result = $src_db->sql_query_limit($sql, $convert->batch_size, $skip_rows);
|
---|
1234 |
|
---|
1235 | if ($convert->mysql_convert && $same_db)
|
---|
1236 | {
|
---|
1237 | $src_db->sql_query("SET NAMES 'utf8'");
|
---|
1238 | }
|
---|
1239 |
|
---|
1240 | // This loop processes each row
|
---|
1241 | $counting = 0;
|
---|
1242 |
|
---|
1243 | $convert->row = $convert_row = array();
|
---|
1244 |
|
---|
1245 | if (!empty($schema['autoincrement']))
|
---|
1246 | {
|
---|
1247 | switch ($db->sql_layer)
|
---|
1248 | {
|
---|
1249 | case 'mssql':
|
---|
1250 | case 'mssql_odbc':
|
---|
1251 | $db->sql_query('SET IDENTITY_INSERT ' . $schema['target'] . ' ON');
|
---|
1252 | break;
|
---|
1253 | }
|
---|
1254 | }
|
---|
1255 |
|
---|
1256 | // Now handle the rows until time is over or no more rows to process...
|
---|
1257 | while ($counting === 0 || still_on_time())
|
---|
1258 | {
|
---|
1259 | $convert_row = $src_db->sql_fetchrow($___result);
|
---|
1260 |
|
---|
1261 | if (!$convert_row)
|
---|
1262 | {
|
---|
1263 | // move to the next batch or table
|
---|
1264 | break;
|
---|
1265 | }
|
---|
1266 |
|
---|
1267 | // With this we are able to always save the last state
|
---|
1268 | $convert->row = $convert_row;
|
---|
1269 |
|
---|
1270 | // Increment the counting variable, it stores the number of rows we have processed
|
---|
1271 | $counting++;
|
---|
1272 |
|
---|
1273 | $insert_values = array();
|
---|
1274 |
|
---|
1275 | $sql_flag = $this->process_row($schema, $sql_data, $insert_values);
|
---|
1276 |
|
---|
1277 | if ($sql_flag === true)
|
---|
1278 | {
|
---|
1279 | switch ($db->sql_layer)
|
---|
1280 | {
|
---|
1281 | // If MySQL, we'll wait to have num_wait_rows rows to submit at once
|
---|
1282 | case 'mysql':
|
---|
1283 | case 'mysql4':
|
---|
1284 | case 'mysqli':
|
---|
1285 | $waiting_rows[] = '(' . implode(', ', $insert_values) . ')';
|
---|
1286 |
|
---|
1287 | if (sizeof($waiting_rows) >= $convert->num_wait_rows)
|
---|
1288 | {
|
---|
1289 | $errored = false;
|
---|
1290 |
|
---|
1291 | $db->sql_return_on_error(true);
|
---|
1292 |
|
---|
1293 | if (!$db->sql_query($insert_query . implode(', ', $waiting_rows)))
|
---|
1294 | {
|
---|
1295 | $errored = true;
|
---|
1296 | }
|
---|
1297 | $db->sql_return_on_error(false);
|
---|
1298 |
|
---|
1299 | if ($errored)
|
---|
1300 | {
|
---|
1301 | $db->sql_return_on_error(true);
|
---|
1302 |
|
---|
1303 | // Because it errored out we will try to insert the rows one by one... most of the time this
|
---|
1304 | // is caused by duplicate entries - but we also do not want to miss one...
|
---|
1305 | foreach ($waiting_rows as $waiting_sql)
|
---|
1306 | {
|
---|
1307 | if (!$db->sql_query($insert_query . $waiting_sql))
|
---|
1308 | {
|
---|
1309 | $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);
|
---|
1310 | }
|
---|
1311 | }
|
---|
1312 |
|
---|
1313 | $db->sql_return_on_error(false);
|
---|
1314 | }
|
---|
1315 |
|
---|
1316 | $waiting_rows = array();
|
---|
1317 | }
|
---|
1318 |
|
---|
1319 | break;
|
---|
1320 |
|
---|
1321 | default:
|
---|
1322 | $insert_sql = $insert_query . '(' . implode(', ', $insert_values) . ')';
|
---|
1323 |
|
---|
1324 | $db->sql_return_on_error(true);
|
---|
1325 |
|
---|
1326 | if (!$db->sql_query($insert_sql))
|
---|
1327 | {
|
---|
1328 | $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);
|
---|
1329 | }
|
---|
1330 | $db->sql_return_on_error(false);
|
---|
1331 |
|
---|
1332 | $waiting_rows = array();
|
---|
1333 |
|
---|
1334 | break;
|
---|
1335 | }
|
---|
1336 | }
|
---|
1337 |
|
---|
1338 | $skip_rows++;
|
---|
1339 | }
|
---|
1340 | $src_db->sql_freeresult($___result);
|
---|
1341 |
|
---|
1342 | // We might still have some rows waiting
|
---|
1343 | if (sizeof($waiting_rows))
|
---|
1344 | {
|
---|
1345 | $errored = false;
|
---|
1346 | $db->sql_return_on_error(true);
|
---|
1347 |
|
---|
1348 | if (!$db->sql_query($insert_query . implode(', ', $waiting_rows)))
|
---|
1349 | {
|
---|
1350 | $errored = true;
|
---|
1351 | }
|
---|
1352 | $db->sql_return_on_error(false);
|
---|
1353 |
|
---|
1354 | if ($errored)
|
---|
1355 | {
|
---|
1356 | $db->sql_return_on_error(true);
|
---|
1357 |
|
---|
1358 | // Because it errored out we will try to insert the rows one by one... most of the time this
|
---|
1359 | // is caused by duplicate entries - but we also do not want to miss one...
|
---|
1360 | foreach ($waiting_rows as $waiting_sql)
|
---|
1361 | {
|
---|
1362 | $db->sql_query($insert_query . $waiting_sql);
|
---|
1363 | $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);
|
---|
1364 | }
|
---|
1365 |
|
---|
1366 | $db->sql_return_on_error(false);
|
---|
1367 | }
|
---|
1368 |
|
---|
1369 | $waiting_rows = array();
|
---|
1370 | }
|
---|
1371 |
|
---|
1372 | if (!empty($schema['autoincrement']))
|
---|
1373 | {
|
---|
1374 | switch ($db->sql_layer)
|
---|
1375 | {
|
---|
1376 | case 'mssql':
|
---|
1377 | case 'mssql_odbc':
|
---|
1378 | $db->sql_query('SET IDENTITY_INSERT ' . $schema['target'] . ' OFF');
|
---|
1379 | break;
|
---|
1380 |
|
---|
1381 | case 'postgres':
|
---|
1382 | $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'] . '));');
|
---|
1383 | break;
|
---|
1384 |
|
---|
1385 | case 'oracle':
|
---|
1386 | $result = $db->sql_query('SELECT MAX(' . $schema['autoincrement'] . ') as max_id FROM ' . $schema['target']);
|
---|
1387 | $row = $db->sql_fetchrow($result);
|
---|
1388 | $db->sql_freeresult($result);
|
---|
1389 |
|
---|
1390 | $largest_id = (int) $row['max_id'];
|
---|
1391 |
|
---|
1392 | if ($largest_id)
|
---|
1393 | {
|
---|
1394 | $db->sql_query('DROP SEQUENCE ' . $schema['target'] . '_seq');
|
---|
1395 | $db->sql_query('CREATE SEQUENCE ' . $schema['target'] . '_seq START WITH ' . ($largest_id + 1));
|
---|
1396 | }
|
---|
1397 | break;
|
---|
1398 | }
|
---|
1399 | }
|
---|
1400 | }
|
---|
1401 |
|
---|
1402 | // When we reach this point, either the current table has been processed or we're running out of time.
|
---|
1403 | if (still_on_time() && $counting < $convert->batch_size/* && !defined('DEBUG_EXTRA')*/)
|
---|
1404 | {
|
---|
1405 | $skip_rows = 0;
|
---|
1406 | $current_table++;
|
---|
1407 | }
|
---|
1408 | else
|
---|
1409 | {/*
|
---|
1410 | if (still_on_time() && $counting < $convert->batch_size)
|
---|
1411 | {
|
---|
1412 | $skip_rows = 0;
|
---|
1413 | $current_table++;
|
---|
1414 | }*/
|
---|
1415 |
|
---|
1416 | // Looks like we ran out of time.
|
---|
1417 | $url = $this->save_convert_progress('&current_table=' . $current_table . '&skip_rows=' . $skip_rows);
|
---|
1418 |
|
---|
1419 | $current_table++;
|
---|
1420 | // $percentage = ($skip_rows == 0) ? 0 : floor(100 / ($total_rows / $skip_rows));
|
---|
1421 |
|
---|
1422 | $msg = sprintf($user->lang['STEP_PERCENT_COMPLETED'], $current_table, sizeof($convert->convertor['schema']));
|
---|
1423 |
|
---|
1424 | $template->assign_vars(array(
|
---|
1425 | 'L_MESSAGE' => $msg,
|
---|
1426 | 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'],
|
---|
1427 | 'U_ACTION' => $url,
|
---|
1428 | ));
|
---|
1429 |
|
---|
1430 | $this->meta_refresh($url);
|
---|
1431 | return;
|
---|
1432 | }
|
---|
1433 | }
|
---|
1434 |
|
---|
1435 | // Process execute_last then we'll be done
|
---|
1436 | $url = $this->save_convert_progress('&jump=1');
|
---|
1437 |
|
---|
1438 | $template->assign_vars(array(
|
---|
1439 | 'L_SUBMIT' => $user->lang['FINAL_STEP'],
|
---|
1440 | 'U_ACTION' => $url,
|
---|
1441 | ));
|
---|
1442 |
|
---|
1443 | $this->meta_refresh($url);
|
---|
1444 | return;
|
---|
1445 | }
|
---|
1446 |
|
---|
1447 | /**
|
---|
1448 | * Sync function being executed at the middle, some functions need to be executed after a successful sync.
|
---|
1449 | */
|
---|
1450 | function sync_forums($sync_batch)
|
---|
1451 | {
|
---|
1452 | global $template, $user, $db, $phpbb_root_path, $phpEx, $config, $cache;
|
---|
1453 | global $convert;
|
---|
1454 |
|
---|
1455 | $template->assign_block_vars('checks', array(
|
---|
1456 | 'S_LEGEND' => true,
|
---|
1457 | 'LEGEND' => $user->lang['SYNC_TOPICS'],
|
---|
1458 | ));
|
---|
1459 |
|
---|
1460 | $batch_size = $convert->batch_size;
|
---|
1461 |
|
---|
1462 | $sql = 'SELECT MIN(topic_id) as min_value, MAX(topic_id) AS max_value
|
---|
1463 | FROM ' . TOPICS_TABLE;
|
---|
1464 | $result = $db->sql_query($sql);
|
---|
1465 | $row = $db->sql_fetchrow($result);
|
---|
1466 | $db->sql_freeresult($result);
|
---|
1467 |
|
---|
1468 | // Set values of minimum/maximum primary value for this table.
|
---|
1469 | $primary_min = $row['min_value'];
|
---|
1470 | $primary_max = $row['max_value'];
|
---|
1471 |
|
---|
1472 | if ($sync_batch == 0)
|
---|
1473 | {
|
---|
1474 | $sync_batch = (int) $primary_min;
|
---|
1475 | }
|
---|
1476 |
|
---|
1477 | if ($sync_batch == 0)
|
---|
1478 | {
|
---|
1479 | $sync_batch = 1;
|
---|
1480 | }
|
---|
1481 |
|
---|
1482 | // Fetch a batch of rows, process and insert them.
|
---|
1483 | while ($sync_batch <= $primary_max && still_on_time())
|
---|
1484 | {
|
---|
1485 | $end = ($sync_batch + $batch_size - 1);
|
---|
1486 |
|
---|
1487 | // Sync all topics in batch mode...
|
---|
1488 | sync('topic_approved', 'range', 'topic_id BETWEEN ' . $sync_batch . ' AND ' . $end, true, false);
|
---|
1489 | sync('topic', 'range', 'topic_id BETWEEN ' . $sync_batch . ' AND ' . $end, true, true);
|
---|
1490 |
|
---|
1491 | $template->assign_block_vars('checks', array(
|
---|
1492 | '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'] . ']' : ''),
|
---|
1493 | 'RESULT' => $user->lang['DONE'],
|
---|
1494 | ));
|
---|
1495 |
|
---|
1496 | $sync_batch += $batch_size;
|
---|
1497 | }
|
---|
1498 |
|
---|
1499 | if ($sync_batch >= $primary_max)
|
---|
1500 | {
|
---|
1501 | $url = $this->save_convert_progress('&final_jump=1');
|
---|
1502 |
|
---|
1503 | $template->assign_vars(array(
|
---|
1504 | 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'],
|
---|
1505 | 'U_ACTION' => $url,
|
---|
1506 | ));
|
---|
1507 |
|
---|
1508 | $this->meta_refresh($url);
|
---|
1509 | return;
|
---|
1510 | }
|
---|
1511 | else
|
---|
1512 | {
|
---|
1513 | $sync_batch--;
|
---|
1514 | }
|
---|
1515 |
|
---|
1516 | $url = $this->save_convert_progress('&sync_batch=' . $sync_batch);
|
---|
1517 |
|
---|
1518 | $template->assign_vars(array(
|
---|
1519 | 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'],
|
---|
1520 | 'U_ACTION' => $url,
|
---|
1521 | ));
|
---|
1522 |
|
---|
1523 | $this->meta_refresh($url);
|
---|
1524 | return;
|
---|
1525 | }
|
---|
1526 |
|
---|
1527 | /**
|
---|
1528 | * Save the convertor status
|
---|
1529 | */
|
---|
1530 | function save_convert_progress($step)
|
---|
1531 | {
|
---|
1532 | global $convert, $language;
|
---|
1533 |
|
---|
1534 | // Save convertor Status
|
---|
1535 | set_config('convert_progress', serialize(array(
|
---|
1536 | 'step' => $step,
|
---|
1537 | 'table_prefix' => $convert->src_table_prefix,
|
---|
1538 | 'tag' => $convert->convertor_tag,
|
---|
1539 | )), true);
|
---|
1540 |
|
---|
1541 | set_config('convert_db_server', serialize(array(
|
---|
1542 | 'dbms' => $convert->src_dbms,
|
---|
1543 | 'dbhost' => $convert->src_dbhost,
|
---|
1544 | 'dbport' => $convert->src_dbport,
|
---|
1545 | 'dbname' => $convert->src_dbname,
|
---|
1546 | )), true);
|
---|
1547 |
|
---|
1548 | set_config('convert_db_user', serialize(array(
|
---|
1549 | 'dbuser' => $convert->src_dbuser,
|
---|
1550 | 'dbpasswd' => $convert->src_dbpasswd,
|
---|
1551 | )), true);
|
---|
1552 |
|
---|
1553 | return $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag={$convert->convertor_tag}$step&language=$language";
|
---|
1554 | }
|
---|
1555 |
|
---|
1556 | /**
|
---|
1557 | * Finish conversion, the last function to be called.
|
---|
1558 | */
|
---|
1559 | function finish_conversion()
|
---|
1560 | {
|
---|
1561 | global $db, $phpbb_root_path, $convert, $config, $language, $user, $template;
|
---|
1562 |
|
---|
1563 | $db->sql_query('DELETE FROM ' . CONFIG_TABLE . "
|
---|
1564 | WHERE config_name = 'convert_progress'
|
---|
1565 | OR config_name = 'convert_options'
|
---|
1566 | OR config_name = 'convert_db_server'
|
---|
1567 | OR config_name = 'convert_db_user'");
|
---|
1568 | $db->sql_query('DELETE FROM ' . SESSIONS_TABLE);
|
---|
1569 |
|
---|
1570 | @unlink($phpbb_root_path . 'cache/data_global.php');
|
---|
1571 | cache_moderators();
|
---|
1572 |
|
---|
1573 | // And finally, add a note to the log
|
---|
1574 | add_log('admin', 'LOG_INSTALL_CONVERTED', $convert->convertor_data['forum_name'], $config['version']);
|
---|
1575 |
|
---|
1576 | $url = $this->p_master->module_url . "?mode={$this->mode}&sub=final&language=$language";
|
---|
1577 |
|
---|
1578 | $template->assign_vars(array(
|
---|
1579 | 'L_SUBMIT' => $user->lang['FINAL_STEP'],
|
---|
1580 | 'U_ACTION' => $url,
|
---|
1581 | ));
|
---|
1582 |
|
---|
1583 | $this->meta_refresh($url);
|
---|
1584 | return;
|
---|
1585 | }
|
---|
1586 |
|
---|
1587 | /**
|
---|
1588 | * This function marks the steps after syncing
|
---|
1589 | */
|
---|
1590 | function final_jump($final_jump)
|
---|
1591 | {
|
---|
1592 | global $template, $user, $src_db, $same_db, $db, $phpbb_root_path, $phpEx, $config, $cache;
|
---|
1593 | global $convert;
|
---|
1594 |
|
---|
1595 | $template->assign_block_vars('checks', array(
|
---|
1596 | 'S_LEGEND' => true,
|
---|
1597 | 'LEGEND' => $user->lang['PROCESS_LAST'],
|
---|
1598 | ));
|
---|
1599 |
|
---|
1600 | if ($final_jump == 1)
|
---|
1601 | {
|
---|
1602 | $db->sql_return_on_error(true);
|
---|
1603 |
|
---|
1604 | update_topics_posted();
|
---|
1605 |
|
---|
1606 | $template->assign_block_vars('checks', array(
|
---|
1607 | 'TITLE' => $user->lang['UPDATE_TOPICS_POSTED'],
|
---|
1608 | 'RESULT' => $user->lang['DONE'],
|
---|
1609 | ));
|
---|
1610 |
|
---|
1611 | if ($db->sql_error_triggered)
|
---|
1612 | {
|
---|
1613 | $template->assign_vars(array(
|
---|
1614 | 'S_ERROR_BOX' => true,
|
---|
1615 | 'ERROR_TITLE' => $user->lang['UPDATE_TOPICS_POSTED'],
|
---|
1616 | 'ERROR_MSG' => $user->lang['UPDATE_TOPICS_POSTED_ERR'],
|
---|
1617 | ));
|
---|
1618 | }
|
---|
1619 | $db->sql_return_on_error(false);
|
---|
1620 |
|
---|
1621 | $this->finish_conversion();
|
---|
1622 | return;
|
---|
1623 | }
|
---|
1624 | }
|
---|
1625 |
|
---|
1626 | /**
|
---|
1627 | * This function marks the steps before syncing (jump=1)
|
---|
1628 | */
|
---|
1629 | function jump($jump, $last_statement)
|
---|
1630 | {
|
---|
1631 | global $template, $user, $src_db, $same_db, $db, $phpbb_root_path, $phpEx, $config, $cache;
|
---|
1632 | global $convert;
|
---|
1633 |
|
---|
1634 | $template->assign_block_vars('checks', array(
|
---|
1635 | 'S_LEGEND' => true,
|
---|
1636 | 'LEGEND' => $user->lang['PROCESS_LAST'],
|
---|
1637 | ));
|
---|
1638 |
|
---|
1639 | if ($jump == 1)
|
---|
1640 | {
|
---|
1641 | // Execute 'last' statements/queries
|
---|
1642 | if (!empty($convert->convertor['execute_last']))
|
---|
1643 | {
|
---|
1644 | if (!is_array($convert->convertor['execute_last']))
|
---|
1645 | {
|
---|
1646 | eval($convert->convertor['execute_last']);
|
---|
1647 | }
|
---|
1648 | else
|
---|
1649 | {
|
---|
1650 | while ($last_statement < sizeof($convert->convertor['execute_last']))
|
---|
1651 | {
|
---|
1652 | eval($convert->convertor['execute_last'][$last_statement]);
|
---|
1653 |
|
---|
1654 | $template->assign_block_vars('checks', array(
|
---|
1655 | 'TITLE' => $convert->convertor['execute_last'][$last_statement],
|
---|
1656 | 'RESULT' => $user->lang['DONE'],
|
---|
1657 | ));
|
---|
1658 |
|
---|
1659 | $last_statement++;
|
---|
1660 | $url = $this->save_convert_progress('&jump=1&last=' . $last_statement);
|
---|
1661 |
|
---|
1662 | $percentage = ($last_statement == 0) ? 0 : floor(100 / (sizeof($convert->convertor['execute_last']) / $last_statement));
|
---|
1663 | $msg = sprintf($user->lang['STEP_PERCENT_COMPLETED'], $last_statement, sizeof($convert->convertor['execute_last']), $percentage);
|
---|
1664 |
|
---|
1665 | $template->assign_vars(array(
|
---|
1666 | 'L_SUBMIT' => $user->lang['CONTINUE_LAST'],
|
---|
1667 | 'L_MESSAGE' => $msg,
|
---|
1668 | 'U_ACTION' => $url,
|
---|
1669 | ));
|
---|
1670 |
|
---|
1671 | $this->meta_refresh($url);
|
---|
1672 | return;
|
---|
1673 | }
|
---|
1674 | }
|
---|
1675 | }
|
---|
1676 |
|
---|
1677 | if (!empty($convert->convertor['query_last']))
|
---|
1678 | {
|
---|
1679 | if (!is_array($convert->convertor['query_last']))
|
---|
1680 | {
|
---|
1681 | $convert->convertor['query_last'] = array('target', array($convert->convertor['query_last']));
|
---|
1682 | }
|
---|
1683 | else if (!is_array($convert->convertor['query_last'][0]))
|
---|
1684 | {
|
---|
1685 | $convert->convertor['query_last'] = array(array($convert->convertor['query_last'][0], $convert->convertor['query_last'][1]));
|
---|
1686 | }
|
---|
1687 |
|
---|
1688 | foreach ($convert->convertor['query_last'] as $query_last)
|
---|
1689 | {
|
---|
1690 | if ($query_last[0] == 'src')
|
---|
1691 | {
|
---|
1692 | if ($convert->mysql_convert && $same_db)
|
---|
1693 | {
|
---|
1694 | $src_db->sql_query("SET NAMES 'binary'");
|
---|
1695 | }
|
---|
1696 |
|
---|
1697 | $src_db->sql_query($query_last[1]);
|
---|
1698 |
|
---|
1699 | if ($convert->mysql_convert && $same_db)
|
---|
1700 | {
|
---|
1701 | $src_db->sql_query("SET NAMES 'utf8'");
|
---|
1702 | }
|
---|
1703 | }
|
---|
1704 | else
|
---|
1705 | {
|
---|
1706 | $db->sql_query($query_last[1]);
|
---|
1707 | }
|
---|
1708 | }
|
---|
1709 | }
|
---|
1710 |
|
---|
1711 | // Sanity check
|
---|
1712 | $db->sql_return_on_error(false);
|
---|
1713 | $src_db->sql_return_on_error(false);
|
---|
1714 |
|
---|
1715 | fix_empty_primary_groups();
|
---|
1716 |
|
---|
1717 | if (!isset($config['board_startdate']))
|
---|
1718 | {
|
---|
1719 | $sql = 'SELECT MIN(user_regdate) AS board_startdate
|
---|
1720 | FROM ' . USERS_TABLE;
|
---|
1721 | $result = $db->sql_query($sql);
|
---|
1722 | $row = $db->sql_fetchrow($result);
|
---|
1723 | $db->sql_freeresult($result);
|
---|
1724 |
|
---|
1725 | if (($row['board_startdate'] < $config['board_startdate'] && $row['board_startdate'] > 0) || !isset($config['board_startdate']))
|
---|
1726 | {
|
---|
1727 | set_config('board_startdate', $row['board_startdate']);
|
---|
1728 | $db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_regdate = ' . $row['board_startdate'] . ' WHERE user_id = ' . ANONYMOUS);
|
---|
1729 | }
|
---|
1730 | }
|
---|
1731 |
|
---|
1732 | update_dynamic_config();
|
---|
1733 |
|
---|
1734 | $template->assign_block_vars('checks', array(
|
---|
1735 | 'TITLE' => $user->lang['CLEAN_VERIFY'],
|
---|
1736 | 'RESULT' => $user->lang['DONE'],
|
---|
1737 | ));
|
---|
1738 |
|
---|
1739 | $url = $this->save_convert_progress('&jump=2');
|
---|
1740 |
|
---|
1741 | $template->assign_vars(array(
|
---|
1742 | 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'],
|
---|
1743 | 'U_ACTION' => $url,
|
---|
1744 | ));
|
---|
1745 |
|
---|
1746 | $this->meta_refresh($url);
|
---|
1747 | return;
|
---|
1748 | }
|
---|
1749 |
|
---|
1750 | if ($jump == 2)
|
---|
1751 | {
|
---|
1752 | $db->sql_query('UPDATE ' . USERS_TABLE . " SET user_permissions = ''");
|
---|
1753 |
|
---|
1754 | // TODO: sync() is likely going to bomb out on forums with a considerable amount of topics.
|
---|
1755 | // TODO: the sync function is able to handle FROM-TO values, we should use them here (batch processing)
|
---|
1756 | sync('forum', '', '', false, true);
|
---|
1757 | $cache->destroy('sql', FORUMS_TABLE);
|
---|
1758 |
|
---|
1759 | $template->assign_block_vars('checks', array(
|
---|
1760 | 'TITLE' => $user->lang['SYNC_FORUMS'],
|
---|
1761 | 'RESULT' => $user->lang['DONE'],
|
---|
1762 | ));
|
---|
1763 |
|
---|
1764 | // Continue with synchronizing the forums...
|
---|
1765 | $url = $this->save_convert_progress('&sync_batch=0');
|
---|
1766 |
|
---|
1767 | $template->assign_vars(array(
|
---|
1768 | 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'],
|
---|
1769 | 'U_ACTION' => $url,
|
---|
1770 | ));
|
---|
1771 |
|
---|
1772 | $this->meta_refresh($url);
|
---|
1773 | return;
|
---|
1774 | }
|
---|
1775 | }
|
---|
1776 |
|
---|
1777 | function build_insert_query(&$schema, &$sql_data, $current_table)
|
---|
1778 | {
|
---|
1779 | global $db, $user;
|
---|
1780 | global $convert;
|
---|
1781 |
|
---|
1782 | // Can we use IGNORE with this DBMS?
|
---|
1783 | $sql_ignore = (strpos($db->sql_layer, 'mysql') === 0 && !defined('DEBUG_EXTRA')) ? 'IGNORE ' : '';
|
---|
1784 | $insert_query = 'INSERT ' . $sql_ignore . 'INTO ' . $schema['target'] . ' (';
|
---|
1785 |
|
---|
1786 | $aliases = array();
|
---|
1787 |
|
---|
1788 | $sql_data = array(
|
---|
1789 | 'source_fields' => array(),
|
---|
1790 | 'target_fields' => array(),
|
---|
1791 | 'source_tables' => array(),
|
---|
1792 | 'select_fields' => array(),
|
---|
1793 | );
|
---|
1794 |
|
---|
1795 | foreach ($schema as $key => $val)
|
---|
1796 | {
|
---|
1797 | // Example: array('group_name', 'extension_groups.group_name', 'htmlspecialchars'),
|
---|
1798 | if (is_int($key))
|
---|
1799 | {
|
---|
1800 | if (!empty($val[0]))
|
---|
1801 | {
|
---|
1802 | // Target fields
|
---|
1803 | $sql_data['target_fields'][$val[0]] = $key;
|
---|
1804 | $insert_query .= $val[0] . ', ';
|
---|
1805 | }
|
---|
1806 |
|
---|
1807 | if (!is_array($val[1]))
|
---|
1808 | {
|
---|
1809 | $val[1] = array($val[1]);
|
---|
1810 | }
|
---|
1811 |
|
---|
1812 | foreach ($val[1] as $valkey => $value_1)
|
---|
1813 | {
|
---|
1814 | // This should cover about any case:
|
---|
1815 | //
|
---|
1816 | // table.field => SELECT table.field FROM table
|
---|
1817 | // table.field AS alias => SELECT table.field AS alias FROM table
|
---|
1818 | // table.field AS table2.alias => SELECT table2.field AS alias FROM table table2
|
---|
1819 | // table.field AS table2.field => SELECT table2.field FROM table table2
|
---|
1820 | //
|
---|
1821 | if (preg_match('/^([a-z0-9_]+)\.([a-z0-9_]+)( +AS +(([a-z0-9_]+?)\.)?([a-z0-9_]+))?$/i', $value_1, $m))
|
---|
1822 | {
|
---|
1823 | // There is 'AS ...' in the field names
|
---|
1824 | if (!empty($m[3]))
|
---|
1825 | {
|
---|
1826 | $value_1 = ($m[2] == $m[6]) ? $m[1] . '.' . $m[2] : $m[1] . '.' . $m[2] . ' AS ' . $m[6];
|
---|
1827 |
|
---|
1828 | // Table alias: store it then replace the source table with it
|
---|
1829 | if (!empty($m[5]) && $m[5] != $m[1])
|
---|
1830 | {
|
---|
1831 | $aliases[$m[5]] = $m[1];
|
---|
1832 | $value_1 = str_replace($m[1] . '.' . $m[2], $m[5] . '.' . $m[2], $value_1);
|
---|
1833 | }
|
---|
1834 | }
|
---|
1835 | else
|
---|
1836 | {
|
---|
1837 | // No table alias
|
---|
1838 | $sql_data['source_tables'][$m[1]] = (empty($convert->src_table_prefix)) ? $m[1] : $convert->src_table_prefix . $m[1] . ' ' . $m[1];
|
---|
1839 | }
|
---|
1840 |
|
---|
1841 | $sql_data['select_fields'][$value_1] = $value_1;
|
---|
1842 | $sql_data['source_fields'][$key][$valkey] = (!empty($m[6])) ? $m[6] : $m[2];
|
---|
1843 | }
|
---|
1844 | }
|
---|
1845 | }
|
---|
1846 | else if ($key == 'where' || $key == 'group_by' || $key == 'order_by' || $key == 'having')
|
---|
1847 | {
|
---|
1848 | if (@preg_match_all('/([a-z0-9_]+)\.([a-z0-9_]+)/i', $val, $m))
|
---|
1849 | {
|
---|
1850 | foreach ($m[1] as $value)
|
---|
1851 | {
|
---|
1852 | $sql_data['source_tables'][$value] = (empty($convert->src_table_prefix)) ? $value : $convert->src_table_prefix . $value . ' ' . $value;
|
---|
1853 | }
|
---|
1854 | }
|
---|
1855 | }
|
---|
1856 | }
|
---|
1857 |
|
---|
1858 | // Add the aliases to the list of tables
|
---|
1859 | foreach ($aliases as $alias => $table)
|
---|
1860 | {
|
---|
1861 | $sql_data['source_tables'][$alias] = $convert->src_table_prefix . $table . ' ' . $alias;
|
---|
1862 | }
|
---|
1863 |
|
---|
1864 | // 'left_join' => 'forums LEFT JOIN forum_prune ON forums.forum_id = forum_prune.forum_id',
|
---|
1865 | if (!empty($schema['left_join']))
|
---|
1866 | {
|
---|
1867 | if (!is_array($schema['left_join']))
|
---|
1868 | {
|
---|
1869 | $schema['left_join'] = array($schema['left_join']);
|
---|
1870 | }
|
---|
1871 |
|
---|
1872 | foreach ($schema['left_join'] as $left_join)
|
---|
1873 | {
|
---|
1874 | // This won't handle concatened LEFT JOINs
|
---|
1875 | if (!preg_match('/([a-z0-9_]+) LEFT JOIN ([a-z0-9_]+) A?S? ?([a-z0-9_]*?) ?(ON|USING)(.*)/i', $left_join, $m))
|
---|
1876 | {
|
---|
1877 | $this->p_master->error(sprintf($user->lang['NOT_UNDERSTAND'], 'LEFT JOIN', $left_join, $current_table, $schema['target']), __LINE__, __FILE__);
|
---|
1878 | }
|
---|
1879 |
|
---|
1880 | if (!empty($aliases[$m[2]]))
|
---|
1881 | {
|
---|
1882 | if (!empty($m[3]))
|
---|
1883 | {
|
---|
1884 | $this->p_master->error(sprintf($user->lang['NAMING_CONFLICT'], $m[2], $m[3], $schema['left_join']), __LINE__, __FILE__);
|
---|
1885 | }
|
---|
1886 |
|
---|
1887 | $m[2] = $aliases[$m[2]];
|
---|
1888 | $m[3] = $m[2];
|
---|
1889 | }
|
---|
1890 |
|
---|
1891 | $right_table = $convert->src_table_prefix . $m[2];
|
---|
1892 | if (!empty($m[3]))
|
---|
1893 | {
|
---|
1894 | unset($sql_data['source_tables'][$m[3]]);
|
---|
1895 | }
|
---|
1896 | else if ($m[2] != $m[1])
|
---|
1897 | {
|
---|
1898 | unset($sql_data['source_tables'][$m[2]]);
|
---|
1899 | }
|
---|
1900 |
|
---|
1901 | if (strpos($sql_data['source_tables'][$m[1]], "\nLEFT JOIN") !== false)
|
---|
1902 | {
|
---|
1903 | $sql_data['source_tables'][$m[1]] = '(' . $sql_data['source_tables'][$m[1]] . ")\nLEFT JOIN $right_table";
|
---|
1904 | }
|
---|
1905 | else
|
---|
1906 | {
|
---|
1907 | $sql_data['source_tables'][$m[1]] .= "\nLEFT JOIN $right_table";
|
---|
1908 | }
|
---|
1909 |
|
---|
1910 | if (!empty($m[3]))
|
---|
1911 | {
|
---|
1912 | unset($sql_data['source_tables'][$m[3]]);
|
---|
1913 | $sql_data['source_tables'][$m[1]] .= ' AS ' . $m[3];
|
---|
1914 | }
|
---|
1915 | else if (!empty($convert->src_table_prefix))
|
---|
1916 | {
|
---|
1917 | $sql_data['source_tables'][$m[1]] .= ' AS ' . $m[2];
|
---|
1918 | }
|
---|
1919 | $sql_data['source_tables'][$m[1]] .= ' ' . $m[4] . $m[5];
|
---|
1920 | }
|
---|
1921 | }
|
---|
1922 |
|
---|
1923 | // Remove ", " from the end of the insert query
|
---|
1924 | $insert_query = substr($insert_query, 0, -2) . ') VALUES ';
|
---|
1925 |
|
---|
1926 | return $insert_query;
|
---|
1927 | }
|
---|
1928 |
|
---|
1929 | /**
|
---|
1930 | * Function for processing the currently handled row
|
---|
1931 | */
|
---|
1932 | function process_row(&$schema, &$sql_data, &$insert_values)
|
---|
1933 | {
|
---|
1934 | global $template, $user, $phpbb_root_path, $phpEx, $db, $lang, $config, $cache;
|
---|
1935 | global $convert, $convert_row;
|
---|
1936 |
|
---|
1937 | $sql_flag = false;
|
---|
1938 |
|
---|
1939 | foreach ($schema as $key => $fields)
|
---|
1940 | {
|
---|
1941 | // We are only interested in the lines with:
|
---|
1942 | // array('comment', 'attachments_desc.comment', 'htmlspecialchars'),
|
---|
1943 | if (is_int($key))
|
---|
1944 | {
|
---|
1945 | if (!is_array($fields[1]))
|
---|
1946 | {
|
---|
1947 | $fields[1] = array($fields[1]);
|
---|
1948 | }
|
---|
1949 |
|
---|
1950 | $firstkey_set = false;
|
---|
1951 | $firstkey = 0;
|
---|
1952 |
|
---|
1953 | foreach ($fields[1] as $inner_key => $inner_value)
|
---|
1954 | {
|
---|
1955 | if (!$firstkey_set)
|
---|
1956 | {
|
---|
1957 | $firstkey = $inner_key;
|
---|
1958 | $firstkey_set = true;
|
---|
1959 | }
|
---|
1960 |
|
---|
1961 | $src_field = isset($sql_data['source_fields'][$key][$inner_key]) ? $sql_data['source_fields'][$key][$inner_key] : '';
|
---|
1962 |
|
---|
1963 | if (!empty($src_field))
|
---|
1964 | {
|
---|
1965 | $fields[1][$inner_key] = $convert->row[$src_field];
|
---|
1966 | }
|
---|
1967 | }
|
---|
1968 |
|
---|
1969 | if (!empty($fields[0]))
|
---|
1970 | {
|
---|
1971 | // We have a target field, if we haven't set $sql_flag yet it will be set to TRUE.
|
---|
1972 | // If a function has already set it to FALSE it won't change it.
|
---|
1973 | if ($sql_flag === false)
|
---|
1974 | {
|
---|
1975 | $sql_flag = true;
|
---|
1976 | }
|
---|
1977 |
|
---|
1978 | // No function assigned?
|
---|
1979 | if (empty($fields[2]))
|
---|
1980 | {
|
---|
1981 | $value = $fields[1][$firstkey];
|
---|
1982 | }
|
---|
1983 | else if (is_array($fields[2]))
|
---|
1984 | {
|
---|
1985 | // Execute complex function/eval/typecast
|
---|
1986 | $value = $fields[1];
|
---|
1987 |
|
---|
1988 | foreach ($fields[2] as $type => $execution)
|
---|
1989 | {
|
---|
1990 | if (strpos($type, 'typecast') === 0)
|
---|
1991 | {
|
---|
1992 | if (!is_array($value))
|
---|
1993 | {
|
---|
1994 | $value = array($value);
|
---|
1995 | }
|
---|
1996 | $value = $value[0];
|
---|
1997 | settype($value, $execution);
|
---|
1998 | }
|
---|
1999 | else if (strpos($type, 'function') === 0)
|
---|
2000 | {
|
---|
2001 | if (!is_array($value))
|
---|
2002 | {
|
---|
2003 | $value = array($value);
|
---|
2004 | }
|
---|
2005 |
|
---|
2006 | $value = call_user_func_array($execution, $value);
|
---|
2007 | }
|
---|
2008 | else if (strpos($type, 'execute') === 0)
|
---|
2009 | {
|
---|
2010 | if (!is_array($value))
|
---|
2011 | {
|
---|
2012 | $value = array($value);
|
---|
2013 | }
|
---|
2014 |
|
---|
2015 | $execution = str_replace('{RESULT}', '$value', $execution);
|
---|
2016 | $execution = str_replace('{VALUE}', '$value', $execution);
|
---|
2017 | eval($execution);
|
---|
2018 | }
|
---|
2019 | }
|
---|
2020 | }
|
---|
2021 | else
|
---|
2022 | {
|
---|
2023 | $value = call_user_func_array($fields[2], $fields[1]);
|
---|
2024 | }
|
---|
2025 |
|
---|
2026 | if (is_null($value))
|
---|
2027 | {
|
---|
2028 | $value = '';
|
---|
2029 | }
|
---|
2030 |
|
---|
2031 | $insert_values[] = $db->_sql_validate_value($value);
|
---|
2032 | }
|
---|
2033 | else if (!empty($fields[2]))
|
---|
2034 | {
|
---|
2035 | if (is_array($fields[2]))
|
---|
2036 | {
|
---|
2037 | // Execute complex function/eval/typecast
|
---|
2038 | $value = '';
|
---|
2039 |
|
---|
2040 | foreach ($fields[2] as $type => $execution)
|
---|
2041 | {
|
---|
2042 | if (strpos($type, 'typecast') === 0)
|
---|
2043 | {
|
---|
2044 | $value = settype($value, $execution);
|
---|
2045 | }
|
---|
2046 | else if (strpos($type, 'function') === 0)
|
---|
2047 | {
|
---|
2048 | if (!is_array($value))
|
---|
2049 | {
|
---|
2050 | $value = array($value);
|
---|
2051 | }
|
---|
2052 |
|
---|
2053 | $value = call_user_func_array($execution, $value);
|
---|
2054 | }
|
---|
2055 | else if (strpos($type, 'execute') === 0)
|
---|
2056 | {
|
---|
2057 | if (!is_array($value))
|
---|
2058 | {
|
---|
2059 | $value = array($value);
|
---|
2060 | }
|
---|
2061 |
|
---|
2062 | $execution = str_replace('{RESULT}', '$value', $execution);
|
---|
2063 | $execution = str_replace('{VALUE}', '$value', $execution);
|
---|
2064 | eval($execution);
|
---|
2065 | }
|
---|
2066 | }
|
---|
2067 | }
|
---|
2068 | else
|
---|
2069 | {
|
---|
2070 | call_user_func_array($fields[2], $fields[1]);
|
---|
2071 | }
|
---|
2072 | }
|
---|
2073 | }
|
---|
2074 | }
|
---|
2075 |
|
---|
2076 | return $sql_flag;
|
---|
2077 | }
|
---|
2078 |
|
---|
2079 | /**
|
---|
2080 | * Own meta refresh function to be able to change the global time used
|
---|
2081 | */
|
---|
2082 | function meta_refresh($url)
|
---|
2083 | {
|
---|
2084 | global $convert, $template;
|
---|
2085 |
|
---|
2086 | if ($convert->options['refresh'])
|
---|
2087 | {
|
---|
2088 | // Because we should not rely on correct settings, we simply use the relative path here directly.
|
---|
2089 | $template->assign_vars(array(
|
---|
2090 | 'S_REFRESH' => true,
|
---|
2091 | 'META' => '<meta http-equiv="refresh" content="5;url=' . $url . '" />')
|
---|
2092 | );
|
---|
2093 | }
|
---|
2094 | }
|
---|
2095 |
|
---|
2096 | /**
|
---|
2097 | * The information below will be used to build the input fields presented to the user
|
---|
2098 | */
|
---|
2099 | var $convert_options = array(
|
---|
2100 | 'legend1' => 'SPECIFY_OPTIONS',
|
---|
2101 | 'src_dbms' => array('lang' => 'DBMS', 'type' => 'select', 'options' => 'dbms_select(\'{VALUE}\', true)', 'explain' => false),
|
---|
2102 | 'src_dbhost' => array('lang' => 'DB_HOST', 'type' => 'text:25:100', 'explain' => true),
|
---|
2103 | 'src_dbport' => array('lang' => 'DB_PORT', 'type' => 'text:25:100', 'explain' => true),
|
---|
2104 | 'src_dbname' => array('lang' => 'DB_NAME', 'type' => 'text:25:100', 'explain' => false),
|
---|
2105 | 'src_dbuser' => array('lang' => 'DB_USERNAME', 'type' => 'text:25:100', 'explain' => false),
|
---|
2106 | 'src_dbpasswd' => array('lang' => 'DB_PASSWORD', 'type' => 'password:25:100', 'explain' => false),
|
---|
2107 | 'src_table_prefix' => array('lang' => 'TABLE_PREFIX', 'type' => 'text:25:100', 'explain' => false),
|
---|
2108 | //'src_url' => array('lang' => 'FORUM_ADDRESS', 'type' => 'text:50:100', 'explain' => true),
|
---|
2109 | 'forum_path' => array('lang' => 'FORUM_PATH', 'type' => 'text:25:100', 'explain' => true),
|
---|
2110 | 'refresh' => array('lang' => 'REFRESH_PAGE', 'type' => 'radio:yes_no', 'explain' => true),
|
---|
2111 | );
|
---|
2112 | }
|
---|
2113 |
|
---|
2114 | ?>
|
---|