Файл: upload/install/index.php
Строк: 144
<?php
// /install/index.php
// ====== НАСТРОЙКИ ======
$required_php = '8.1.0';
$required_ext = ['pdo_mysql', 'mbstring', 'openssl', 'curl', 'json'];
$writable_dirs = [
$_SERVER['DOCUMENT_ROOT'] . '/core',
$_SERVER['DOCUMENT_ROOT'] . '/uploads',
];
$install_sql_path = __DIR__ . '/SQL/install.sql';
$config_path = $_SERVER['DOCUMENT_ROOT'] . '/core/DataADP/config.php';
$installed_lock = $_SERVER['DOCUMENT_ROOT'] . '/core/installed.lock';
require_once $_SERVER['DOCUMENT_ROOT'] . '/core/version.php';
// ====== ВСПОМОГАТЕЛЬНЫЕ ======
function h($s) {
return htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
}
function is_installed() {
global $installed_lock;
return file_exists($installed_lock);
}
// ====== ОПРЕДЕЛЯЕМ ШАГ ======
$step = isset($_GET['step']) ? (int)$_GET['step'] : 1;
if ($step < 1 || $step > 5) $step = 1;
// ====== ШАПКА ======
echo '<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Установка FirstWork</title>
<link rel="stylesheet" href="/install/css/style.css">
</head>
<body>
<div class="wrap">';
// ====== ЗАЩИТА ОТ ПОВТОРНОЙ УСТАНОВКИ ======
if (is_installed()) {
echo '<h2>FirstWork уже установлен</h2>';
echo '<p>Чтобы переустановить систему удалите файлы:<br><br>
<code>core/DataADP/config.php</code><br>
<code>core/installed.lock</code>
</p>
<a class="btn" href="/install">Повторить попытку</a>';
exit;
}
echo '<h1>Установка FirstWork</h1>';
echo '<p class="small">Шаг ' . $step . ' из 5</p>';
// ====== ШАГ 1: ПРИВЕТСТВИЕ ======
if ($step === 1) {
echo '<h2>Добро пожаловать в FirstWork!</h2>';
echo '<p>FirstWork — это современная платформа для фриланс‑проектов и управления задачами.</p>';
echo '<p>Сначала мы поможем вам:</p>
<ul>
<li>проверить серверное окружение</li>
<li>настроить подключение к базе данных</li>
<li>создать администратора системы</li>
</ul>';
echo '<p>Нажмите кнопку ниже, чтобы начать установку.</p>';
echo '<a class="btn" href="?step=2">Начать установку</a>';
}
// ====== ШАГ 2: ЛИЦЕНЗИОННОЕ СОГЛАШЕНИЕ ======
elseif ($step === 2) {
$license_file = $_SERVER['DOCUMENT_ROOT'] . '/LICENSE.txt';
if (!file_exists($license_file)) {
echo '<h2>Ошибка</h2>';
echo '<div class="error">Файл LICENSE.txt не найден. Установка невозможна.</div>';
exit;
}
$license_text = nl2br(h(file_get_contents($license_file)));
echo '<h2>Лицензионное соглашение</h2>';
echo '<div class="lic-box">
<div class="license-box">' . $license_text . '</div>
</div>';
echo '<br><a class="btn" href="?step=3">Я принимаю условия</a>';
// ====== ШАГ 3: ПРОВЕРКА ОКРУЖЕНИЯ ======
} elseif ($step === 3) {
$errors = [];
global $required_php, $required_ext, $writable_dirs;
if (version_compare(PHP_VERSION, $required_php, '<')) {
$errors[] = 'Требуется PHP ' . $required_php . ' или выше. У вас: ' . PHP_VERSION;
}
foreach ($required_ext as $ext) {
if (!extension_loaded($ext)) {
$errors[] = 'Не найдено расширение PHP: <b>' . h($ext) . '</b>';
}
}
foreach ($writable_dirs as $dir) {
if (!is_dir($dir)) {
$errors[] = 'Каталог не найден: <b>' . h($dir) . '</b>';
} elseif (!is_writable($dir)) {
$errors[] = 'Нет прав на запись в каталог: <b>' . h($dir) . '</b>';
}
}
echo '<h2>Проверка окружения</h2>';
if ($errors) {
echo '<div class="error"><b>Обнаружены проблемы:</b><ul>';
foreach ($errors as $e) {
echo '<li>' . $e . '</li>';
}
echo '</ul></div>';
echo '<p>Исправьте указанные проблемы и обновите страницу.</p>';
} else {
echo '<div class="ok">Окружение в порядке, можно продолжать установку.</div>';
echo '<a class="btn" href="?step=4">Перейти к настройке базы данных</a>';
}
// ====== ШАГ 4: НАСТРОЙКА БД + СОЗДАНИЕ СТРУКТУРЫ ======
} elseif ($step === 4) {
global $install_sql_path, $config_path;
$error = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$host = trim($_POST['host'] ?? '');
$user = trim($_POST['user'] ?? '');
$pass = $_POST['password'] ?? '';
$db = trim($_POST['database'] ?? '');
if ($host === '' || $user === '' || $db === '') {
$error = 'Заполните все обязательные поля.';
} elseif (!file_exists($install_sql_path)) {
$error = 'Файл структуры базы не найден: <code>' . h($install_sql_path) . '</code>';
} else {
// Пытаемся подключиться и выполнить install.sql через твой адаптер
try {
if ($version['stade'] == 'Demo') {
$isDemo = true;
} else {
$isDemo = false;
}
// Генерируем временный config для адаптера
$tmp_config = "<?phpn$config = [n" .
" 'host' => '" . addslashes($host) . "',n" .
" 'user' => '" . addslashes($user) . "',n" .
" 'pass' => '" . addslashes($pass) . "',n" .
" 'base' => '" . addslashes($db) . "',n" .
" 'demo' => " . ($isDemo ? 'true' : 'false') . "n" .
"];n" .
"?>";
file_put_contents($config_path, $tmp_config);
require_once $_SERVER['DOCUMENT_ROOT'] . '/core/DataADP/core.php';
// Проверка подключения
dbquery("SELECT 1");
// Выполнение install.sql
$sql = file_get_contents($install_sql_path);
$queries = preg_split('/;s*[rn]+/', $sql);
foreach ($queries as $q) {
$q = trim($q);
if ($q !== '') {
dbquery($q);
}
}
// Перезаписываем config с секретным ключом
$final_config = "<?phpn$config = [n" .
" 'host' => '" . addslashes($host) . "',n" .
" 'user' => '" . addslashes($user) . "',n" .
" 'pass' => '" . addslashes($pass) . "',n" .
" 'base' => '" . addslashes($db) . "',n" .
" 'demo' => " . ($isDemo ? 'true' : 'false') . "n" .
"];n" .
"?>";
file_put_contents($config_path, $final_config);
header("Location: ?step=5");
exit;
} catch (Throwable $e) {
$error = 'Ошибка при подключении или создании структуры: ' . h($e->getMessage());
// Если что-то пошло не так — удаляем временный config
if (file_exists($config_path)) {
unlink($config_path);
}
}
}
}
echo '<h2>Подключение к базе данных</h2>';
if ($error) {
echo '<div class="error">' . $error . '</div>';
}
echo '<form method="post">
<label>Хост базы данных</label>
<input type="text" name="host" required value="' . h($_POST['host'] ?? 'localhost') . '">
<label>Пользователь</label>
<input type="text" name="user" required value="' . h($_POST['user'] ?? '') . '">
<label>Пароль</label>
<input type="password" name="password" value="' . h($_POST['password'] ?? '') . '">
<label>Имя базы данных</label>
<input type="text" name="database" required value="' . h($_POST['database'] ?? '') . '">
<br>
<button type="submit">Продолжить</button>
</form>';
// ====== ШАГ 5: СОЗДАНИЕ АДМИНИСТРАТОРА ======
} elseif ($step === 5) {
global $config_path, $installed_lock;
if (!file_exists($config_path)) {
echo '<div class="error">Файл конфигурации не найден. Сначала выполните шаг 4.</div>';
echo '<a class="btn" href="?step=2">Назад к настройке базы</a>';
echo '</div></body></html>';
exit;
}
require $config_path;
require_once $_SERVER['DOCUMENT_ROOT'] . '/core/DataADP/core.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/core/function.php';
$error = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$login = trim($_POST['login'] ?? '');
$email = trim($_POST['email'] ?? '');
$pass = $_POST['pass'] ?? '';
$rpass = $_POST['r_pass'] ?? '';
if ($login === '' || $email === '' || $pass === '' || $rpass === '') {
$error = 'Заполните все поля.';
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = 'Некорректный email.';
} elseif ($pass !== $rpass) {
$error = 'Пароли не совпадают.';
} else {
try {
$salt = genRandomString(15);
$hash = CryptorPass($pass, $salt);
create_user($login, $hash, $email, $salt, '0', 'local', 'local', '', $config);
dbquery("UPDATE `users` SET `level_us` = '2' WHERE `id` = '1'");
file_put_contents($installed_lock, time());
echo '<h2>Установка завершена</h2>';
echo '<div class="ok">Администратор создан, система установлена.</div>';
echo '<a class="btn" href="/login">Перейти к авторизации</a>';
echo '</div></body></html>';
exit;
} catch (Throwable $e) {
$error = 'Ошибка при создании администратора: ' . h($e->getMessage());
}
}
}
echo '<h2>Создание администратора</h2>';
if ($error) {
echo '<div class="error">' . $error . '</div>';
}
echo '<form method="post">
<label>Логин</label>
<input type="text" name="login" maxlength="32" required value="' . h($_POST['login'] ?? '') . '">
<label>Email</label>
<input type="email" name="email" maxlength="64" required value="' . h($_POST['email'] ?? '') . '">
<label>Пароль</label>
<input type="password" name="pass" required>
<label>Повтор пароля</label>
<input type="password" name="r_pass" required>
<br>
<button type="submit">Завершить установку</button>
</form>';
}
// ====== ФУТЕР ======
echo '</div></body></html>';