Ajout du dossier api avec la géolocalisation automatique des casernes de pompiers

This commit is contained in:
d6soft
2025-05-16 21:03:04 +02:00
parent 69dcff42f8
commit f4f7882963
143 changed files with 24329 additions and 1 deletions

View File

@@ -0,0 +1,379 @@
<?php
declare(strict_types=1);
/**
* Configuration de l'application Geosector
*
* Ce fichier contient la configuration de l'application Geosector pour les trois environnements :
* - Production (app.geosector.fr)
* - Recette (rapp.geosector.fr)
* - Développement (dapp.geosector.fr)
*
* Il inclut les paramètres de base de données, les informations SMTP,
* les clés de chiffrement et les configurations des services externes (Mapbox, Stripe, SMS OVH).
*/
class AppConfig {
private static ?self $instance = null;
private array $headers;
private array $config;
private string $currentHost;
private string $clientIp;
private function __construct() {
// Récupération du host directement depuis SERVER_NAME ou HTTP_HOST
$this->currentHost = $_SERVER['SERVER_NAME'] ?? $_SERVER['HTTP_HOST'] ?? '';
// Récupérer les autres en-têtes pour une utilisation ultérieure si nécessaire
$this->headers = getallheaders();
// Déterminer l'adresse IP du client
$this->clientIp = $this->getClientIpAddress();
$this->initConfig();
$this->validateApp();
}
public static function getInstance(): self {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
private function initConfig(): void {
// Configuration de base commune à tous les environnements
$baseConfig = [
'name' => 'geosector',
'encryption_key' => 'Qga2M8Ov6tyx2fIQRWHQ1U6oMK/bAFdTL7A8VRtiDhk=',
'smtp' => [
'host' => 'barbotte.o2switch.net',
'auth' => true,
'user' => 'noreply@geosector.fr',
'pass' => '@G83^[OMSo^Q',
'secure' => 'ssl',
'port' => 465,
],
'email' => [
'from' => 'noreply@geosector.fr',
'contact' => 'contact@geosector.fr',
'hourly_limit' => 1500, // Limite de 1500 emails/heure comme mentionné dans le cahier des charges
],
'mapbox' => [
'api_key' => '', // À remplir avec la clé API Mapbox
],
'stripe' => [
'api_key' => '', // À remplir avec la clé API Stripe
'webhook_secret' => '', // À remplir avec le secret du webhook Stripe
],
'sms' => [
'provider' => 'ovh', // Comme mentionné dans le cahier des charges
'api_key' => '', // À remplir avec la clé API SMS OVH
'api_secret' => '', // À remplir avec le secret API SMS OVH
],
];
// Configuration PRODUCTION
$this->config['app.geosector.fr'] = array_merge($baseConfig, [
'env' => 'production',
'database' => [
'host' => 'localhost',
'name' => 'geo_app',
'username' => 'geo_app_user_prod',
'password' => 'QO:96-SrHJ6k7-df*?k{4W6m',
],
]);
// Configuration RECETTE
$this->config['rapp.geosector.fr'] = array_merge($baseConfig, [
'env' => 'recette',
'database' => [
'host' => 'localhost',
'name' => 'geo_app',
'username' => 'geo_app_user_rec',
'password' => 'QO:96df*?k-dS3KiO-{4W6m',
],
// Vous pouvez remplacer d'autres paramètres spécifiques à l'environnement de recette ici
]);
// Configuration DÉVELOPPEMENT
$this->config['dapp.geosector.fr'] = array_merge($baseConfig, [
'env' => 'development',
'database' => [
'host' => 'localhost',
'name' => 'geo_app',
'username' => 'geo_app_user_dev',
'password' => '34GOz-X5gJu-oH@Fa3$#Z',
],
// Vous pouvez activer des fonctionnalités de débogage en développement
'debug' => true,
// Configurez des endpoints de test pour Stripe, etc.
'stripe' => [
'api_key' => 'pk_test_...', // Clé de test Stripe
'webhook_secret' => 'whsec_test_...', // Secret de test
],
]);
}
private function validateApp(): void {
// Si l'hôte est vide, utiliser une solution de secours (développement par défaut)
if (empty($this->currentHost)) {
// Journaliser cette situation anormale
error_log("WARNING: No host detected, falling back to development environment");
$this->currentHost = 'dapp.geosector.fr';
}
// Si l'hôte n'existe pas dans la configuration, tenter une correction
if (!isset($this->config[$this->currentHost])) {
// Essayer de faire correspondre avec l'un des hôtes connus
$knownHosts = array_keys($this->config);
foreach ($knownHosts as $host) {
if (strpos($this->currentHost, str_replace(['app.', 'rapp.', 'dapp.'], '', $host)) !== false) {
// Correspondance trouvée, utiliser cette configuration
$this->currentHost = $host;
break;
}
}
// Si toujours pas de correspondance, utiliser l'environnement de développement par défaut
if (!isset($this->config[$this->currentHost])) {
error_log("WARNING: Unknown host '{$this->currentHost}', falling back to development environment");
$this->currentHost = 'dapp.geosector.fr';
}
}
// Journaliser l'environnement détecté
$environment = $this->config[$this->currentHost]['env'] ?? 'unknown';
error_log("INFO: Environment detected: {$environment} (Host: {$this->currentHost}, IP: {$this->clientIp})");
}
/**
* Retourne le type de client (web, mobile, etc.)
*
* @return string Le type de client ou 'unknown' si non défini
*/
public function getClientType(): string {
return $this->headers['X-Client-Type'] ?? $_SERVER['HTTP_X_CLIENT_TYPE'] ?? 'unknown';
}
/**
* Retourne l'identifiant de l'application basé sur l'hôte
*
* @return string L'identifiant de l'application (app.geosector.fr, rapp.geosector.fr, dapp.geosector.fr)
*/
public function getAppIdentifier(): string {
return $this->currentHost;
}
/**
* Retourne l'environnement actuel (production, recette, development)
*
* @return string L'environnement actuel
*/
public function getEnvironment(): string {
return $this->getCurrentConfig()['env'] ?? 'production';
}
/**
* Vérifie si l'application est en mode développement
*
* @return bool True si l'application est en mode développement
*/
public function isDevelopment(): bool {
return $this->getEnvironment() === 'development';
}
/**
* Vérifie si l'application est en mode recette
*
* @return bool True si l'application est en mode recette
*/
public function isRecette(): bool {
return $this->getEnvironment() === 'recette';
}
/**
* Vérifie si l'application est en mode production
*
* @return bool True si l'application est en mode production
*/
public function isProduction(): bool {
return $this->getEnvironment() === 'production';
}
/**
* Retourne la configuration complète de l'environnement actuel
*
* @return array Configuration de l'environnement
*/
public function getCurrentConfig(): array {
return $this->config[$this->currentHost];
}
/**
* Retourne le nom de l'application
*
* @return string Nom de l'application (geosector)
*/
public function getName(): string {
return $this->getCurrentConfig()['name'];
}
/**
* Retourne la configuration de la base de données
*
* @return array Configuration de la base de données
*/
public function getDatabaseConfig(): array {
return $this->getCurrentConfig()['database'];
}
/**
* Retourne la clé de chiffrement
*
* @return string Clé de chiffrement
*/
public function getEncryptionKey(): string {
return $this->getCurrentConfig()['encryption_key'];
}
/**
* Retourne la configuration SMTP
*
* @return array Configuration SMTP
*/
public function getSmtpConfig(): array {
return $this->getCurrentConfig()['smtp'];
}
/**
* Retourne la configuration email
*
* @return array Configuration email
*/
public function getEmailConfig(): array {
return $this->getCurrentConfig()['email'];
}
/**
* Retourne la configuration Mapbox
*
* @return array Configuration Mapbox
*/
public function getMapboxConfig(): array {
return $this->getCurrentConfig()['mapbox'];
}
/**
* Retourne la configuration Stripe
*
* @return array Configuration Stripe
*/
public function getStripeConfig(): array {
return $this->getCurrentConfig()['stripe'];
}
/**
* Retourne la configuration SMS
*
* @return array Configuration SMS
*/
public function getSmsConfig(): array {
return $this->getCurrentConfig()['sms'];
}
/**
* Retourne si le mode debug est activé
*
* @return bool True si le mode debug est activé
*/
public function isDebugEnabled(): bool {
return $this->getCurrentConfig()['debug'] ?? false;
}
/**
* Retourne la liste des origines autorisées (domaines)
*
* @return array Liste des origines autorisées
*/
public function getAllowedOrigins(): array {
return array_keys($this->config);
}
/**
* Vérifie si le client est d'un type spécifique
*
* @param string $type Type de client à vérifier
* @return bool True si le client est du type spécifié
*/
public function isClientType(string $type): bool {
return $this->getClientType() === $type;
}
/**
* Retourne la configuration complète pour l'utilisation externe
*
* @return array Configuration complète
*/
public function getFullConfig(): array {
return [
'environment' => $this->getEnvironment(),
'database' => $this->getDatabaseConfig(),
'api' => [
'allowed_origins' => $this->getAllowedOrigins(),
'current_site' => $this->getName(),
],
'debug' => $this->isDebugEnabled()
];
}
/**
* Retourne l'adresse IP du client
*
* @return string L'adresse IP du client
*/
public function getClientIp(): string {
return $this->clientIp;
}
/**
* Détermine l'adresse IP du client en tenant compte des proxys et load balancers
*
* @return string L'adresse IP du client
*/
private function getClientIpAddress(): string {
// Vérifier les en-têtes courants pour l'IP client
$ipSources = [
'HTTP_X_REAL_IP', // Nginx proxy
'HTTP_CLIENT_IP', // Proxy partagé
'HTTP_X_FORWARDED_FOR', // Proxy ou load balancer courant
'HTTP_X_FORWARDED', // Proxy générique
'HTTP_X_CLUSTER_CLIENT_IP', // Reverse proxy
'HTTP_FORWARDED_FOR', // Proxies précédents
'HTTP_FORWARDED', // Format standardisé (RFC 7239)
'REMOTE_ADDR', // Fallback direct
];
foreach ($ipSources as $source) {
if (!empty($_SERVER[$source])) {
// Pour des en-têtes comme X-Forwarded-For qui peuvent contenir plusieurs IPs séparées par des virgules
// (format: "client, proxy1, proxy2")
if ($source === 'HTTP_X_FORWARDED_FOR' || $source === 'HTTP_FORWARDED_FOR') {
$ips = explode(',', $_SERVER[$source]);
$clientIp = trim($ips[0]); // Prendre la première adresse (client original)
} else {
$clientIp = $_SERVER[$source];
}
// Valider l'IP pour éviter les injections
$filteredIp = filter_var($clientIp, FILTER_VALIDATE_IP);
if ($filteredIp !== false) {
return $filteredIp;
}
}
}
// Si aucune adresse IP valide n'est trouvée, retourner une valeur par défaut
return '0.0.0.0';
}
}