Issues (4868)

setup/fix_mysql_charset.php (1 issue)

1
<?php
2
/**
3
 * EGroupware Setup - fixes a mysql DB to match our system_charset
4
 *
5
 * @link http://www.egroupware.org
6
 * @package setup
7
 * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
8
 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
9
 * @version $Id$
10
 */
11
12
// if we are NOT called as part of an update script, behave like a regular setup script
13
if (!isset($GLOBALS['egw_setup']) || !is_object($GLOBALS['egw_setup']))
14
{
15
	$diagnostics = 1;	// can be set to 0=non, 1=some (default for now), 2=all
16
17
	include('./inc/functions.inc.php');
18
	// Authorize the user to use setup app and load the database
19
	// Does not return unless user is authorized
20
	if (!$GLOBALS['egw_setup']->auth('Config') || @$_POST['cancel'])
21
	{
22
		Header('Location: index.php');
23
		exit;
24
	}
25
	$GLOBALS['egw_setup']->loaddb();
26
27
	$tpl_root = $GLOBALS['egw_setup']->html->setup_tpl_dir('setup');
28
	$setup_tpl = CreateObject('phpgwapi.Template',$tpl_root);
0 ignored issues
show
Deprecated Code introduced by
The function CreateObject() has been deprecated: use autoloadable class-names and new ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

28
	$setup_tpl = /** @scrutinizer ignore-deprecated */ CreateObject('phpgwapi.Template',$tpl_root);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
29
	$setup_tpl->set_file(array(
30
		'T_head' => 'head.tpl',
31
		'T_footer' => 'footer.tpl',
32
	));
33
	$GLOBALS['egw_setup']->html->show_header('',False,'config',$GLOBALS['egw_setup']->ConfigDomain . '(' . $GLOBALS['egw_domain'][$GLOBALS['egw_setup']->ConfigDomain]['db_type'] . ')');
34
	echo '<h3>'.'Fix mysql DB to match the EGroupware system_charset'."</h3>\n";
35
	$running_standalone = true;
36
}
37
$db =& $GLOBALS['egw_setup']->db;
38
$charset2mysql =& $GLOBALS['egw_setup']->db->Link_ID->charset2mysql;
39
$mysql2charset = array_flip($charset2mysql);
40
41
$ServerInfo = $db->Link_ID->ServerInfo();
42
$db_version = (float) $ServerInfo['version'];
43
44
if ($running_standalone || $_REQUEST['debug']) echo "<p>DB-Type='<b>{$GLOBALS['egw_setup']->db->Type}</b>', DB-Version=<b>$db_version</b> ($ServerInfo[description]), EGroupware system_charset='<b>{$GLOBALS['egw_setup']->system_charset}</b>', DB-connection charset was '<b>{$GLOBALS['egw_setup']->db_charset_was}</b>'</p>\n";
45
46
$mysql_system_charset = isset($charset2mysql[$GLOBALS['egw_setup']->system_charset]) ?
47
	$charset2mysql[$GLOBALS['egw_setup']->system_charset] : $GLOBALS['egw_setup']->system_charset;
48
49
if (substr($db->Type,0,5) == 'mysql' && $db_version >= 4.1 && $GLOBALS['egw_setup']->system_charset && $GLOBALS['egw_setup']->db_charset_was &&
50
	$GLOBALS['egw_setup']->system_charset != $GLOBALS['egw_setup']->db_charset_was)
51
{
52
	$tables_modified = 'no';
53
54
	$tables = array();
55
	$db->query("SHOW TABLE STATUS",__LINE__,__FILE__);
56
	while (($row = $db->row(true)))
57
	{
58
		$tables[$row['Name']] = $row['Collation'];
59
	}
60
	foreach($tables as $table => $collation)
61
	{
62
		$columns = array();
63
		$db->query("SHOW FULL FIELDS FROM `$table`",__LINE__,__FILE__);
64
		while(($row = $db->row(true)))
65
		{
66
			$columns[] = $row;
67
		}
68
		//echo $table; _debug_array($columns);
69
		$fulltext = $fulltext_back = array();
70
		$db->query("SHOW KEYS FROM `$table`",__LINE__,__FILE__);
71
		while(($row = $db->row(true)))
72
		{
73
			if ($row['Index_type'] == 'FULLTEXT')
74
			{
75
				$fulltext[$row['Column_name']] = $row['Key_name'];
76
			}
77
		}
78
79
		$alter_table = $alter_table_back = array();
80
		foreach($columns as $column)
81
		{
82
			if ($column['Collation'] && preg_match('/^(char|varchar|.*text)\(?([0-9]*)\)?$/i',$column['Type'],$matches))
83
			{
84
				list(,$type,$size) = $matches;
85
				list($charset) = explode('_',$column['Collation']);
86
87
				if (isset($mysql2charset[$charset])) $charset = $mysql2charset[$charset];
88
89
				if ($charset != $GLOBALS['egw_setup']->system_charset)
90
				{
91
					$col = $column['Field'];
92
93
					if ($type == 'varchar' || $type == 'char')	// old schema_proc (pre 1.0.1) used also char
94
					{
95
						$type = 'varchar('.$size.')';
96
						$bintype = 'varbinary('.$size.')';
97
					}
98
					else
99
					{
100
						$bintype = str_replace('text','blob',$type);
101
					}
102
					//echo "<p>$table.$col $type CHARACTER SET $charset $default $null</p>\n";
103
104
					$default = !is_null($column['Default']) ? "DEFAULT '".$column['Default']."'" : '';
105
					$null = $column['Null'] ? 'NULL' : 'NOT NULL';
106
107
					if (isset($fulltext[$col]))
108
					{
109
						$idx_name = $fulltext[$col];
110
						$idx_cols = array();
111
						foreach($fulltext as $c => $i)
112
						{
113
							if ($i == $idx_name)
114
							{
115
								$idx_cols[] = $c;
116
								unset($fulltext[$c]);
117
							}
118
						}
119
						$fulltext_back[$idx_name] = $idx_cols;
120
						$alter_table[] = " DROP INDEX `$idx_name`";
121
					}
122
					$alter_table[] = " CHANGE `$col` `$col` $bintype $default $null";
123
					$alter_table_back[] = " CHANGE `$col` `$col` $type CHARACTER SET $mysql_system_charset $default $null";
124
				}
125
			}
126
		}
127
		list($charset) = explode('_',$collation);
128
		if (isset($mysql2charset[$charset])) $charset = $mysql2charset[$charset];
129
		if ($charset != $GLOBALS['egw_setup']->system_charset)
130
		{
131
			$alter_table[] = " DEFAULT CHARACTER SET $mysql_system_charset";
132
		}
133
		if (count($alter_table))
134
		{
135
			$alter_table = "ALTER TABLE $table\n".implode(",\n",$alter_table);
136
137
			if ($running_standalone || $_REQUEST['debug']) echo '<p>'.nl2br($alter_table)."</p>\n";
138
			if (!$db->query($alter_table,__LINE__,__FILE__))
139
			{
140
				echo "<p>SQL Error: ".nl2br($alter_table)."</p>\n";
141
				echo "<b>{$db->Type} Error</b>: {$db->Errno} ({$db->Error})</p>\n";
142
				echo "<p>continuing ...</p>\n";
143
				continue;
144
			}
145
			foreach($fulltext_back as $idx_name => $idx_cols)
146
			{
147
				$alter_table_back[] = " ADD FULLTEXT `$idx_name` (`".implode('`,`',$idx_cols)."`)";
148
			}
149
			if (count($alter_table_back))
150
			{
151
				$alter_table_back = "ALTER TABLE $table\n".implode(",\n",$alter_table_back);
152
153
				if ($running_standalone || $_REQUEST['debug']) echo '<p>'.nl2br($alter_table_back)."</p>\n";
154
				if (!$db->query($alter_table_back,__LINE__,__FILE__))
155
				{
156
					echo "<p><b>SQL Error</b>: ".nl2br($alter_table_back)."</p>\n";
157
					echo "<b>{$db->Type} Error</b>: {$db->Errno} ({$db->Error})</p>\n";
158
					echo "<p>continuing ...</p>\n";
159
					continue;
160
				}
161
			}
162
			++$tables_modified;
163
		}
164
	}
165
	// change the default charset of the DB
166
	$db->query("SHOW CREATE DATABASE `$db->Database`",__LINE__,__FILE__);
167
	$create_db = $db->next_record() ? $db->f(1) : '';
168
	if (preg_match('/CHARACTER SET ([a-z1-9_-]+) /i',$create_db,$matches) && $matches[1] != $mysql_system_charset)
169
	{
170
		$alter_db = "ALTER DATABASE `$db->Database` DEFAULT CHARACTER SET $mysql_system_charset";
171
		if ($running_standalone || $_REQUEST['debug']) echo '<p>'.$alter_db."</p>\n";
172
		$db->query($alter_db,__LINE__,__FILE__);
173
	}
174
}
175
if ($running_standalone || $_REQUEST['debug'])
176
{
177
	echo "<p>$tables_modified tables changed to our system_charset {$GLOBALS['egw_setup']->system_charset}($mysql_system_charset)</p>\n";
178
179
	if ($running_standalone) $GLOBALS['egw_setup']->html->show_footer();
180
}
181