Files

551 lines
26 KiB
PHP

<?php
/* First-run installer. It imports schema.mysql.sql into an existing database and
writes config.php. The missing config.php is the only thing gating this
endpoint, so it refuses to run once that file exists. */
require(__DIR__.'/lib/http.php');
require(__DIR__.'/lib/i18n.php');
// Installer has no config yet, so language follows the request/cookie/browser.
i18n_configure(NULL, rtrim(str_replace('\\', '/', dirname(install_page_url())), '/'));
function install_escape($value) {
return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
}
function install_config_path() {
return __DIR__.DIRECTORY_SEPARATOR.'config.php';
}
function install_is_complete() {
return file_exists(install_config_path());
}
function install_page_url() {
$script = isset($_SERVER['SCRIPT_NAME']) ? (string) $_SERVER['SCRIPT_NAME'] : '';
return $script === '' ? '/install.php' : $script;
}
function install_home_url() {
$base = rtrim(str_replace('\\', '/', dirname(install_page_url())), '/');
return $base === '' ? '/' : $base.'/';
}
function install_request_is_https() {
$https = isset($_SERVER['HTTPS']) ? strtolower((string) $_SERVER['HTTPS']) : '';
return $https === 'on' || $https === '1'
|| (isset($_SERVER['SERVER_PORT']) && (string) $_SERVER['SERVER_PORT'] === '443');
}
function install_start_session() {
if (session_status() === PHP_SESSION_ACTIVE) {
return TRUE;
}
if (session_status() === PHP_SESSION_DISABLED || headers_sent()) {
return FALSE;
}
session_name('PHPGITSERVERINSTALL');
session_set_cookie_params(array(
'lifetime' => 0,
'path' => install_home_url(),
'secure' => install_request_is_https(),
'httponly' => TRUE,
'samesite' => 'Strict'));
return @session_start();
}
function install_csrf_token() {
if (!install_start_session()) {
return FALSE;
}
if (!isset($_SESSION['install_csrf_token'])
|| !is_string($_SESSION['install_csrf_token'])
|| strlen($_SESSION['install_csrf_token']) !== 64) {
try {
$_SESSION['install_csrf_token'] = bin2hex(random_bytes(32));
} catch (Exception $exception) {
return FALSE;
}
}
return $_SESSION['install_csrf_token'];
}
function install_post_value($name) {
return isset($_POST[$name]) && is_string($_POST[$name]) ? $_POST[$name] : '';
}
function install_post_checked($name) {
return isset($_POST[$name]) && $_POST[$name] === '1';
}
/* MySQL identifiers cannot be bound as parameters, so they are restricted to a
conservative character set before any interpolation. Hyphens are allowed
because shared hosting panels routinely generate names that contain them. */
function install_identifier_is_valid($value) {
return is_string($value) && preg_match('~^[A-Za-z0-9_$-]{1,64}$~D', $value) === 1;
}
function install_host_is_valid($value) {
return is_string($value) && preg_match('~^[A-Za-z0-9._%-]{1,255}$~D', $value) === 1;
}
function install_quote_identifier($value) {
return '`'.str_replace('`', '``', $value).'`';
}
function install_schema_statements() {
$buffer = @file_get_contents(__DIR__.DIRECTORY_SEPARATOR.'schema.mysql.sql');
if ($buffer === FALSE) {
return FALSE;
}
$statements = array();
foreach (preg_split('~;\s*(?:\r?\n|$)~', $buffer) as $statement) {
$statement = trim($statement);
if ($statement !== '') {
$statements[] = $statement;
}
}
return $statements;
}
function install_validate($input) {
$errors = array();
if ($input['url_base'] !== ''
&& !preg_match('~^/[A-Za-z0-9._~/-]*[A-Za-z0-9._~-]$~D', $input['url_base'])) {
$errors[] = t('install.error_url_base');
}
if (!install_host_is_valid($input['db_host'])) {
$errors[] = t('install.error_db_host');
}
if (!preg_match('~^[1-9][0-9]{0,4}$~D', $input['db_port']) || (int) $input['db_port'] > 65535) {
$errors[] = t('install.error_db_port');
}
if (!install_identifier_is_valid($input['db_name'])) {
$errors[] = t('install.error_db_name');
}
if (!install_identifier_is_valid($input['db_user'])) {
$errors[] = t('install.error_db_user');
}
if ($input['db_password'] === '' || strlen($input['db_password']) > 255) {
$errors[] = t('install.error_db_password');
}
if (auth_normalize_username($input['admin_username']) === FALSE) {
$errors[] = t('install.error_admin_username');
}
if (!auth_password_is_valid($input['admin_password'])) {
$errors[] = t('install.error_admin_password');
} else if (!hash_equals($input['admin_password'], $input['admin_password_confirmation'])) {
$errors[] = t('install.error_admin_password_mismatch');
}
return $errors;
}
function install_connect($dsn, $username, $password) {
return new PDO($dsn, $username, $password, array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => FALSE));
}
function install_database_dsn($input) {
return 'mysql:host='.$input['db_host'].';port='.$input['db_port']
.';dbname='.$input['db_name'].';charset=utf8mb4';
}
function install_import_schema($connection) {
$statements = install_schema_statements();
if ($statements === FALSE) {
return array('status' => 'schema_unreadable');
}
$existing = $connection->query('SHOW TABLES LIKE \'pgit_%\'')->fetchAll(PDO::FETCH_COLUMN);
if (!empty($existing)) {
return array('status' => 'schema_present', 'tables' => count($existing));
}
try {
foreach ($statements as $statement) {
$connection->exec($statement);
}
} catch (PDOException $exception) {
$driver_code = isset($exception->errorInfo[1]) ? (int) $exception->errorInfo[1] : 0;
if ($driver_code === 1142 || $driver_code === 1044) {
return array('status' => 'schema_denied');
}
throw $exception;
}
return array('status' => 'schema_imported', 'tables' => count($statements));
}
/* SHOW GRANTS output is awkward to parse reliably, so DELETE is confirmed with a
statement that matches no rows but still requires the privilege. */
function install_verify_delete_privilege($connection) {
try {
$connection->exec('DELETE FROM pgit_users WHERE 1 = 0');
return TRUE;
} catch (PDOException $exception) {
return FALSE;
}
}
function install_create_administrator($connection, $username, $password) {
$statement = $connection->prepare(
'SELECT id FROM pgit_users WHERE username = ? LIMIT 1');
$statement->execute(array($username));
if ($statement->fetch() !== FALSE) {
return 'administrator_exists';
}
$statement = $connection->prepare(
'INSERT INTO pgit_users (username, password_hash) VALUES (?, ?)');
$statement->execute(array($username, password_hash($password, PASSWORD_DEFAULT)));
return 'administrator_created';
}
function install_config_contents($input) {
$administrators = " ".var_export($input['admin_username'], TRUE).",\n";
$secure_cookie = $input['session_cookie_secure']
? " 'session_cookie_secure' => TRUE,\n" : '';
return "<?php\n\n"
."/* Generated by install.php. See config.php.sample for every option. */\n\n"
."\$url_base = ".var_export($input['url_base'], TRUE).";\n"
."\$language = ".var_export($input['language'], TRUE).";\n\n"
."\$auth = array(\n"
." 'enabled' => TRUE,\n"
." 'registration_enabled' => ".($input['registration_enabled'] ? 'TRUE' : 'FALSE').",\n"
.$secure_cookie
." 'administrators' => array(\n"
.$administrators
." ),\n"
." 'database' => array(\n"
." 'dsn' => ".var_export(install_database_dsn($input), TRUE).",\n"
." 'username' => ".var_export($input['db_user'], TRUE).",\n"
." 'password' => ".var_export($input['db_password'], TRUE)."));\n\n"
."\$managed_repositories = array(\n"
." 'options' => array(\n"
." 'read' => TRUE,\n"
." 'push' => TRUE,\n"
." 'branches' => TRUE,\n"
." 'tags' => TRUE,\n"
." 'other_refs' => FALSE,\n"
." 'allow_non_fast_forward' => FALSE,\n"
." 'max_object_bytes' => 268435456,\n"
." 'max_pack_objects' => 100000,\n"
." 'max_request_bytes' => 0));\n\n"
."\$repos = array(\n"
." array('/php-git-server.git', '.git', array(\n"
." 'read' => TRUE,\n"
." 'push' => FALSE,\n"
." 'owner' => NULL,\n"
." 'private' => FALSE)),\n"
." );\n";
}
/* Exclusive creation keeps a second concurrent installer from overwriting a
configuration that was just written. */
function install_write_config($input) {
$path = install_config_path();
$handle = @fopen($path, 'xb');
if ($handle === FALSE) {
return FALSE;
}
$contents = install_config_contents($input);
$written = fwrite($handle, $contents);
fclose($handle);
if ($written !== strlen($contents)) {
@unlink($path);
return FALSE;
}
@chmod($path, 0600);
return TRUE;
}
function install_run($input) {
$steps = array();
try {
$connection = install_connect(
install_database_dsn($input), $input['db_user'], $input['db_password']);
$steps[] = array('success', t('install.step_connected'));
$import = install_import_schema($connection);
if ($import['status'] === 'schema_unreadable') {
return array('errors' => array(t('install.error_schema_unreadable')), 'steps' => $steps);
}
if ($import['status'] === 'schema_denied') {
return array(
'errors' => array(t('install.error_schema_denied')),
'steps' => $steps);
}
$steps[] = $import['status'] === 'schema_imported'
? array('success', t('install.step_schema_imported', array('count' => $import['tables'])))
: array('success', t('install.step_schema_present'));
if (!install_verify_delete_privilege($connection)) {
return array(
'errors' => array(t('install.error_delete_privilege')),
'steps' => $steps);
}
$steps[] = array('success', t('install.step_privileges_ok'));
$administrator = install_create_administrator(
$connection, $input['admin_username'], $input['admin_password']);
$steps[] = $administrator === 'administrator_created'
? array('success', t('install.step_admin_created', array('name' => $input['admin_username'])))
: array('success', t('install.step_admin_promoted', array('name' => $input['admin_username'])));
} catch (PDOException $exception) {
return array(
'errors' => array(t('install.error_database', array('message' => $exception->getMessage()))),
'steps' => $steps);
}
if (!install_write_config($input)) {
return array(
'errors' => array(t('install.error_config_write')),
'steps' => $steps);
}
$steps[] = array('success', t('install.step_config_written'));
return array('errors' => array(), 'steps' => $steps, 'complete' => TRUE);
}
function install_send_head() {
echo <<<'HTML'
<!DOCTYPE html>
<html lang="__LANG__">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>__TITLE__</title>
<style>
:root { color-scheme: light dark; --canvas:#f3f7f5;--surface:#fff;--surface-soft:#f7faf8;--ink:#17231d;--muted:#63736a;--line:#d9e4dd;--accent:#167447;--accent-strong:#0d5a34;--accent-soft:#e8f5ed;--danger:#b23b3b;--warning:#9a6b12;--link:#0d658f;--shadow:0 18px 46px rgba(25,59,42,.09); }
* { box-sizing:border-box; } html { background:var(--canvas); } body { width:min(54rem,calc(100% - 2rem));margin:0 auto;padding:3.5rem 0;color:var(--ink);background:transparent;font-family:Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI","Noto Sans CJK SC",sans-serif;line-height:1.6; } body::before { position:fixed;z-index:-1;inset:0;content:"";background:radial-gradient(circle at 7% 0%,#dcf1e5 0,transparent 28rem),radial-gradient(circle at 96% 7%,#e0f1f8 0,transparent 27rem),var(--canvas); }
h1 { margin:0;font-size:clamp(1.75rem,4vw,2.35rem);line-height:1.15;letter-spacing:-.045em; } h1::before { display:inline-grid;width:2.3rem;height:2.3rem;place-items:center;margin-right:.7rem;content:"⌘";border-radius:.68rem;color:#fff;background:var(--accent);font-size:1.38rem;vertical-align:-.18em;box-shadow:0 7px 18px rgba(22,116,71,.24); } h2 { margin:2rem 0 .6rem;font-size:1.15rem;letter-spacing:-.02em; } p { margin:0 0 1rem; }.language-switcher { display:inline-flex;margin:.8rem 0 1.5rem;padding:.25rem .5rem;border:1px solid var(--line);border-radius:999px;background:rgba(255,255,255,.6);font-size:.82rem; }.language-switcher a,a { color:var(--link); }.lead { margin:0 0 1.4rem;padding:1.1rem 1.2rem;border:1px solid #cde3d5;border-radius:.75rem;color:#315340;background:var(--accent-soft); }
form { padding:1.35rem;border:1px solid var(--line);border-radius:.9rem;background:var(--surface);box-shadow:var(--shadow); } fieldset { margin:0 0 1.1rem;padding:1.15rem;border:1px solid var(--line);border-radius:.7rem;background:var(--surface-soft); } legend { padding:0 .45rem;color:var(--ink);font-weight:800; }.grid { display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.95rem; } label { display:block;margin-bottom:.35rem;color:#304239;font-size:.85rem;font-weight:800; } input[type="text"],input[type="password"],input[type="number"] { width:100%;min-height:2.65rem;padding:.52rem .7rem;border:1px solid #bbcbbf;border-radius:.52rem;background:#fff;color:var(--ink);font:inherit;transition:border-color .15s,box-shadow .15s; } input:focus { border-color:var(--accent);outline:0;box-shadow:0 0 0 3px rgba(22,116,71,.16); }.check { display:flex;align-items:flex-start;gap:.55rem;margin-top:.9rem; }.check input { margin-top:.32rem;accent-color:var(--accent); }.check label { margin:0;font-weight:600; }.hint { margin:.35rem 0 0;color:var(--muted);font-size:.84rem; }button { min-height:2.7rem;padding:.55rem 1.35rem;border:1px solid var(--accent-strong);border-radius:.52rem;color:#fff;background:var(--accent);font:inherit;font-weight:800;cursor:pointer;box-shadow:0 2px 4px rgba(13,90,52,.15);transition:transform .15s,background .15s,box-shadow .15s; }button:hover { background:var(--accent-strong);box-shadow:0 5px 12px rgba(13,90,52,.2);transform:translateY(-1px); }button:focus-visible { outline:3px solid #79c99d;outline-offset:2px; }.notice { margin:0 0 1rem;padding:.78rem 1rem;border:1px solid;border-left:.32rem solid;border-radius:.55rem;font-weight:600; }.notice-success { border-color:#a7d9b9;border-left-color:var(--accent);background:var(--accent-soft);color:#155735; }.notice-error { border-color:#f1c5c5;border-left-color:var(--danger);background:#fff1f1;color:#852b2b; }.notice-warning { border-color:#ebd39c;border-left-color:var(--warning);background:#fff7e6;color:#6d4c11; }ul { margin:0 0 1rem;padding-left:1.2rem; }code { padding:.07rem .25rem;border-radius:.24rem;background:#edf3ef;font-size:.9em;word-break:break-all;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; }pre { padding:.85rem 1rem;overflow-x:auto;border:1px solid var(--line);border-radius:.62rem;background:#f5f8f6; }pre code { padding:0;background:transparent; }
@media (max-width:40rem) { body { width:min(100% - 1.25rem,54rem);padding-top:2rem; }h1::before { display:none; }.grid { grid-template-columns:1fr; }form { padding:1.05rem; }fieldset { padding:1rem; }button { width:100%; } }
@media (prefers-color-scheme:dark) { :root { --canvas:#101916;--surface:#17231e;--surface-soft:#1d2b25;--ink:#e5efe8;--muted:#a0b2a8;--line:#31443a;--accent:#42a76d;--accent-strong:#2d8953;--accent-soft:#173b27;--danger:#d05a5a;--warning:#e0ad50;--link:#75c4eb;--shadow:0 18px 46px rgba(0,0,0,.22); }body::before { background:radial-gradient(circle at 7% 0%,#173e2a 0,transparent 28rem),radial-gradient(circle at 96% 7%,#163744 0,transparent 27rem),var(--canvas); }h1::before { color:#102319; }.language-switcher { background:rgba(23,35,30,.62); }label { color:#d5e2d9; }fieldset { background:var(--surface-soft); }input[type="text"],input[type="password"],input[type="number"] { border-color:#587064;background:#132019;color:var(--ink); }code { background:#22332b; }pre { background:#1b2a23; }.lead { border-color:#356d4b;color:#b7dfc4; }.notice-success { border-color:#356d4b;color:#a9e5bd; }.notice-error { border-color:#713838;background:#3a2020;color:#ffb6b6; }.notice-warning { border-color:#745b27;background:#3e3218;color:#f1d48e; } }
</style>
</head>
<body>
<h1>__INSTALL_HEADING__</h1>
HTML;
echo i18n_language_switcher(install_page_url())."\n";
}
function install_send_form($input, $errors) {
$token = install_csrf_token();
if ($token === FALSE) {
echo '<p class="notice notice-error">'.install_escape(t('install.session_unavailable')).'</p>' ."\n";
return;
}
echo '<p class="lead">'.t('install.lead').'</p>' ."\n";
if (!install_request_is_https()) {
echo '<p class="notice notice-warning">'.t('install.warning_http').'</p>' ."\n";
}
if (!extension_loaded('pdo_mysql')) {
echo '<p class="notice notice-error">'.t('install.error_no_pdo_mysql').'</p>' ."\n";
}
if (!is_writable(__DIR__)) {
echo '<p class="notice notice-error">'.t('install.error_not_writable').'</p>' ."\n";
}
if (!empty($errors)) {
echo '<div class="notice notice-error"><ul>' ."\n";
foreach ($errors as $error) {
echo '<li>'.install_escape($error).'</li>' ."\n";
}
echo '</ul></div>' ."\n";
}
echo '<form method="post" action="'.install_escape(install_page_url()).'">' ."\n";
echo '<input type="hidden" name="csrf_token" value="'.install_escape($token).'">' ."\n";
echo '<fieldset><legend>'.install_escape(t('install.legend_application')).'</legend><div class="grid">' ."\n";
echo '<div><label for="url_base">'.install_escape(t('install.label_url_base')).'</label>'
.'<input id="url_base" name="url_base" type="text" value="'
.install_escape($input['url_base']).'" placeholder="/php-git-server">'
.'<p class="hint">'.t('install.hint_url_base').'</p></div>' ."\n";
echo '<div><label for="language">'.install_escape(t('install.label_language')).'</label>'
.'<select id="language" name="language">'
.'<option value=""'.($input['language'] === '' ? ' selected' : '').'>'
.install_escape(t('install.language_auto')).'</option>'
.'<option value="en"'.($input['language'] === 'en' ? ' selected' : '').'>'.install_escape(t('install.language_en')).'</option>'
.'<option value="zh"'.($input['language'] === 'zh' ? ' selected' : '').'>'.install_escape(t('install.language_zh')).'</option>'
.'</select></div>' ."\n";
echo '</div><div class="check"><input id="registration_enabled" name="registration_enabled" '
.'type="checkbox" value="1"'.($input['registration_enabled'] ? ' checked' : '').'>'
.'<label for="registration_enabled">'.install_escape(t('install.label_registration_enabled')).'</label></div>' ."\n";
echo '<div class="check"><input id="session_cookie_secure" name="session_cookie_secure" '
.'type="checkbox" value="1"'.($input['session_cookie_secure'] ? ' checked' : '').'>'
.'<label for="session_cookie_secure">'.install_escape(t('install.label_session_cookie_secure')).'</label>'
.'</div></fieldset>' ."\n";
echo '<fieldset><legend>'.install_escape(t('install.legend_database')).'</legend>' ."\n";
echo '<p class="hint">'.t('install.hint_database').'</p>' ."\n";
echo '<div class="grid">' ."\n";
echo '<div><label for="db_host">'.install_escape(t('install.label_db_host')).'</label><input id="db_host" name="db_host" type="text" '
.'value="'.install_escape($input['db_host']).'" required>'
.'<p class="hint">'.t('install.hint_db_host').'</p></div>' ."\n";
echo '<div><label for="db_port">'.install_escape(t('install.label_db_port')).'</label><input id="db_port" name="db_port" '
.'type="number" min="1" max="65535" value="'.install_escape($input['db_port'])
.'" required></div>' ."\n";
echo '<div><label for="db_name">'.install_escape(t('install.label_db_name')).'</label><input id="db_name" name="db_name" '
.'type="text" value="'.install_escape($input['db_name']).'" required>'
.'<p class="hint">'.t('install.hint_db_name').'</p></div>' ."\n";
echo '<div><label for="db_user">'.install_escape(t('install.label_db_user')).'</label><input id="db_user" name="db_user" '
.'type="text" value="'.install_escape($input['db_user']).'" required></div>' ."\n";
echo '<div><label for="db_password">'.install_escape(t('install.label_db_password')).'</label><input id="db_password" '
.'name="db_password" type="password" autocomplete="new-password" required></div>' ."\n";
echo '</div>' ."\n";
echo '<p class="hint">'.t('install.hint_schema_import').'</p>' ."\n";
echo '</fieldset>' ."\n";
echo '<fieldset><legend>'.install_escape(t('install.legend_administrator')).'</legend>' ."\n";
echo '<p class="hint">'.t('install.hint_administrator').'</p>' ."\n";
echo '<div class="grid">' ."\n";
echo '<div><label for="admin_username">'.install_escape(t('install.label_admin_username')).'</label><input id="admin_username" '
.'name="admin_username" type="text" minlength="3" maxlength="64" value="'
.install_escape($input['admin_username']).'" autocomplete="off" required></div>' ."\n";
echo '<div><label for="admin_password">'.install_escape(t('install.label_admin_password')).'</label><input id="admin_password" '
.'name="admin_password" type="password" minlength="8" maxlength="72" '
.'autocomplete="new-password" required></div>' ."\n";
echo '<div><label for="admin_password_confirmation">'.install_escape(t('install.label_admin_password_confirmation')).'</label>'
.'<input id="admin_password_confirmation" name="admin_password_confirmation" '
.'type="password" minlength="8" maxlength="72" autocomplete="new-password" required>'
.'</div>' ."\n";
echo '</div></fieldset>' ."\n";
echo '<button type="submit">'.install_escape(t('install.button_submit')).'</button>' ."\n";
echo '</form>' ."\n";
}
function install_send_result($steps) {
echo '<p class="notice notice-success">'.install_escape(t('install.complete')).'</p>' ."\n";
foreach ($steps as $step) {
echo '<p class="notice notice-'.install_escape($step[0]).'">'
.install_escape($step[1]).'</p>' ."\n";
}
echo '<h2>'.install_escape(t('install.next_steps_title')).'</h2>' ."\n";
echo '<p>'.install_escape(t('install.next_steps_remove')).'</p>' ."\n";
echo '<pre><code>rm install.php</code></pre>' ."\n";
echo '<p>'.t('install.next_steps_shared_hosting').'</p>' ."\n";
echo '<p>'.t('install.next_steps_permissions').'</p>' ."\n";
echo '<p><a href="'.install_escape(install_home_url()).'">'.install_escape(t('install.link_home')).'</a></p>' ."\n";
}
function install_send_foot() {
echo '</body>' ."\n".'</html>' ."\n";
}
if (install_is_complete()) {
send_error(
403,
'Forbidden',
'Installation is already complete. Remove install.php, or delete config.php to reinstall.');
}
require(__DIR__.'/lib/auth.php');
/* Session must be started before any output so the cookie can be set. */
install_start_session();
ob_start('i18n_translate_markup');
header_nocache();
header('Content-Type: text/html; charset=utf-8');
header('X-Content-Type-Options: nosniff');
header('Content-Security-Policy: default-src \'none\'; style-src \'unsafe-inline\'; '
.'form-action \'self\'; base-uri \'none\'; frame-ancestors \'none\'');
$method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
if ($method !== 'GET' && $method !== 'HEAD' && $method !== 'POST') {
send_status(405, 'Method Not Allowed');
header('Allow: GET, HEAD, POST');
header('Content-Type: text/plain; charset=utf-8');
echo 'Method Not Allowed';
die();
}
$input = array(
'url_base' => rtrim(str_replace('\\', '/', dirname(install_page_url())), '/'),
'registration_enabled' => TRUE,
'session_cookie_secure' => FALSE,
'language' => '',
'db_host' => '127.0.0.1',
'db_port' => '3306',
'db_name' => 'php_git_server',
'db_user' => 'php_git_server',
'db_password' => '',
'admin_username' => '',
'admin_password' => '',
'admin_password_confirmation' => '');
if ($method !== 'POST') {
install_send_head();
install_send_form($input, array());
install_send_foot();
die();
}
if (!request_content_type_is(
get_request_header('Content-Type'), 'application/x-www-form-urlencoded')) {
send_error(415, 'Unsupported Media Type', 'Expected a form-encoded request.');
}
$expected_token = install_csrf_token();
if ($expected_token === FALSE
|| !hash_equals($expected_token, install_post_value('csrf_token'))) {
send_error(403, 'Forbidden', 'The form security token is invalid.');
}
$input = array(
'url_base' => rtrim(trim(install_post_value('url_base')), '/'),
'registration_enabled' => install_post_checked('registration_enabled'),
'session_cookie_secure' => install_post_checked('session_cookie_secure'),
'language' => install_post_value('language'),
'db_host' => trim(install_post_value('db_host')),
'db_port' => trim(install_post_value('db_port')),
'db_name' => trim(install_post_value('db_name')),
'db_user' => trim(install_post_value('db_user')),
'db_password' => install_post_value('db_password'),
'admin_username' => trim(install_post_value('admin_username')),
'admin_password' => install_post_value('admin_password'),
'admin_password_confirmation' => install_post_value('admin_password_confirmation'));
$errors = install_validate($input);
if (!extension_loaded('pdo_mysql')) {
$errors[] = t('install.error_pdo_mysql_missing');
}
install_send_head();
if (!empty($errors)) {
install_send_form($input, $errors);
install_send_foot();
die();
}
$result = install_run($input);
if (empty($result['errors'])) {
install_send_result($result['steps']);
} else {
foreach ($result['steps'] as $step) {
echo '<p class="notice notice-'.install_escape($step[0]).'">'
.install_escape($step[1]).'</p>' ."\n";
}
install_send_form($input, $result['errors']);
}
install_send_foot();