[ Index ]

PHP Cross Reference of Eventum

title

Body

[close]

/setup/ -> index.php (source)

   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  }


Generated: Wed Dec 19 21:21:33 2007 Cross-referenced by PHPXref 0.7