<?php
declare(strict_types = 1);

/**
 * Initialisation de l'application.
 *
 * @license https://www.gnu.org/licenses/gpl-3.0.html
 * @link https://www.igalerie.org/
 */

// Permet de supprimer l'affichage de l'erreur "Warning: POST Content-Length of..."
// lors de l'envoi d'un fichier par <input type="file">.
if (ob_get_length())
{
	ob_end_clean();
}

// Vérification de la version de PHP.
if (!function_exists('version_compare')
 || !defined('PHP_VERSION')
 || version_compare(PHP_VERSION, '7.2', '<'))
{
	die('PHP 7.2 or greater is required.');
}

// Gestion du temps d'exécution.
define('START_TIME', microtime(TRUE));
if (function_exists('ignore_user_abort'))
{
	ignore_user_abort(TRUE);
}
if (function_exists('set_time_limit'))
{
	set_time_limit(60);
}

// Constantes de la galerie.
define('GALLERY_ROOT', dirname(__DIR__));
define('GALLERY_HTTPS',
	   in_array(strtolower($_SERVER['HTTPS'] ?? ''), ['on', '1'])
	|| ($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') == 'https'
	|| in_array(strtolower($_SERVER['HTTP_X_FORWARDED_SSL'] ?? ''), ['on', '1'])
	|| $_SERVER['SERVER_PORT'] == 443);
define('GALLERY_HOST', (GALLERY_HTTPS ? 'https://' : 'http://') . ($_SERVER['HTTP_HOST']
	?? ($_SERVER['SERVER_NAME'] . (in_array($_SERVER['SERVER_PORT'], [80, 443])
		? '' : ':' . $_SERVER['SERVER_PORT']))));

// Chargement du fichier de configuration.
if (file_exists(GALLERY_ROOT . '/config/conf.php'))
{
	require_once(GALLERY_ROOT . '/config/conf.php');
}
else
{
	require_once(GALLERY_ROOT . '/config/conf_default.php');
}

// Si la galerie n'est pas installée, on redirige vers le script d'installation.
if (!defined('CONF_KEY'))
{
	function is_install()
	{
		return preg_match('`install/index\.php`i', $_SERVER['SCRIPT_FILENAME'] ?? '')
			|| preg_match('`install/index\.php`i', $_SERVER['SCRIPT_NAME'] ?? '')
			|| preg_match('`install/index\.php`i', $_SERVER['PHP_SELF'] ?? '')
			|| preg_match('`/install/`i', $_SERVER['REQUEST_URI'] ?? '');
	}
	if (!is_install())
	{
		$dir = dirname($_SERVER['SCRIPT_FILENAME']);
		$location = $dir != dirname($dir)
			&& is_dir(dirname($dir) . '/install')
			&& is_file(dirname($dir) . '/install/schema.sql')
			? './../install/'
			: './install/';
		header('Location: ' . $location);
		die;
	}
}

// Chargement automatique des classes du noyau.
spl_autoload_register(function(string $class)
{
	if (!file_exists($file = GALLERY_ROOT . '/includes/core/' . $class . '.class.php'))
	{
		$message = 'Failed opening required file (' . $class . '.class.php).';
		trigger_error($message, E_USER_WARNING);
		die($message);
	}
	require_once($file);
});

// Gestion des erreurs et de la mémoire.
error_reporting(-1);
if (function_exists('ini_set'))
{
	ini_set('memory_limit', '512M');
	ini_set('display_errors', CONF_ERRORS_DISPLAY ? '1' : '0');
}
set_error_handler(['ErrorHandler', 'phpError']);
set_exception_handler(['ErrorHandler', 'exception']);
register_shutdown_function(['ErrorHandler', 'shutdown']);
libxml_use_internal_errors(TRUE);

// Filtrage des paramètres de requête.
Security::filterGET($gets ?? ['q']);

// Jeu de caractères pour les fonctions mbstring.
if (!extension_loaded('mbstring'))
{
	die('mbstring not loaded.');
}
mb_internal_encoding(CONF_CHARSET);
if (function_exists('mb_regex_encoding'))
{
	mb_regex_encoding(CONF_CHARSET);
}

// En-têtes HTTP et gestion des cookies.
Auth::sessionHandler();
header('Content-Type: text/html; charset=' . CONF_CHARSET);

// Gestion du cache.
header('Expires: Wed, 21 Oct 2015 07:28:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', FALSE);

// Sécurité.
define('CSP_NONCE', Security::getCSPNonce());
Security::headers();
Security::antiCSRFToken();



/**
 * Localisation.
 *
 * @param string $str
 *
 * @return string
 */
function __(string $str)
{
	if (isset(L10N::$text[$str]))
	{
		L10N::$text[$str] = trim((string) L10N::$text[$str]);
		$str = L10N::$text[$str] === '' ? $str : L10N::$text[$str];
		$file = str_replace(GALLERY_ROOT, '', (string) debug_backtrace()[0]['file']);
		return strstr($file, 'template') ? htmlspecialchars($str) : $str;
	}
	if (CONF_DEBUG_MODE && Auth::$lang != 'fr')
	{
		trigger_error("Localization not found: \"$str\"", E_USER_NOTICE);
	}
	return $str;
}

/**
 * Débogage.
 *
 * @param mixed $data
 * @param bool $l
 *
 * @return array
 */
function l($data, $l = TRUE)
{
	static $log = [];
	if ($l)
	{
		$log[] = ['trace' => debug_backtrace(), 'data' => $data];
	}
	return $log;
}
?>