<?php
declare(strict_types = 1);

/**
 * Installation de l'application.
 *
 * @license https://www.gnu.org/licenses/gpl-3.0.html
 * @link https://www.igalerie.org/
 */
require_once(__DIR__ . '/../includes/prepend.php');

// Initialisation.
Template::init();
Install::start();
Template::start();
$tpl =& Template::$data;



/**
 * Gestion de l'installation.
 *
 */
class Install
{
	/**
	 * Démarrage de l'installation.
	 *
	 * @return void
	 */
	public static function start(): void
	{
		// Paramètres de configuration.
		Config::$params = Config::getDBParamDefault();

		// Localisation.
		$langs = [];
		foreach (Config::$params['lang_params']['langs'] as $code => &$name)
		{
			$langs[$code] = ['code' => $code, 'name' => $name];
		}
		Config::$params['lang_switch'] = 1;
		L10N::locale($_POST['lang'] ?? Auth::$prefs->read('lang'));
		Template::set('lang', str_replace('_', '-', Auth::$lang));
		Template::set('lang_switch', $langs);
		Config::$params['lang_default'] = Auth::$lang;
		Config::$params['tz_default'] = Auth::$tz;

		// Paramètres de base.
		Template::set('installed', defined('CONF_KEY'));
		if (defined('CONF_KEY'))
		{
			return;
		}
		define('CONF_KEY', Security::key(62));
		define('CONF_PASSWORD_PEPPER', Security::key(62));
		Template::set('requirements', FALSE);

		// Drivers PDO disponibles.
		$pdo_drivers = PDO::getAvailableDrivers();

		// Nettoyage des données.
		$_POST = array_map('trim', $_POST);

		// Paramètres de template.
		$db_types = ['sqlite', 'mysql', 'pgsql'];
		foreach ($db_types as $type)
		{
			${'is_' . $type} = in_array($type, $pdo_drivers);
			if (${'is_' . $type} && empty($_POST['db_type']))
			{
				$_POST['db_type'] = $type;
			}
			Template::set($type, ${'is_' . $type});
			Template::set('post',
			[
				'db_' . $type => isset($_POST['db_type']) && $_POST['db_type'] == $type
			]);
		}
		Template::set('post',
		[
			'db_name' => $_POST['db_name'] ?? '',
			'db_pass' => $_POST['db_pass'] ?? '',
			'db_pref' => $_POST['db_pref'] ?? 'igal3_',
			'db_host' => $_POST['db_host'] ?? '',
			'db_port' => $_POST['db_port'] ?? '',
			'db_user' => $_POST['db_user'] ?? '',
			'email' => $_POST['email'] ?? '',
			'login' => $_POST['login'] ?? '',
			'password' => $_POST['password'] ?? '',
			'password_confirm' => $_POST['password_confirm'] ?? ''
		]);

		// On vérifie que les pilotes et extensions indispensables
		// au fonctionnement de l'application sont chargés.
		if (!$is_sqlite && !$is_mysql && !$is_pgsql)
		{
			Report::warning(__('L\'installation ne peut se poursuivre'
				. ' car aucun pilote de base de données n\'a été trouvé.'));
			return;
		}
		$loaded_extensions = get_loaded_extensions();
		$required_extensions = ['gd', 'iconv', 'mbstring', 'PDO'];
		foreach ($required_extensions as &$ext)
		{
			if (!in_array($ext, $loaded_extensions))
			{
				Report::warning(sprintf(__('L\'installation ne peut se poursuivre'
					. ' car l\'extension %s n\'est pas chargée.'), '"' . $ext . '"'));
				return;
			}
		}

		Template::set('requirements', TRUE);

		// Vérifications du formulaire.
		if (!isset($_POST['db_host']) || strlen($_POST['db_host']) > 128
		 || !isset($_POST['db_port']) || strlen($_POST['db_port']) > 5
		 || !isset($_POST['db_user']) || strlen($_POST['db_user']) > 128
		 || !isset($_POST['db_pass']) || strlen($_POST['db_pass']) > 128
		 || !isset($_POST['db_name']) || strlen($_POST['db_name']) > 128
		 || !isset($_POST['db_pref']) || strlen($_POST['db_pref']) > 32
		 || !isset($_POST['db_type']) || !in_array($_POST['db_type'], $pdo_drivers)
		 || !isset($_POST['login'])
		 || strlen($_POST['login']) > User::COLUMNS_LENGTH_MAX['login']
		 || !isset($_POST['password'])
		 || strlen($_POST['password']) > User::COLUMNS_LENGTH_MAX['password']
		 || !isset($_POST['password_confirm'])
		 || strlen($_POST['password_confirm']) > User::COLUMNS_LENGTH_MAX['password']
		 || !isset($_POST['email'])
		 || strlen($_POST['email']) > User::COLUMNS_LENGTH_MAX['email'])
		{
			return;
		}

		// Chargement de la classe du driver de base de données.
		require_once(GALLERY_ROOT . '/includes/core/dblayer/' . $_POST['db_type'] . '.class.php');

		// Vérification des informations de base de données.
		if ($_POST['db_type'] == 'sqlite')
		{
			// Emplacement de la base de données.
			$db_name = str_replace(DIRECTORY_SEPARATOR, '/', GALLERY_ROOT) . '/db/sqlite.db';
		}
		else
		{
			// Adresse serveur.
			$db_host = $_POST['db_host'];
			$db_port = preg_match('`^\d{1,5}$`', $_POST['db_port'])
				? $_POST['db_port']
				: DB::PORT_DEFAULT;

			// Informations de connexion.
			$db_user = $_POST['db_user'];
			$db_pass = $_POST['db_pass'];

			// Base de données.
			$db_name = $_POST['db_name'];

			// Préfixe des tables.
			$db_pref = $_POST['db_pref'];
			if (!preg_match('`^[a-z0-9_]{0,32}$`i', $db_pref))
			{
				Report::warning(__('Le préfixe des tables ne doit comporter que des'
					. ' caractères alphanumériques ou le caractère de soulignement (_).'));
				return;
			}
		}

		// Constantes de base de données.
		define('CONF_DB_TYPE', $_POST['db_type']);
		define('CONF_DB_USER', $db_user ?? '');
		define('CONF_DB_PASS', $db_pass ?? '');
		define('CONF_DB_HOST', $db_host ?? '');
		define('CONF_DB_PORT', $db_port ?? '');
		define('CONF_DB_NAME', $db_name);
		define('CONF_DB_PREF', $db_pref ?? 'igal3_');
		define('CONF_DB_DATE', 'php');
		define('CONF_DB_TRAN', 1);

		// Les champs du compte super-admin sont obligatoires.
		if (strlen($_POST['login']) < 1 || strlen($_POST['password']) < 1)
		{
			Report::warning(L10N::getText('required_fields'));
			return;
		}

		// Vérification du nom d'utilisateur du compte super-administrateur.
		$r = User::checkLoginFormat($_POST['login']);
		if (is_string($r))
		{
			Report::warning($r);
			return;
		}

		// Vérification du mot de passe du compte super-administrateur.
		$r = User::checkPasswordFormat($_POST['password']);
		if (is_string($r))
		{
			Report::warning($r);
			return;
		}

		// Confirmation du mot de passe du compte super-administrateur.
		if ($_POST['password'] !== $_POST['password_confirm'])
		{
			Report::warning(L10N::getText('password_confirm_error'));
			return;
		}

		// Vérification de l'adresse de courriel du compte super-administrateur.
		$_POST['email'] = Utility::trimAll($_POST['email']);
		if ($_POST['email'] !== '')
		{
			$r = User::checkEmailFormat($_POST['email']);
			if (is_string($r))
			{
				Report::warning($r);
				return;
			}
		}

		// On tente de se connecter à la base de données.
		if ($_POST['db_type'] == 'sqlite')
		{
			if (file_exists($db_name))
			{
				File::unlink($db_name);
			}
		}
		if (!DB::connect())
		{
			Report::error(__('Impossible de se connecter à la base de données.')
				. "\n" . DB::getError());
			return;
		}

		// On vérifie la compatibilité de la version.
		$db_version = preg_replace('`^\D*([\d.]+)\D*.*$`', '$1', DB::$version);
		$min_version = DB::VERSION_MIN;
		if (version_compare($db_version, $min_version, '<'))
		{
			Report::warning(sprintf(__('La version de la base de données (%s) est antérieure'
				. ' à la version requise par l\'application (%s).'), $db_version, $min_version));
			return;
		}

		// Récupération du schéma de la base de données.
		if (($sql_content = SQL::getSchema()) === FALSE)
		{
			Report::error(__('Impossible de lire le fichier SQL.'));
			return;
		}

		// Création des tables.
		if (!self::_createTables($sql_content))
		{
			Report::error(__('Une erreur s\'est produite durant la création des tables.')
				. "\n" . DB::getError());
			return;
		}

		// Chemin de la galerie.
		$gallery_path = App::getGalleryPath();

		// Création du fichier de configuration.
		$config_default_file = GALLERY_ROOT . '/config/conf_default.php';
		$config_file = GALLERY_ROOT . '/config/conf.php';
		if (!File::copy($config_default_file, $config_file))
		{
			Report::error(__('Impossible de créer le fichier de configuration.'));
			return;
		}

		// Modification du fichier .htaccess.
		$htaccess_file = __DIR__ . '/../htaccess';
		if (file_exists($htaccess_file))
		{
			$htaccess_content = File::getContents($htaccess_file);
			if ($htaccess_content !== FALSE)
			{
				$htaccess_content = preg_replace(
					'`#(\s+RewriteBase\s+)/`',
					'$1' . $gallery_path . '/',
					$htaccess_content
				);
				if (!File::putContents($htaccess_file, $htaccess_content))
				{
					Report::error(__('Impossible de modifier le fichier.'));
					return;
				}
			}
			if (!File::rename($htaccess_file, __DIR__ . '/../.htaccess'))
			{
				Report::error(__('Impossible de renommer le fichier.'));
				return;
			}
		}

		// Modification du fichier de configuration.
		$params_db =
		[
			'CONF_DB_USER' => CONF_DB_USER,
			'CONF_DB_PASS' => CONF_DB_PASS,
			'CONF_DB_TYPE' => CONF_DB_TYPE,
			'CONF_DB_HOST' => CONF_DB_HOST,
			'CONF_DB_PORT' => CONF_DB_PORT,
			'CONF_DB_NAME' => CONF_DB_NAME,
			'CONF_DB_PREF' => CONF_DB_PREF,
			'CONF_DB_DATE' => CONF_DB_DATE,
			'CONF_DB_TRAN' => CONF_DB_TRAN
		];
		$params_key =
		[
			'CONF_KEY' => CONF_KEY,
			'CONF_ACCESS_KEY' => Security::key(62),
			'CONF_PASSWORD_PEPPER' => CONF_PASSWORD_PEPPER
		];
		$params_change =
		[
			'CONF_ALBUMS_PATH' => str_replace(DIRECTORY_SEPARATOR, '/', GALLERY_ROOT) . '/albums',
			'CONF_GALLERY_PATH' => $gallery_path
		];
		if (!Config::addFileParams($params_db, 'Base de données.')
		 || !Config::addFileParams($params_key, 'Clés de sécurité (ne jamais modifier).')
		 || !Config::changeFileParams($params_change))
		{
			Report::error(__('Impossible de modifier le fichier de configuration.'));
			return;
		}

		// On supprime les éventuelles erreurs enregistrées.
		foreach (glob(GALLERY_ROOT . '/errors/*.xml') as &$f)
		{
			File::unlink($f);
		}

		// Connexion automatique et redirection vers l'administration.
		Auth::form($_POST['login'], $_POST['password'], TRUE);
		header('Location: ' . GALLERY_HOST . $gallery_path . '/' . CONF_ADMIN_DIR . '/');
		die;
	}



	/**
	 * Création des tables de base de données
	 * et insertion des paramètres de configuration.
	 *
	 * @param array $sql_content
	 *
	 * @return bool
	 */
	private static function _createTables(array $sql_content): bool
	{
		// Création des tables.
		foreach ($sql_content as $n => &$sql)
		{
			if (!DB::execute($sql))
			{
				l($sql);
				return FALSE;
			}
		}

		// Localisation de certains textes.
		$lang_install_file = GALLERY_ROOT . '/locale/' . Auth::$lang . '/install.php';
		if (file_exists($lang_install_file))
		{
			include_once($lang_install_file);
			if (isset($config) && is_array($config))
			{
				foreach ($config as $name => &$value)
				{
					if (array_key_exists($name, Config::$params))
					{
						Config::$params[$name] = (string) $value;
					}
				}
			}
		}

		// Modifications de certains paramètres.
		$db_config = [];
		foreach (Config::$params as $name => &$value)
		{
			switch ($name)
			{
				case 'app_history' :
					$value = sprintf('[{"version":"%s","date":"%s"}]',
						System::APP_VERSION, date('Y-m-d H:i:s'));
					break;

				case 'app_version' :
					$value = System::APP_VERSION;
					break;

				case 'items_resize_type' :
				case 'users_items_resize_type' :
				case 'thumbs_type' :
					$value = 'webp';
					break;

				case 'mail_auto_sender_address' :
					$value = strtolower(System::APP_NAME) . '@' . preg_replace(
						'`^www\.`', '', ($_SERVER['SERVER_NAME'] ?? 'localhost')
					);
					break;

				case 'mail_auto_sender_name' :
					$value = System::APP_NAME;
					break;

				case 'new_version_check' :
					$value = (int) Update::isAllowedHTTPOrigin();
					break;

				case 'pages_params' :
					$value['contact']['email'] = $_POST['email'];
					break;
			}

			$db_config[] = [$name, is_array($value) ? Utility::jsonEncode($value) : $value];
		}

		// Remplissage de la table 'config'.
		$sql = "INSERT INTO {config} (conf_name, conf_value) VALUES (?, ?)";
		if (!DB::execute($sql, $db_config))
		{
			return FALSE;
		}
		$db_config = NULL;

		// Permissions de groupe.
		$perms = Config::USERS_GROUP_PERMS_DEFAULT;
		$perms = Utility::jsonEncode($perms);

		// Enregistrement des trois premiers groupes.
		$sql = "INSERT INTO {groups} (group_name, group_title,
				group_desc, group_crtdt, group_perms, group_admin)
				VALUES ('', '', NULL, NOW(), ?, ?)";
		if (!DB::execute($sql, [[$perms, '1'], [$perms, '0'], [$perms, '0']]))
		{
			return FALSE;
		}

		// Enregistrement des deux premiers utilisateurs.
		$sql = "INSERT INTO {users} (group_id, user_login, user_password,
			    user_email, user_alert, user_lang, user_tz, user_crtdt, user_crtip)
			    VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), ?)";
		$user_alert = $_POST['email'] ? '111111' : '000000';
		$params =
		[
			[1, $_POST['login'], Security::passwordHash($_POST['password']),
				$_POST['email'], $user_alert, Auth::$lang, Auth::$tz, $_SERVER['REMOTE_ADDR']],
			[2, 'guest', Security::passwordHash('pass', $_POST['password']),
				'', '000000', Config::$params['lang_default'], Config::$params['tz_default'], '']
		];
		if (!DB::execute($sql, $params))
		{
			return FALSE;
		}

		// Enregistrement de la première catégorie.
		$sep = Parents::SEPARATOR;
		$sql = "INSERT INTO {categories}
			   (user_id, cat_parents, parent_id, cat_path, cat_name, cat_url, cat_crtdt)
			   VALUES (1, '1$sep', 1, '.', '', '', NOW())";
		if (!DB::execute($sql))
		{
			return FALSE;
		}

		return TRUE;
	}
}
?>
<!DOCTYPE html>
<html lang="<?php echo $tpl['lang']; ?>">

<head>
	<title><?php echo __('Installation'); ?></title>
	<meta charset="utf-8">
	<link rel="stylesheet" type="text/css" media="screen" title="style" href="./../<?php echo CONF_ADMIN_DIR; ?>/template/default/style/default/style.css">
	<meta name="viewport" content="width=device-width">
	<style nonce="<?php echo CSP_NONCE; ?>" type="text/css">
	body
	{
		padding: 0 15px;
		height: auto;
	}
	#installation
	{
		margin-top: 20px;
		width: auto;
		max-width: 32em;
	}
	#installation form
	{
		margin: 30px 10px 10px;
	}
	p.field
	{
		display: flex;
		align-items: center;
	}
	p.field label
	{
		flex: 1;
	}
	p.field input
	{
		margin-left: 10px;
		width: 150px;
	}
	p.field .password_container
	{
		margin: 0 0 -2px 10px;
		width: 160px;
	}
	p.field .password_container input
	{
		margin: 0;
		width: 111px;
	}
	#installation .deactivate *
	{
		color: gray;
	}
	#installed
	{
		margin: 30px 0 60px;
	}
	#welcome
	{
		margin: 0 0 40px 10px;
		font-size: 180%;
		letter-spacing: .05em;
		font-family: Georgia, serif;
		font-style: italic;
		line-height: 1.3em;
	}
	#welcome strong
	{
		display: inline-block;
		color: #333;
	}
	form > p:last-child
	{
		display: flex;
		justify-content: center;
	}
	input[type="submit"]
	{
		margin: 30px 0 40px;
		padding: 8px 10px;
		font-size: 130%;
	}
	input[type="submit"][disabled]
	{
		cursor: not-allowed;
	}
	.report_msg.report_error,
	.report_msg.report_warning
	{
		margin-bottom: 40px;
	}
	#db_nosqlite
	{
		display: none;
	}
	#db_nosqlite.show
	{
		display: block;
	}

	/* Lien du menu des langues */
	#footer_lang
	{
		display: flex;
		justify-content: center;
		margin-bottom: 5px;
	}
	#footer_lang a
	{
		border: 0;
		display: flex;
		align-items: center;
		margin: 0 10px 0 0;
	}
	#footer_lang a:hover,
	#footer_lang a:hover span
	{
		color: black;
	}
	#footer_lang a span
	{
		font-family: "IcoMoon";
		font-size: 170%;
		margin: -1px 5px 0 0;
		color: #333;
	}

	/* Menu des langues */
	#form_lang
	{
		display: none;
	}
	#lang_switch
	{
		position: fixed;
		z-index: 100;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		align-items: center;
		justify-content: center;
		display: none;
	}
	#lang_switch::before
	{
		content: '';
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background: #000;
		opacity: 0.5;
		z-index: 100;
	}
	#lang_switch ul
	{
		max-width: 800px;
		max-height: calc(100% - 30px);
		padding: 15px;
		background: white;
		z-index: 100;
		overflow: auto;
	}
	#lang_switch li
	{
		margin: 10px;
	}
	#lang_switch li a
	{
		padding: 10px;
		padding-right: 25px;
		border: 1px solid silver;
		margin: 0;
		display: flex;
		align-items: center;
		color: #000;
	}
	#lang_switch li a span
	{
		font-family: "Courier New", serif;
		margin: 0 5px;
		top: 1px;
		position: relative;
	}
	#lang_switch li a:hover
	{
		background: #eee;
	}
	#lang_switch li.current
	{
		outline: 2px solid #726256;
	}
	#lang_switch li.current a
	{
		border-color: #726256;
	}
	@media (min-width: 1200px)
	{
		#installation
		{
			width: 560px;
			max-width: 560px;
		}
		#installation form
		{
			margin: 30px 15px 10px 20px;
		}
		p.field input
		{
			width: 200px;
		}
		p.field .password_container
		{
			width: 210px;
		}
		p.field .password_container input
		{
			width: 100%;
		}
		fieldset
		{
			background-size: 100% 1px;
		}
	}
	</style>
	<script type="text/javascript" src="./../js/jquery/jquery.js"></script>
	<script type="text/javascript" src="./../<?php echo CONF_ADMIN_DIR; ?>/template/default/js/admin.js"></script>
</head>

<body>

	<div id="installation">
		<h1><span><?php echo __('Installation'); ?></span></h1>
		<form method="post" action="">
<?php if ($tpl['installed']) : ?>
			<div id="installed">
				<div class="report_classic">
					<div class="report_msg report_info"><p><?php printf(__('%s est déjà installé.'), System::APP_NAME); ?></p></div>
				</div>
			</div>
<?php elseif (isset($tpl['report']['error'])) : ?>
			<div class="report_classic">
				<div class="report_msg report_error"><p><?php echo nl2br($tpl['report']['error']); ?></p></div>
			</div>
<?php else : ?>
<?php if (isset($tpl['report']['warning'])) : ?>
			<div class="report_classic">
				<div class="report_msg report_warning"><p><?php echo nl2br($tpl['report']['warning']); ?></p></div>
			</div>
<?php endif; ?>
			<div id="form"<?php if (!$tpl['requirements']) : ?> class="deactivate"<?php endif; ?>>
<?php if (empty($tpl['report'])) : ?>
<?php if ($tpl['requirements']) : ?>
				<p id="welcome"><?php printf(__('Bienvenue dans l\'installation de %s !'), '<strong>' . System::APP_NAME . ' ' . System::APP_VERSION . '</strong>'); ?></p>
<?php else : ?>
				<br>
<?php endif; ?>
<?php endif; ?>
				<fieldset <?php if (!$tpl['requirements']) : ?>disabled<?php endif; ?>>
					<legend><?php echo __('Base de données'); ?></legend>
					<p class="field">
						<label for="db_type"><?php echo __('Type de base de données :'); ?></label>
						<select id="db_type" name="db_type" autofocus>
<?php if ($tpl['sqlite']) : ?>
							<option value="sqlite"<?php if ($tpl['post']['db_sqlite']) : ?> selected<?php endif; ?>>SQLite</option>
<?php endif; ?>
<?php if ($tpl['mysql']) : ?>
							<option value="mysql"<?php if ($tpl['post']['db_mysql']) : ?> selected<?php endif; ?>>MySQL / MariaDB</option>
<?php endif; ?>
<?php if ($tpl['pgsql']) : ?>
							<option value="pgsql"<?php if ($tpl['post']['db_pgsql']) : ?> selected<?php endif; ?>>PostgreSQL</option>
<?php endif; ?>
						</select>
					</p>
<?php if ($tpl['requirements']) : ?>
					<div id="db_nosqlite"<?php if (!$tpl['post']['db_sqlite']) : ?> class="show"<?php endif; ?>>
						<p class="field">
							<label for="db_host"><?php echo __('Adresse du serveur :'); ?></label>
							<input id="db_host" name="db_host" maxlength="128" type="text" value="<?php echo $tpl['post']['db_host']; ?>">
						</p>
						<p class="field">
							<label for="db_port"><?php echo __('Numéro de port :'); ?></label>
							<input id="db_port" name="db_port" maxlength="5" type="text" value="<?php echo $tpl['post']['db_port']; ?>">
						</p>
						<p class="field">
							<label for="db_user"><?php echo __('Nom d\'utilisateur :'); ?></label>
							<input id="db_user" name="db_user" maxlength="128" type="text" value="<?php echo $tpl['post']['db_user']; ?>">
						</p>
						<p class="field">
							<label for="db_pass"><?php echo __('Mot de passe :'); ?></label>
							<input data-password-view="1" id="db_pass" name="db_pass" maxlength="128" type="password" value="<?php echo $tpl['post']['db_pass']; ?>">
						</p>
						<p class="field">
							<label for="db_name"><?php echo __('Base de données :'); ?></label>
							<input id="db_name" name="db_name" maxlength="128" type="text" value="<?php echo $tpl['post']['db_name']; ?>">
						</p>
						<p class="field">
							<label for="db_pref"><?php echo __('Préfixe des tables :'); ?></label>
							<input id="db_pref" name="db_pref" maxlength="32" type="text" value="<?php echo $tpl['post']['db_pref']; ?>">
						</p>
					</div>
<?php endif; ?>
				</fieldset>
				<fieldset <?php if (!$tpl['requirements']) : ?>disabled<?php endif; ?>>
					<legend><?php echo __('Compte super-administrateur'); ?></legend>
					<p class="field">
						<label for="login"><?php echo __('Nom d\'utilisateur :'); ?></label>
						<input required id="login" name="login" maxlength="<?php echo User::COLUMNS_LENGTH_MAX['login']; ?>" type="text" value="<?php echo $tpl['post']['login']; ?>">
					</p>
					<p class="field">
						<label for="password"><?php printf(__('Mot de passe (%s caractères minimum) :'), User::getPasswordMinLength()); ?></label>
						<input data-password-view="1" required id="password" name="password" maxlength="<?php echo User::COLUMNS_LENGTH_MAX['password']; ?>" type="password" value="<?php echo $tpl['post']['password']; ?>">
					</p>
					<p class="field">
						<label for="password_confirm"><?php echo __('Confirmez le mot de passe :'); ?></label>
						<input data-password-view="1" required id="password_confirm" name="password_confirm" maxlength="<?php echo User::COLUMNS_LENGTH_MAX['password']; ?>" type="password" value="<?php echo $tpl['post']['password_confirm']; ?>">
					</p>
					<p class="field">
						<label for="email"><?php echo __('Courriel (facultatif) :'); ?></label>
						<input id="email" name="email" maxlength="<?php echo User::COLUMNS_LENGTH_MAX['email']; ?>" type="email" value="<?php echo $tpl['post']['email']; ?>">
					</p>
<?php if ($tpl['requirements']) : ?>
					<div class="report_classic">
						<div class="report_msg report_info">
							<p><?php echo __('Votre adresse de courriel n\'est pas indispensable, mais elle sera utile en cas d\'oubli de mot de passe, ainsi que pour les notifications (commentaires, inscriptions, etc.).'); ?></p>
						</div>
					</div>
<?php endif; ?>
				</fieldset>
			</div>
			<p<?php if (!$tpl['requirements']) : ?> class="deactivate"<?php endif; ?>>
				<input name="anticsrf" type="hidden" value="<?php echo $tpl['anticsrf'](); ?>">
				<input name="start" type="submit" value="<?php echo __('Démarrer l\'installation'); ?>"<?php if (!$tpl['requirements']) : ?> disabled<?php endif; ?>>
			</p>
<?php endif; ?>
		</form>
		<footer>
<?php if ($tpl['lang_switch']) : ?>
			<p id="footer_lang">
				<a href="javascript:;"><span>&#xe900;</span><?php echo $tpl['lang_switch'][$tpl['lang']]['name']; ?></a>
			</p>
			<div id="lang_switch">
				<ul>
<?php foreach ($tpl['lang_switch'] as $i) : ?>
					<li<?php if ($i['code'] == $tpl['lang']) : ?> class="current"<?php endif; ?>>
						<a href="javascript:;" data-code="<?php echo $i['code']; ?>">
							<span>[<?php echo $i['code']; ?>]</span>
							<?php echo $i['name']; ?>
						</a>
					</li>
<?php endforeach; ?>
				</ul>
			</div>
<?php endif; ?>
			<p id="footer_system">
				<?php printf(__('Propulsé par %s'), '<a class="ex" href="' . $tpl['app']['website'] . '">' . $tpl['app']['name'] . '</a>'); ?>
			</p>
		</footer>
	</div>

	<br>

<?php $tpl['print']('logs'); ?>

<?php $tpl['print']('errors'); ?>

	<script nonce="<?php echo CSP_NONCE; ?>" type="text/javascript">
	jQuery(function($)
	{
		// Lien sur le titre.
		$('h1 span').css('cursor', 'pointer').click(() => document.location.href = document.URL);

		// Type de base de données.
		$('.deactivate select, .deactivate input').attr('disabled', 'disabled');
		var db_params = function()
		{
			$('#db_nosqlite').show();
			switch ($('#db_type option:selected').val())
			{
				case 'mysql' :
					$('#db_port').val('3306');
					break;

				case 'pgsql':
					$('#db_port').val('5432');
					break;

				case 'sqlite':
					$('#db_nosqlite').hide();
					break;
			}
		};
		$('#db_type').change(function()
		{
			db_params();
		});
		db_params();

		// Menu des langues.
		var anticsrf = "<?php echo $tpl['anticsrf'](); ?>";
		if ($('#lang_switch').is('div'))
		{
			var langs_box_open = false;
			var close_langs = function()
			{
				$('#lang_switch').css('display', 'none');
				langs_box_open = false;
			};
			$('#footer_lang a').click(function()
			{
				$('#lang_switch').css('display', 'flex');
				langs_box_open = true;
				return false;
			});
			$('#lang_switch').click(function()
			{
				close_langs();
			});
			$('#lang_switch ul').click(function(e)
			{
				e.stopPropagation();
			});
			$('#lang_switch li a').click(function()
			{
				$('#installation').append('<form id="form_lang" method="post">'
					+ '<input type="hidden" name="lang" value="' + $(this).attr('data-code') + '">'
					+ '<input type="hidden" name="anticsrf" value="' + anticsrf + '">'
					+ '</form>');
				$('#form_lang').submit();
				return false;
			});
			$(window).keyup(function(e)
			{
				if (langs_box_open && e.keyCode == 27)
				{
					close_langs();
				}
			});
		}
	});
	</script>
</body>

</html>
