PageRenderTime 28ms CodeModel.GetById 17ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/installer/installer.php

http://github.com/gallery/gallery3
PHP | 270 lines | 209 code | 32 blank | 29 comment | 30 complexity | 1e355e2ff95d0300725e67a06745d063 MD5 | raw file
  1<?php defined("SYSPATH") or die("No direct script access.");
  2/**
  3 * Gallery - a web based photo album viewer and editor
  4 * Copyright (C) 2000-2013 Bharat Mediratta
  5 *
  6 * This program is free software; you can redistribute it and/or modify
  7 * it under the terms of the GNU General Public License as published by
  8 * the Free Software Foundation; either version 2 of the License, or (at
  9 * your option) any later version.
 10 *
 11 * This program is distributed in the hope that it will be useful, but
 12 * WITHOUT ANY WARRANTY; without even the implied warranty of
 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14 * General Public License for more details.
 15 *
 16 * You should have received a copy of the GNU General Public License
 17 * along with this program; if not, write to the Free Software
 18 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA.
 19 */
 20
 21class installer {
 22  static $mysqli;
 23
 24  static function already_installed() {
 25    return file_exists(VARPATH . "database.php");
 26  }
 27
 28  static function var_writable() {
 29    if (is_writable(VARPATH)) {
 30      return true;
 31    }
 32
 33    if (@mkdir(VARPATH)) {
 34      return true;
 35    }
 36
 37    return false;
 38  }
 39
 40  static function create_database_config($config) {
 41    $db_config_file = VARPATH . "database.php";
 42    ob_start();
 43    extract($config);
 44    include(DOCROOT . "installer/database_config.php");
 45    $output = ob_get_clean();
 46    return file_put_contents($db_config_file, $output) !== false;
 47  }
 48
 49  static function unpack_var() {
 50    if (!file_exists(VARPATH)) {
 51      mkdir(VARPATH);
 52      chmod(VARPATH, 0777);
 53    }
 54
 55    include(DOCROOT . "installer/init_var.php");
 56    return true;
 57  }
 58
 59  static function unpack_sql($config) {
 60    $prefix = $config["prefix"];
 61    $buf = null;
 62    foreach (file(DOCROOT . "installer/install.sql") as $line) {
 63      $buf .= trim($line);
 64      if (preg_match("/;$/", $buf)) {
 65        if (!mysql_query(self::prepend_prefix($prefix, $buf))) {
 66          return false;
 67        }
 68        $buf = "";
 69      }
 70    }
 71    return true;
 72  }
 73
 74  static function connect($config) {
 75    // We know that we have either mysql or mysqli.  By default we use mysql functions, so if
 76    // they're not defined then do the simplest thing which will work: remap them to their mysqli
 77    // counterparts.
 78    if (!function_exists("mysql_query")) {
 79      function mysql_connect($host, $user, $pass) {
 80        list ($host, $port) = explode(":", $host . ":");
 81        installer::$mysqli = new mysqli($host, $user, $pass, $port);
 82        // http://php.net/manual/en/mysqli.connect.php says to use mysqli_connect_error() instead of
 83        // $mysqli->connect_error because of bugs before PHP 5.2.9
 84        $error = mysqli_connect_error();
 85        return empty($error);
 86      }
 87      function mysql_query($query) {
 88        return installer::$mysqli->query($query);
 89      }
 90      function mysql_num_rows($result) {
 91        return $result->num_rows;
 92      }
 93      function mysql_error() {
 94        return installer::$mysqli->error;
 95      }
 96      function mysql_select_db($db) {
 97        return installer::$mysqli->select_db($db);
 98      }
 99    }
100
101    $host = empty($config["port"]) ? $config['host'] : "{$config['host']}:{$config['port']}";
102    return @mysql_connect($host, $config["user"], $config["password"]);
103  }
104
105  static function select_db($config) {
106    if (mysql_select_db($config["dbname"])) {
107      return true;
108    }
109
110    return mysql_query("CREATE DATABASE `{$config['dbname']}`") &&
111      mysql_select_db($config["dbname"]);
112  }
113
114  static function verify_mysql_version($config) {
115    return version_compare(installer::mysql_version($config), "5.0.0", ">=");
116  }
117
118  static function mysql_version($config) {
119    $result = mysql_query("SHOW VARIABLES WHERE variable_name = \"version\"");
120    $row = mysql_fetch_object($result);
121    return $row->Value;
122  }
123
124  static function db_empty($config) {
125    $query = "SHOW TABLES LIKE '{$config['prefix']}items'";
126    $results = mysql_query($query);
127    if ($results === false) {
128      $msg = mysql_error();
129      return $msg;
130    }
131    return mysql_num_rows($results) === 0;
132  }
133
134  static function create_admin($config) {
135    $salt = "";
136    for ($i = 0; $i < 4; $i++) {
137      $char = mt_rand(48, 109);
138      $char += ($char > 90) ? 13 : ($char > 57) ? 7 : 0;
139      $salt .= chr($char);
140    }
141    if (!$password = $config["g3_password"]) {
142      $password = substr(md5(time() . mt_rand()), 0, 6);
143    }
144    // Escape backslash in preparation for our UPDATE statement.
145    $hashed_password = str_replace("\\", "\\\\", $salt . md5($salt . $password));
146    $sql = self::prepend_prefix($config["prefix"],
147       "UPDATE {users} SET `password` = '$hashed_password' WHERE `id` = 2");
148    if (mysql_query($sql)) {
149    } else {
150      throw new Exception(mysql_error());
151    }
152
153    return array("admin", $password);
154  }
155
156  static function create_admin_session($config) {
157    $session_id = md5(time() . mt_rand());
158    $user_agent = $_SERVER["HTTP_USER_AGENT"];
159    $user_agent_len = strlen($user_agent);
160    $now = time();
161    $data = "session_id|s:32:\"$session_id\"";
162    $data .= ";user_agent|s:{$user_agent_len}:\"$user_agent\"";
163    $data .= ";user|i:2";
164    $data .= ";after_install|i:1";
165    $data .= ";last_activity|i:$now";
166    $data = base64_encode($data);
167    $sql = "INSERT INTO {sessions}(`session_id`, `last_activity`, `data`) " .
168      "VALUES('$session_id', $now, '$data')";
169    $sql = self::prepend_prefix($config["prefix"], $sql);
170    if (mysql_query($sql)) {
171      setcookie("g3sid", $session_id, 0, "/", "", false, false);
172    } else {
173      throw new Exception(mysql_error());
174    }
175  }
176
177  static function create_private_key($config) {
178    $key = md5(uniqid(mt_rand(), true)) . md5(uniqid(mt_rand(), true));
179    $sql = self::prepend_prefix($config["prefix"],
180       "INSERT INTO {vars} VALUES(NULL, 'gallery', 'private_key', '$key')");
181    if (mysql_query($sql)) {
182    } else {
183      throw new Exception(mysql_error());
184    }
185  }
186
187  static function prepend_prefix($prefix, $sql) {
188    return preg_replace("#{([a-zA-Z0-9_]+)}#", "`{$prefix}$1`", $sql);
189  }
190
191  static function check_environment() {
192    if (!function_exists("mysql_query") && !function_exists("mysqli_set_charset")) {
193      $errors[] = "Gallery 3 requires a MySQL database, but PHP doesn't have either the <a href=\"http://php.net/mysql\">MySQL</a> or the  <a href=\"http://php.net/mysqli\">MySQLi</a> extension.";
194    }
195
196    if (!preg_match("/^.$/u", "ñ")) {
197      $errors[] = "PHP is missing <a href=\"http://php.net/pcre\">Perl-Compatible Regular Expression</a> with UTF-8 support.";
198    } else if (!preg_match("/^\pL$/u", "ñ")) {
199      $errors[] = "PHP is missing <a href=\"http://php.net/pcre\">Perl-Compatible Regular Expression</a> with Unicode support.";
200    }
201
202    if (!(function_exists("spl_autoload_register"))) {
203      $errors[] = "PHP is missing <a href=\"http://php.net/spl\">Standard PHP Library (SPL)</a> support";
204    }
205
206    if (!(class_exists("ReflectionClass"))) {
207      $errors[] = "PHP is missing <a href=\"http://php.net/reflection\">reflection</a> support";
208    }
209
210    if (!(function_exists("filter_list"))) {
211      $errors[] = "PHP is missing the <a href=\"http://php.net/filter\">filter extension</a>";
212    }
213
214    if (!(extension_loaded("iconv"))) {
215      $errors[] = "PHP is missing the <a href=\"http://php.net/iconv\">iconv extension</a>";
216    }
217
218    if (!(extension_loaded("xml"))) {
219      $errors[] = "PHP is missing the <a href=\"http://php.net/xml\">XML Parser extension</a>";
220    }
221
222    if (!(extension_loaded("simplexml"))) {
223      $errors[] = "PHP is missing the <a href=\"http://php.net/simplexml\">SimpleXML extension</a>";
224    }
225
226    if (!extension_loaded("mbstring")) {
227      $errors[] = "PHP is missing the <a href=\"http://php.net/mbstring\">mbstring extension</a>";
228    } else if (ini_get("mbstring.func_overload") & MB_OVERLOAD_STRING) {
229      $errors[] = "The <a href=\"http://php.net/mbstring\">mbstring extension</a> is overloading PHP's native string functions.  Please disable it.";
230    }
231
232    if (!function_exists("json_encode")) {
233      $errors[] = "PHP is missing the <a href=\"http://php.net/manual/en/book.json.php\">JavaScript Object Notation (JSON) extension</a>.  Please install it.";
234    }
235
236    if (!ini_get("short_open_tag")) {
237      $errors[] = "Gallery requires <a href=\"http://php.net/manual/en/ini.core.php\">short_open_tag</a> to be on.  Please enable it in your php.ini.";
238    }
239
240    if (!function_exists("ctype_alpha")) {
241      $errors[] = "Gallery requires the <a href=\"http://php.net/manual/en/book.ctype.php\">PHP Ctype</a> extension.  Please install it.";
242    }
243
244    if (self::ini_get_bool("safe_mode")) {
245      $errors[] = "Gallery cannot function when PHP is in <a href=\"http://php.net/manual/en/features.safe-mode.php\">Safe Mode</a>.  Please disable safe mode.";
246    }
247
248    return @$errors;
249  }
250
251  /**
252   * Convert any possible boolean ini value to true/false.
253   *   On = on = 1 = true
254   *   Off = off = 0 = false
255   */
256  static function ini_get_bool($varname) {
257    $value = ini_get($varname);
258
259    if (!strcasecmp("on", $value) || $value == 1 || $value === true) {
260      return true;
261    }
262
263    if (!strcasecmp("off", $value) || $value == 0 || $value === false) {
264      return false;
265    }
266
267    return false;
268  }
269
270}