[ Index ] |
PHP Cross Reference of Eventum |
[Summary view] [Print] [Text view]
1 <?php 2 /* vim: set expandtab tabstop=4 shiftwidth=4 encoding=utf-8: */ 3 // +----------------------------------------------------------------------+ 4 // | Eventum - Issue Tracking System | 5 // +----------------------------------------------------------------------+ 6 // | Copyright (c) 2003, 2004, 2005, 2006, 2007 MySQL AB | 7 // | | 8 // | This program is free software; you can redistribute it and/or modify | 9 // | it under the terms of the GNU General Public License as published by | 10 // | the Free Software Foundation; either version 2 of the License, or | 11 // | (at your option) any later version. | 12 // | | 13 // | This program is distributed in the hope that it will be useful, | 14 // | but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 // | GNU General Public License for more details. | 17 // | | 18 // | You should have received a copy of the GNU General Public License | 19 // | along with this program; if not, write to: | 20 // | | 21 // | Free Software Foundation, Inc. | 22 // | 59 Temple Place - Suite 330 | 23 // | Boston, MA 02111-1307, USA. | 24 // +----------------------------------------------------------------------+ 25 // | Authors: Bryan Alsdorf <bryan@mysql.com> | 26 // | Authors: Elan Ruusamäe <glen@delfi.ee> | 27 // +----------------------------------------------------------------------+ 28 // 29 30 // XXX: try reading $_ENV['HOSTNAME'] and then ask the user if nothing could be found 31 // XXX: dynamically check the email blob and skips the email if it is bigger than 16mb on PHP4 versions 32 33 ini_set('memory_limit', '64M'); 34 set_magic_quotes_runtime(0); 35 36 ini_set('display_errors', 1); 37 error_reporting(E_ALL); 38 set_time_limit(0); 39 define('APP_CHARSET', 'UTF-8'); 40 define('APP_DEFAULT_LOCALE', 'en_US'); 41 define('APP_PATH', realpath(dirname(__FILE__) . '/..') . '/'); 42 define('APP_INC_PATH', APP_PATH . 'include/'); 43 define('APP_PEAR_PATH', APP_INC_PATH . 'pear/'); 44 define('APP_SMARTY_PATH', APP_INC_PATH . 'Smarty/'); 45 define('APP_CONFIG_PATH', APP_PATH . 'config/'); 46 define('APP_SETUP_FILE', APP_CONFIG_PATH . 'setup.php'); 47 define('APP_TPL_PATH', APP_PATH . 'templates/'); 48 define('APP_TPL_COMPILE_PATH', APP_PATH . 'templates_c'); 49 define('APP_LOG_PATH', APP_PATH . 'logs/'); 50 define('APP_ERROR_LOG', APP_LOG_PATH . 'errors.log'); 51 define('APP_LOCKS_PATH', APP_PATH . 'locks/'); 52 53 define('APP_BENCHMARK', false); 54 55 header('content-type: text/html;charset=' . APP_CHARSET); 56 57 set_include_path(get_include_path() . PATH_SEPARATOR . APP_PEAR_PATH); 58 require_once('File/Util.php'); 59 60 $html = checkRequirements(); 61 if (!empty($html)) { 62 echo $html; 63 exit; 64 } 65 66 require_once(APP_SMARTY_PATH . 'Smarty.class.php'); 67 68 $tpl = new Smarty(); 69 $tpl->template_dir = APP_TPL_PATH; 70 $tpl->compile_dir = APP_TPL_COMPILE_PATH; 71 $tpl->config_dir = ''; 72 73 if (@$_POST['cat'] == 'install') { 74 $res = install(); 75 $tpl->assign('result', $res); 76 // check for the optional IMAP extension 77 $tpl->assign('is_imap_enabled', function_exists('imap_open')); 78 } 79 80 81 $full_url = dirname($_SERVER['PHP_SELF']); 82 $pieces = explode('/', $full_url); 83 $relative_url = array(); 84 $relative_url[] = ''; 85 foreach ($pieces as $piece) { 86 if ((!empty($piece)) && ($piece != 'setup')) { 87 $relative_url[] = $piece; 88 } 89 } 90 $relative_url[] = ''; 91 $relative_url = implode('/', $relative_url); 92 93 $tpl->assign('phpversion', phpversion()); 94 $tpl->assign('rel_url', $relative_url); 95 if (@$_SERVER['HTTPS'] == 'on') { 96 $ssl_mode = 'enabled'; 97 } else { 98 $ssl_mode = 'disabled'; 99 } 100 $tpl->assign('ssl_mode', $ssl_mode); 101 102 $tpl->display('setup.tpl.html'); 103 104 105 function checkPermissions($file, $desc, $is_directory = FALSE) 106 { 107 clearstatcache(); 108 if (!file_exists($file)) { 109 if (!$is_directory) { 110 // try to create the file ourselves then 111 $fp = @fopen($file, 'w'); 112 if (!$fp) { 113 return getPermissionError($file, $desc, $is_directory, false); 114 } 115 @fclose($fp); 116 } else { 117 if (!@mkdir($file)) { 118 return getPermissionError($file, $desc, $is_directory, false); 119 } 120 } 121 } 122 clearstatcache(); 123 if (!is_writable($file)) { 124 if (!stristr(PHP_OS, 'win')) { 125 // let's try to change the permissions ourselves 126 @chmod($file, 0644); 127 clearstatcache(); 128 if (!is_writable($file)) { 129 return getPermissionError($file, $desc, $is_directory, true); 130 } 131 } else { 132 return getPermissionError($file, $desc, $is_directory, true); 133 } 134 } 135 if (stristr(PHP_OS, 'win')) { 136 // need to check whether we can really create files in this directory or not 137 // since is_writable() is not trustworthy on windows platforms 138 if (is_dir($file)) { 139 $fp = @fopen($file . '/dummy.txt', 'w'); 140 if (!$fp) { 141 return "$desc is not writable"; 142 } 143 @fwrite($fp, 'test'); 144 @fclose($fp); 145 // clean up after ourselves 146 @unlink($file . '/dummy.txt'); 147 } 148 } 149 return ''; 150 } 151 152 function getPermissionError($file, $desc, $is_directory, $exists) 153 { 154 $error = ''; 155 if ($is_directory) { 156 $title = 'Directory'; 157 } else { 158 $title = 'File'; 159 } 160 $error = "$title <b>'" . File_Util::realPath($file) . ($is_directory ? '/' : '') . "'</b> "; 161 162 if (!$exists) { 163 $error .= "does not exist. Please create the $title and reload this page."; 164 } else { 165 $error .= "is not writeable. Please change this $title to be writeable by the web server."; 166 } 167 168 return $error; 169 } 170 171 function checkRequirements() 172 { 173 $errors = array(); 174 175 // check for GD support 176 ob_start(); 177 phpinfo(); 178 $contents = ob_get_contents(); 179 ob_end_clean(); 180 if (!preg_match('/GD Support.*<\/td><td.*>enabled/U', $contents)) { 181 $errors[] = 'The GD extension needs to be enabled in your PHP.INI file in order for Eventum to work properly.'; 182 } 183 // check for session support 184 if (!function_exists('session_start')) { 185 $errors[] = 'The Session extension needs to be enabled in your PHP.INI file in order for Eventum to work properly.'; 186 } 187 // check for MySQL support 188 if (!function_exists('mysql_query')) { 189 $errors[] = 'The MySQL extension needs to be enabled in your PHP.INI file in order for Eventum to work properly.'; 190 } 191 // check for the file_uploads php.ini directive 192 if (ini_get('file_uploads') != "1") { 193 $errors[] = "The 'file_uploads' directive needs to be enabled in your PHP.INI file in order for Eventum to work properly."; 194 } 195 $error = checkPermissions(APP_CONFIG_PATH, "Directory '" . APP_CONFIG_PATH . "'", TRUE); 196 if (!empty($error)) { 197 $errors[] = $error; 198 } 199 $error = checkPermissions(APP_LOCKS_PATH, "Directory '" . APP_LOCKS_PATH . "'", TRUE); 200 if (!empty($error)) { 201 $errors[] = $error; 202 } 203 $error = checkPermissions(APP_LOG_PATH, "Directory '". APP_LOG_PATH . "'", TRUE); 204 if (!empty($error)) { 205 $errors[] = $error; 206 } 207 $error = checkPermissions(APP_TPL_COMPILE_PATH, "Directory '" . APP_TPL_COMPILE_PATH . "'", TRUE); 208 if (!empty($error)) { 209 $errors[] = $error; 210 } 211 $error = checkPermissions(APP_ERROR_LOG, "File '" . APP_ERROR_LOG . "'"); 212 if (!empty($error)) { 213 $errors[] = $error; 214 } 215 216 $html = ''; 217 if (count($errors) > 0) { 218 $html = '<html> 219 <head> 220 <style type="text/css"> 221 <!-- 222 .default { 223 font-family: Verdana, Arial, Helvetica, sans-serif; 224 font-style: normal; 225 font-weight: normal; 226 font-size: 70%; 227 } 228 --> 229 </style> 230 <title>Eventum Setup</title> 231 </head> 232 <body> 233 234 <br /><br /> 235 236 <table width="600" bgcolor="#003366" border="0" cellspacing="0" cellpadding="1" align="center"> 237 <tr> 238 <td> 239 <table bgcolor="#FFFFFF" width="100%" cellspacing="1" cellpadding="2" border="0"> 240 <tr> 241 <td><img src="../images/icons/error.gif" hspace="2" vspace="2" border="0" align="left"></td> 242 <td width="100%" class="default"><span style="font-weight: bold; font-size: 160%; color: red;">Configuration Error:</span></td> 243 </tr> 244 <tr> 245 <td colspan="2" class="default"> 246 <br /> 247 <b>The following problems regarding file and/or directory permissions were found:</b> 248 <br /><br /> 249 ' . implode("\n<hr>\n", $errors) . ' 250 <br /><br /> 251 <b>Please provide the appropriate permissions to the user that the web server run as to write in the directories and files specified above.</b> 252 <br /><br /> 253 </td> 254 </tr> 255 </table> 256 </td> 257 </tr> 258 </table> 259 260 </body> 261 </html>'; 262 } 263 return $html; 264 } 265 266 267 function replace_table_prefix($str) 268 { 269 return str_replace('%TABLE_PREFIX%', $_POST['db_table_prefix'], $str); 270 } 271 272 function getErrorMessage($type, $message) 273 { 274 if (empty($message)) { 275 return ''; 276 } else { 277 if (stristr($message, 'Unknown MySQL Server Host')) { 278 return 'Could not connect to the MySQL database server with the provided information.'; 279 } elseif (stristr($message, 'Unknown database')) { 280 return 'The database name provided does not exist.'; 281 } elseif (($type == 'create_test') && (stristr($message, 'Access denied'))) { 282 return 'The provided MySQL username doesn\'t have the appropriate permissions to create tables. Please contact your local system administrator for further assistance.'; 283 } elseif (($type == 'drop_test') && (stristr($message, 'Access denied'))) { 284 return 'The provided MySQL username doesn\'t have the appropriate permissions to drop tables. Please contact your local system administrator for further assistance.'; 285 } 286 return $message; 287 } 288 } 289 290 function getDatabaseList($conn) 291 { 292 $db_list = mysql_list_dbs($conn); 293 $dbs = array(); 294 while ($row = mysql_fetch_array($db_list)) { 295 $dbs[] = $row['Database']; 296 } 297 return $dbs; 298 } 299 300 function getUserList($conn) 301 { 302 @mysql_select_db('mysql'); 303 $res = @mysql_query('SELECT DISTINCT User from user'); 304 $users = array(); 305 // if the user cannot select from the mysql.user table, then return an empty list 306 if (!$res) { 307 return $users; 308 } 309 while ($row = mysql_fetch_row($res)) { 310 $users[] = $row[0]; 311 } 312 return $users; 313 } 314 315 function getTableList($conn) 316 { 317 $res = mysql_query('SHOW TABLES', $conn); 318 $tables = array(); 319 while ($row = mysql_fetch_row($res)) { 320 $tables[] = $row[0]; 321 } 322 return $tables; 323 } 324 325 function install() 326 { 327 $private_key_path = APP_CONFIG_PATH . 'private_key.php'; 328 $config_file_path = APP_CONFIG_PATH . 'config.php'; 329 $setup_file_path = APP_SETUP_FILE; 330 331 clearstatcache(); 332 // check if config directory is writable 333 if (!is_writable(APP_CONFIG_PATH)) { 334 return "The file '" . APP_CONFIG_PATH . "' directory needs to be writable by the web server user. Please correct this problem and try again."; 335 } 336 // need to create a random private key variable 337 $private_key = '<?php 338 $private_key = "' . md5(microtime()) . '"; 339 ?>'; 340 $fp = @fopen($private_key_path, 'w'); 341 if ($fp === FALSE) { 342 return "Could not open the file '$private_key_path' for writing. The permissions on the file should be set as to allow the user that the web server runs as to open it. Please correct this problem and try again."; 343 } 344 $res = fwrite($fp, $private_key); 345 if ($fp === FALSE) { 346 return "Could not write the configuration information to '$private_key_path'. The file should be writable by the user that the web server runs as. Please correct this problem and try again."; 347 } 348 fclose($fp); 349 // check if we can connect 350 $conn = @mysql_connect($_POST['db_hostname'], $_POST['db_username'], $_POST['db_password']); 351 if (!$conn) { 352 return getErrorMessage('connect', mysql_error()); 353 } 354 $db_list = getDatabaseList($conn); 355 $db_list = array_map('strtolower', $db_list); 356 if (@$_POST['create_db'] == 'yes') { 357 if (!in_array(strtolower($_POST['db_name']), $db_list)) { 358 if (!mysql_query('CREATE DATABASE ' . $_POST['db_name'], $conn)) { 359 return getErrorMessage('create_db', mysql_error()); 360 } 361 } 362 } else { 363 if ((count($db_list) > 0) && (!in_array(strtolower($_POST['db_name']), $db_list))) { 364 return "The provided database name could not be found. Review your information or specify that the database should be created in the form below."; 365 } 366 } 367 // create the new user, if needed 368 if (@$_POST["alternate_user"] == 'yes') { 369 $user_list = getUserList($conn); 370 if (count($user_list) > 0) { 371 $user_list = array_map('strtolower', $user_list); 372 if (@$_POST["create_user"] == 'yes') { 373 if (!in_array(strtolower(@$_POST['eventum_user']), $user_list)) { 374 $stmt = "GRANT SELECT, UPDATE, DELETE, INSERT, ALTER, DROP, CREATE, INDEX ON " . $_POST['db_name'] . ".* TO '" . $_POST["eventum_user"] . "'@'%' IDENTIFIED BY '" . $_POST["eventum_password"] . "'"; 375 if (!mysql_query($stmt, $conn)) { 376 return getErrorMessage('create_user', mysql_error()); 377 } 378 } 379 } else { 380 if (!in_array(strtolower(@$_POST['eventum_user']), $user_list)) { 381 return "The provided MySQL username could not be found. Review your information or specify that the username should be created in the form below."; 382 } 383 } 384 } 385 } 386 // check if we can use the database 387 if (!mysql_select_db($_POST['db_name'])) { 388 return getErrorMessage('select_db', mysql_error()); 389 } 390 // check the CREATE and DROP privileges by trying to create and drop a test table 391 $table_list = getTableList($conn); 392 $table_list = array_map('strtolower', $table_list); 393 if (!in_array('eventum_test', $table_list)) { 394 if (!mysql_query('CREATE TABLE eventum_test (test char(1))', $conn)) { 395 return getErrorMessage('create_test', mysql_error()); 396 } 397 } 398 if (!mysql_query('DROP TABLE eventum_test', $conn)) { 399 return getErrorMessage('drop_test', mysql_error()); 400 } 401 $contents = implode("", file("schema.sql")); 402 $queries = explode(";", $contents); 403 unset($queries[count($queries)-1]); 404 // COMPAT: the next line requires PHP >= 4.0.6 405 $queries = array_map("trim", $queries); 406 $queries = array_map("replace_table_prefix", $queries); 407 foreach ($queries as $stmt) { 408 if ((stristr($stmt, 'DROP TABLE')) && (@$_POST['drop_tables'] != 'yes')) { 409 continue; 410 } 411 // need to check if a CREATE TABLE on an existing table throws an error 412 if (!mysql_query($stmt, $conn)) { 413 if (stristr($stmt, 'DROP TABLE')) { 414 $type = 'drop_table'; 415 } else { 416 $type = 'create_table'; 417 } 418 return getErrorMessage($type, mysql_error()); 419 } 420 } 421 // substitute the appropriate values in config.php!!! 422 if (@$_POST['alternate_user'] == 'yes') { 423 $_POST['db_username'] = $_POST['eventum_user']; 424 $_POST['db_password'] = $_POST['eventum_password']; 425 } 426 $config_contents = file_get_contents('config.php'); 427 $config_contents = str_replace("%{APP_SQL_DBHOST}%", $_POST['db_hostname'], $config_contents); 428 $config_contents = str_replace("%{APP_SQL_DBNAME}%", $_POST['db_name'], $config_contents); 429 $config_contents = str_replace("%{APP_SQL_DBUSER}%", $_POST['db_username'], $config_contents); 430 $config_contents = str_replace("%{APP_SQL_DBPASS}%", $_POST['db_password'], $config_contents); 431 $config_contents = str_replace("%{APP_TABLE_PREFIX}%", $_POST['db_table_prefix'], $config_contents); 432 $config_contents = str_replace("%{APP_HOSTNAME}%", $_POST['hostname'], $config_contents); 433 $config_contents = str_replace("%{CHARSET}%", APP_CHARSET, $config_contents); 434 $config_contents = str_replace("%{APP_RELATIVE_URL}%", $_POST['relative_url'], $config_contents); 435 if (@$_POST['is_ssl'] == 'yes') { 436 $protocol_type = 'https://'; 437 } else { 438 $protocol_type = 'http://'; 439 } 440 $config_contents = str_replace("%{PROTOCOL_TYPE}%", $protocol_type, $config_contents); 441 // disable the full-text search feature for certain mysql server users 442 $stmt = "SELECT VERSION();"; 443 $res = mysql_query($stmt, $conn); 444 $mysql_version = mysql_result($res, 0, 0); 445 preg_match('/(\d{1,2}\.\d{1,2}\.\d{1,2})/', $mysql_version, $matches); 446 if ($matches[1] > '4.0.23') { 447 $config_contents = str_replace("'%{APP_ENABLE_FULLTEXT}%'", "true", $config_contents); 448 } else { 449 $config_contents = str_replace("'%{APP_ENABLE_FULLTEXT}%'", "false", $config_contents); 450 } 451 452 $fp = @fopen($config_file_path, 'w'); 453 if ($fp === FALSE) { 454 return "Could not open the file '$config_file_path' for writing. The permissions on the file should be set as to allow the user that the web server runs as to open it. Please correct this problem and try again."; 455 } 456 $res = fwrite($fp, $config_contents); 457 if ($fp === FALSE) { 458 return "Could not write the configuration information to '$config_file_path'. The file should be writable by the user that the web server runs as. Please correct this problem and try again."; 459 } 460 fclose($fp); 461 462 // write setup file 463 require_once (APP_INC_PATH . "class.setup.php"); 464 $_REQUEST['setup']['update'] = 1; 465 $_REQUEST['setup']['closed'] = 1; 466 $_REQUEST['setup']['emails'] = 1; 467 $_REQUEST['setup']['files'] = 1; 468 $_REQUEST['setup']['allow_unassigned_issues'] = 'yes'; 469 $_REQUEST['setup']['support_email'] = 'enabled'; 470 Setup::save($_REQUEST['setup']); 471 472 return 'success'; 473 } 474 475 476 function ev_gettext($str) 477 { 478 return $str; 479 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Dec 19 21:21:33 2007 | Cross-referenced by PHPXref 0.7 |