196 lines
5.2 KiB
PHP
196 lines
5.2 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Fonctions utilitaires pour MH Wilds - Partage de Quêtes à Couronnes
|
||
|
*/
|
||
|
|
||
|
// Empêcher l'accès direct à ce fichier
|
||
|
if (!defined('SECURE_ACCESS')) {
|
||
|
header('HTTP/1.0 403 Forbidden');
|
||
|
exit;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sécuriser une chaîne pour l'affichage
|
||
|
*
|
||
|
* @param string $string Chaîne à sécuriser
|
||
|
* @return string Chaîne sécurisée
|
||
|
*/
|
||
|
function secure_output($string) {
|
||
|
return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Rediriger vers une URL
|
||
|
*
|
||
|
* @param string $url URL de destination
|
||
|
*/
|
||
|
function redirect($url) {
|
||
|
header("Location: $url");
|
||
|
exit;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Vérifier si l'utilisateur est connecté
|
||
|
*
|
||
|
* @return bool L'utilisateur est-il connecté
|
||
|
*/
|
||
|
function is_logged_in() {
|
||
|
return isset($_SESSION['admin_authenticated']) && $_SESSION['admin_authenticated'] === true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Vérifier que l'utilisateur est connecté ou rediriger vers la page de connexion
|
||
|
*/
|
||
|
function require_login() {
|
||
|
if (!is_logged_in()) {
|
||
|
set_flash_message('error', 'Vous devez être connecté pour accéder à cette page.');
|
||
|
redirect('login.php');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Définir un message flash dans la session
|
||
|
*
|
||
|
* @param string $type Type de message ('success', 'error', 'info', 'warning')
|
||
|
* @param string $message Contenu du message
|
||
|
*/
|
||
|
function set_flash_message($type, $message) {
|
||
|
$_SESSION['flash_message'] = [
|
||
|
'type' => $type,
|
||
|
'message' => $message
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Récupérer et effacer un message flash de la session
|
||
|
*
|
||
|
* @return array|null Message flash ou null
|
||
|
*/
|
||
|
function get_flash_message() {
|
||
|
if (isset($_SESSION['flash_message'])) {
|
||
|
$message = $_SESSION['flash_message'];
|
||
|
unset($_SESSION['flash_message']);
|
||
|
return $message;
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Afficher un message flash s'il existe
|
||
|
*/
|
||
|
function display_flash_message() {
|
||
|
$flash = get_flash_message();
|
||
|
if ($flash) {
|
||
|
$type = $flash['type'];
|
||
|
$message = $flash['message'];
|
||
|
|
||
|
// Convertir le type en classe Bootstrap
|
||
|
$class = 'alert-info';
|
||
|
if ($type === 'error') {
|
||
|
$class = 'alert-danger';
|
||
|
} elseif ($type === 'success') {
|
||
|
$class = 'alert-success';
|
||
|
} elseif ($type === 'warning') {
|
||
|
$class = 'alert-warning';
|
||
|
}
|
||
|
|
||
|
echo "<div class='alert $class alert-dismissible fade show' role='alert'>";
|
||
|
echo secure_output($message);
|
||
|
echo "<button type='button' class='btn-close' data-bs-dismiss='alert' aria-label='Fermer'></button>";
|
||
|
echo "</div>";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Formater une date relative (aujourd'hui, hier, il y a X jours)
|
||
|
*
|
||
|
* @param string $date Date au format ISO ou timestamp
|
||
|
* @return string Date relative formatée
|
||
|
*/
|
||
|
function format_relative_date($date) {
|
||
|
if (is_numeric($date)) {
|
||
|
$timestamp = $date;
|
||
|
} else {
|
||
|
$timestamp = strtotime($date);
|
||
|
}
|
||
|
|
||
|
$now = time();
|
||
|
$diff = $now - $timestamp;
|
||
|
$day_diff = floor($diff / 86400);
|
||
|
|
||
|
if ($day_diff == 0) {
|
||
|
return "Aujourd'hui";
|
||
|
} else if ($day_diff == 1) {
|
||
|
return "Hier";
|
||
|
} else if ($day_diff < 7) {
|
||
|
return "Il y a $day_diff jours";
|
||
|
} else {
|
||
|
return date('d/m/Y', $timestamp);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Compter les quêtes pour un monstre
|
||
|
*
|
||
|
* @param int $monster_id ID du monstre
|
||
|
* @param string|null $crown_type Type de couronne (null pour toutes)
|
||
|
* @return int Nombre de quêtes
|
||
|
*/
|
||
|
function count_quests_for_monster($monster_id, $crown_type = null) {
|
||
|
$db = get_db_connection();
|
||
|
|
||
|
if ($crown_type === null) {
|
||
|
$stmt = $db->prepare('SELECT COUNT(*) as count FROM quests WHERE monster_id = :monster_id');
|
||
|
$stmt->bindParam(':monster_id', $monster_id, PDO::PARAM_INT);
|
||
|
} else {
|
||
|
$stmt = $db->prepare('SELECT COUNT(*) as count FROM quests WHERE monster_id = :monster_id AND crown_type = :crown_type');
|
||
|
$stmt->bindParam(':monster_id', $monster_id, PDO::PARAM_INT);
|
||
|
$stmt->bindParam(':crown_type', $crown_type);
|
||
|
}
|
||
|
|
||
|
$stmt->execute();
|
||
|
$result = $stmt->fetch(PDO::FETCH_ASSOC);
|
||
|
return $result['count'];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Générer les statistiques globales
|
||
|
*
|
||
|
* @return array Tableau de statistiques
|
||
|
*/
|
||
|
function get_site_statistics() {
|
||
|
$db = get_db_connection();
|
||
|
|
||
|
// Compter les monstres
|
||
|
$stmt = $db->query('SELECT COUNT(*) as count FROM monsters');
|
||
|
$monsters_count = $stmt->fetch(PDO::FETCH_ASSOC)['count'];
|
||
|
|
||
|
// Récupérer les statistiques de quêtes
|
||
|
$quests_stats = count_quests_by_crown_type();
|
||
|
|
||
|
return [
|
||
|
'total_monsters' => $monsters_count,
|
||
|
'total_quests' => $quests_stats['total_quests'],
|
||
|
'small_crown_quests' => $quests_stats['small_crown_quests'],
|
||
|
'large_crown_quests' => $quests_stats['large_crown_quests']
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Vérifier si une URL d'image est valide
|
||
|
*
|
||
|
* @param string $url URL de l'image
|
||
|
* @return bool L'URL est-elle valide
|
||
|
*/
|
||
|
function is_valid_image_url($url) {
|
||
|
// Vérifier si l'URL commence par le dossier d'images
|
||
|
if (strpos($url, 'assets/img/') !== 0) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Vérifier l'extension de l'image
|
||
|
$valid_extensions = ['jpg', 'jpeg', 'png', 'gif'];
|
||
|
$extension = strtolower(pathinfo($url, PATHINFO_EXTENSION));
|
||
|
|
||
|
return in_array($extension, $valid_extensions);
|
||
|
}
|