1<?php
2
3// No need to do anything if already converted and not forcing an update
4$isUTF8 = getConfig('UTF8converted');
5
6if ($isUTF8 && !isset($cline['f'])) {
7    echo s('The DB was already converted to UTF-8 on').' '.$isUTF8;
8    cl_output(s('The DB was already converted to UTF-8 on').' '.$isUTF8);
9
10    return;
11}
12//# convert DB to UTF-8
13if (!$GLOBALS['commandline']) {
14    ob_end_flush();
15    // make sure the browser doesn't buffer it
16    for ($i = 0; $i < 10000; ++$i) {
17        echo ' '."\n";
18    }
19}
20
21//# check diskspace. this operation duplicates the space required.
22$maxsize = 0;
23$req = Sql_Query('select (data_length+index_length) tablesize
24  from information_schema.tables
25  where table_schema="' .$GLOBALS['database_name'].'"');
26
27while ($row = Sql_Fetch_Assoc($req)) {
28    if ($row['tablesize'] > $maxsize) {
29        $maxsize = $row['tablesize'];
30    }
31}
32$maxsize = (int) ($maxsize * 1.2); //# add another 20%
33$row = Sql_Fetch_Row_Query('select @@datadir');
34$dataDir = $row[0];
35$avail = disk_free_space($dataDir);
36
37$require_confirmation = !isset($_GET['force']) || $_GET['force'] != 'yes';
38
39if ($maxsize > $avail && $require_confirmation) {
40    echo '<div class="error">'.s('Converting to UTF-8 requires sufficient diskspace on your system.').'<br/>';
41    echo s('The maximum table size in your system is %s and space available on the root filesystem is %s, which means %s is required.',
42        formatBytes($maxsize), formatBytes($avail), formatBytes($maxsize - $avail));
43    echo ' '.s('This is not a problem if your Database server is on a different filesystem. Click the button to continue.');
44
45    echo ' '.s('Otherwise, free up some diskspace and try again');
46    echo '<br/>'.PageLinkButton('converttoutf8&force=yes', s('Confirm UTF8 conversion'));
47
48    echo '</div>';
49
50    return;
51}
52
53cl_output(s('Converting DB to use UTF-8, please wait'));
54
55set_time_limit(5000);
56
57echo s('Converting DB to use UTF-8, please wait').'<br/>';
58//# convert to UTF8
59$dbname = $GLOBALS['database_name'];
60if (!empty($dbname)) {
61    //# the conversion complains about a key length
62    Sql_Query(sprintf('alter table '.$GLOBALS['tables']['user_blacklist_data'].' change column email email varchar(150) not null unique'));
63
64    $req = Sql_Query('select * from information_schema.columns where table_schema = "'.$dbname.'" and CHARACTER_SET_NAME != "utf8"');
65
66    $dbcolumns = array();
67    $dbtables = array();
68    while ($row = Sql_Fetch_Assoc($req)) {
69        //# make sure to only change our own tables, in case we share with other applications
70        if (in_array($row['TABLE_NAME'], array_values($GLOBALS['tables']))) {
71            $dbcolumns[] = $row;
72            $dbtables[$row['TABLE_NAME']] = $row['TABLE_NAME'];
73        }
74    }
75
76    cl_output($GLOBALS['I18N']->get('Upgrading the database to use UTF-8, please wait'));
77    foreach ($dbtables as $dbtable) {
78        set_time_limit(600);
79        echo($GLOBALS['I18N']->get('Upgrading table ').' '.$dbtable).'<br/>';
80        flush();
81        cl_output($GLOBALS['I18N']->get('Upgrading table ').' '.$dbtable);
82        Sql_Query(sprintf('alter table %s default charset utf8', $dbtable), 1);
83    }
84
85    foreach ($dbcolumns as $dbcolumn) {
86        set_time_limit(600);
87        echo($GLOBALS['I18N']->get('Upgrading column ').' '.$dbcolumn['COLUMN_NAME']).'<br/>';
88        flush();
89        cl_output($GLOBALS['I18N']->get('Upgrading column ').' '.$dbcolumn['COLUMN_NAME']);
90        Sql_Query(sprintf('alter table %s change column %s %s %s character set utf8',
91            $dbcolumn['TABLE_NAME'], $dbcolumn['COLUMN_NAME'], $dbcolumn['COLUMN_NAME'], $dbcolumn['COLUMN_TYPE']),
92            1);
93    }
94    cl_output($GLOBALS['I18N']->get('upgrade to UTF-8, done'));
95    saveConfig('UTF8converted', date('Y-m-d H:i'), 0);
96} else {
97    echo s('Unable to determine the name of the database to convert');
98}
99
100echo '<br/>'.s('All Done');
101