From e6540c866b4b2522635f67b6b3a025a251b21eda Mon Sep 17 00:00:00 2001 From: sorcier Date: Wed, 4 Nov 2026 01:58:26 +0100 Subject: [PATCH] fix(db): remove demo data auto-seeding to prevent resurrection of deleted items (v1.3.2) --- public/api.php | 2 +- public/assets/app.js | 2 +- src/Database.php | 236 +-------------------------------------- src/PhonebookManager.php | 2 + version.json | 11 +- 5 files changed, 15 insertions(+), 238 deletions(-) diff --git a/public/api.php b/public/api.php index d9cd532..d8559d3 100644 --- a/public/api.php +++ b/public/api.php @@ -1126,7 +1126,7 @@ try { $inband_progress = (int)!empty($payload['inband_progress']); $match_ips = trim((string)($payload['match_ips'] ?? '')); $context = preg_replace('/[^a-zA-Z0-9_\-]/', '', trim((string)($payload['context'] ?? 'from-external'))) ?: 'from-external'; - $inbound_dest = trim((string)($payload['inbound_dest'] ?? 'ivr-accueil')) ?: 'hangup'; + $inbound_dest = trim((string)($payload['inbound_dest'] ?? 'terminate-hangup')) ?: 'terminate-hangup'; $outbound_prefix = preg_replace('/[^0-9*#X._\[\]\-+]/', '', trim((string)($payload['outbound_prefix'] ?? ''))); $custom_endpoint_params = trim((string)($payload['custom_endpoint_params'] ?? '')); $custom_reg_params = trim((string)($payload['custom_reg_params'] ?? '')); diff --git a/public/assets/app.js b/public/assets/app.js index e02c916..75e228e 100644 --- a/public/assets/app.js +++ b/public/assets/app.js @@ -3003,7 +3003,7 @@ function openIvrModal(ivr = null) { document.getElementById('modal-ivr-title').textContent = ivr ? `Modifier le SVI « ${ivr.name} »` : 'Nouveau Serveur Vocal Interactif (SVI / IVR)'; form.elements['id'].value = ivr ? ivr.id : ''; - form.elements['name'].value = ivr ? ivr.name : 'ivr-accueil'; + form.elements['name'].value = ivr ? ivr.name : ''; form.elements['description'].value = ivr && ivr.description ? ivr.description : ''; form.elements['timeout'].value = ivr ? Number(ivr.timeout) : 5; form.elements['timeout_retries'].value = ivr ? Number(ivr.timeout_retries || 2) : 2; diff --git a/src/Database.php b/src/Database.php index cfd3f25..10e0eba 100644 --- a/src/Database.php +++ b/src/Database.php @@ -159,7 +159,7 @@ class Database max_channels INTEGER NOT NULL DEFAULT 0, match_ips TEXT NOT NULL DEFAULT '', context VARCHAR(64) NOT NULL DEFAULT 'from-external', - inbound_dest VARCHAR(64) NOT NULL DEFAULT 'ivr-accueil', + inbound_dest VARCHAR(64) NOT NULL DEFAULT 'terminate-hangup', did_routes_json TEXT NOT NULL DEFAULT '{}', outbound_prefix VARCHAR(32) NOT NULL DEFAULT '', custom_endpoint_params TEXT NOT NULL DEFAULT '', @@ -331,61 +331,6 @@ class Database ':p' => password_hash('admin123', PASSWORD_DEFAULT), ]); } - - // Données de démonstration initiales si la table extensions est vide - $extCount = (int)$db->query('SELECT COUNT(*) FROM extensions')->fetchColumn(); - if ($extCount === 0) { - $stmtExt = $db->prepare(' - INSERT INTO extensions (extension, name, secret, transport, encryption, codecs, max_contacts, enabled) - VALUES (:ext, :name, :secret, :transport, :encryption, :codecs, :max_contacts, 1) - '); - $stmtExt->execute([ - ':ext' => '101', - ':name' => 'Accueil Bureau (LAN)', - ':secret' => 'LanPass101!Sip', - ':transport' => 'udp', - ':encryption' => 0, - ':codecs' => 'alaw,ulaw,g722', - ':max_contacts' => 2, - ]); - $stmtExt->execute([ - ':ext' => '102', - ':name' => 'Direction Nomade (TLS/SRTP)', - ':secret' => 'TlsSecure102!Sip', - ':transport' => 'tls', - ':encryption' => 1, - ':codecs' => 'opus,g722,alaw', - ':max_contacts' => 3, - ]); - - $stmtGrp = $db->prepare(' - INSERT INTO groups (extension, name, strategy, ring_time, members, failover_dest) - VALUES (:ext, :name, :strategy, :ring_time, :members, :failover) - '); - $stmtGrp->execute([ - ':ext' => '600', - ':name' => 'Support Général', - ':strategy' => 'ringall', - ':ring_time' => 25, - ':members' => json_encode(['101', '102']), - ':failover' => 'hangup', - ]); - - $stmtIvr = $db->prepare(' - INSERT INTO ivrs (name, audio_file, timeout, options_json) - VALUES (:name, :audio, :timeout, :options) - '); - $stmtIvr->execute([ - ':name' => 'ivr-accueil', - ':audio' => 'custom/bienvenue-entreprise', - ':timeout' => 5, - ':options' => json_encode([ - '1' => 'ext-101', - '2' => 'grp-600', - '0' => 'ext-102', - ]), - ]); - } } private static function migrateSettingsTable(PDO $db): void @@ -539,7 +484,7 @@ class Database max_channels INTEGER NOT NULL DEFAULT 0, match_ips TEXT NOT NULL DEFAULT '', context VARCHAR(64) NOT NULL DEFAULT 'from-external', - inbound_dest VARCHAR(64) NOT NULL DEFAULT 'ivr-accueil', + inbound_dest VARCHAR(64) NOT NULL DEFAULT 'terminate-hangup', did_routes_json TEXT NOT NULL DEFAULT '{}', outbound_prefix VARCHAR(32) NOT NULL DEFAULT '', custom_endpoint_params TEXT NOT NULL DEFAULT '', @@ -594,166 +539,17 @@ class Database private static function migrateOutboundRoutesTable(PDO $db): void { - $count = (int)$db->query('SELECT COUNT(*) FROM outbound_routes')->fetchColumn(); - if ($count === 0) { - // Vérifie quels trunks et postes existent déjà pour pré-initialiser la route sortante principale - $trunks = $db->query('SELECT name, outbound_callerid FROM trunks ORDER BY id ASC')->fetchAll(); - $firstTrunkName = !empty($trunks) ? (string)$trunks[0]['name'] : 'ovh-telecom'; - $firstTrunkCid = !empty($trunks) && trim((string)$trunks[0]['outbound_callerid']) !== '' - ? trim((string)$trunks[0]['outbound_callerid']) - : 'Mon Entreprise <0123456789>'; - - $exts = $db->query('SELECT extension FROM extensions ORDER BY CAST(extension AS INTEGER) ASC')->fetchAll(PDO::FETCH_COLUMN); - $grps = $db->query('SELECT extension FROM groups ORDER BY CAST(extension AS INTEGER) ASC')->fetchAll(PDO::FETCH_COLUMN); - - $stmt = $db->prepare(' - INSERT INTO outbound_routes ( - priority, name, outbound_callerid, override_ext_cid, route_password, - route_type, moh_class, trunk_sequence_json, dial_patterns_json, - permission_mode, allowed_groups_json, allowed_extensions_json, - continue_next_route, congestion_dest, record_mode, enabled - ) VALUES ( - :priority, :name, :cid, :override_cid, :pwd, - :rtype, :moh, :trunks, :patterns, - :pmode, :agroups, :aexts, - :cont, :cdest, :rec, 1 - ) - '); - - // Route 1 : OVH (principale) - $stmt->execute([ - ':priority' => 1, - ':name' => 'OVH', - ':cid' => $firstTrunkCid, - ':override_cid' => 0, - ':pwd' => '', - ':rtype' => 'normal', - ':moh' => 'default', - ':trunks' => json_encode([$firstTrunkName]), - ':patterns' => json_encode([ - ['prepend' => '', 'prefix' => '', 'match_pattern' => '0[1-59]XXXXXXXX', 'callerid' => ''], - ['prepend' => '', 'prefix' => '', 'match_pattern' => '0[67]XXXXXXXX', 'callerid' => ''], - ['prepend' => '', 'prefix' => '', 'match_pattern' => '080[0-9]XXXXXX', 'callerid' => ''], - ]), - ':pmode' => 'all', - ':agroups' => json_encode($grps), - ':aexts' => json_encode($exts), - ':cont' => 1, - ':cdest' => 'all-circuits-busy', - ':rec' => 'dontcare', - ]); - - // Route 2 : Emergency (Numéros d'urgence) - $stmt->execute([ - ':priority' => 2, - ':name' => 'Emergency', - ':cid' => $firstTrunkCid, - ':override_cid' => 1, - ':pwd' => '', - ':rtype' => 'emergency', - ':moh' => 'default', - ':trunks' => json_encode([$firstTrunkName]), - ':patterns' => json_encode([ - ['prepend' => '', 'prefix' => '', 'match_pattern' => '15', 'callerid' => ''], - ['prepend' => '', 'prefix' => '', 'match_pattern' => '17', 'callerid' => ''], - ['prepend' => '', 'prefix' => '', 'match_pattern' => '18', 'callerid' => ''], - ['prepend' => '', 'prefix' => '', 'match_pattern' => '112', 'callerid' => ''], - ['prepend' => '', 'prefix' => '', 'match_pattern' => '114', 'callerid' => ''], - ]), - ':pmode' => 'all', - ':agroups' => json_encode($grps), - ':aexts' => json_encode($exts), - ':cont' => 1, - ':cdest' => 'terminate-congestion', - ':rec' => 'dontcare', - ]); - } + // Aucun enregistrement de démonstration auto-injecté pour conserver une base propre } private static function migrateExtensionGroupsTable(PDO $db): void { - $count = (int)$db->query('SELECT COUNT(*) FROM extension_groups')->fetchColumn(); - if ($count === 0) { - $stmt = $db->prepare('INSERT INTO extension_groups (name, description, color, members) VALUES (:n, :d, :c, :m)'); - $stmt->execute([ - ':n' => 'Groupe Nice', - ':d' => 'Extensions du site secondaire (Trunk passerelle locale)', - ':c' => 'emerald', - ':m' => json_encode(['101', '102']), - ]); - $stmt->execute([ - ':n' => 'Groupe Paris', - ':d' => 'Extensions du site de Paris (Trunk principal OVH)', - ':c' => 'indigo', - ':m' => json_encode(['103']), - ]); - } + // Aucun enregistrement de démonstration auto-injecté pour conserver une base propre } private static function migrateSoundsTable(PDO $db): void { - $count = (int)$db->query('SELECT COUNT(*) FROM sounds')->fetchColumn(); - if ($count === 0) { - $stmt = $db->prepare(' - INSERT INTO sounds (name, slug, site_category, usage_type, description, filename, original_filename, duration_sec, file_size, format) - VALUES (:name, :slug, :site, :usage, :desc, :file, :orig, :dur, :size, :fmt) - '); - - $demoSounds = [ - [ - ':name' => 'Message d\'accueil SVI Standard', - ':slug' => 'bienvenue-entreprise', - ':site' => 'Global', - ':usage' => 'ivr', - ':desc' => 'Jingle d\'accueil principal du serveur vocal interactif', - ':file' => 'bienvenue-entreprise.wav', - ':orig' => 'bienvenue-entreprise.wav', - ':dur' => 2, - ':size' => 31800, - ':fmt' => 'wav', - ], - [ - ':name' => 'Musique d\'attente Standard', - ':slug' => 'attente-musicale-standard', - ':site' => 'Global', - ':usage' => 'moh', - ':desc' => 'Mélodie douce d\'attente (MoH) par défaut pour les appels mis en garde', - ':file' => 'attente-musicale-standard.wav', - ':orig' => 'attente-musicale-standard.wav', - ':dur' => 4, - ':size' => 63600, - ':fmt' => 'wav', - ], - [ - ':name' => 'Message Ligne Occupée & Congestion', - ':slug' => 'ligne-occupee-congestion', - ':site' => 'Global', - ':usage' => 'congestion', - ':desc' => 'Tonalité cadencée d\'occupation si aucun trunk ou poste n\'est disponible', - ':file' => 'ligne-occupee-congestion.wav', - ':orig' => 'ligne-occupee-congestion.wav', - ':dur' => 1, - ':size' => 16000, - ':fmt' => 'wav', - ], - [ - ':name' => 'Annonce Fermeture Nice', - ':slug' => 'annonce-fermeture-nice', - ':site' => 'Site Nice', - ':usage' => 'announcement', - ':desc' => 'Message informant des horaires d\'ouverture du bureau de Nice', - ':file' => 'annonce-fermeture-nice.wav', - ':orig' => 'annonce-fermeture-nice.wav', - ':dur' => 2, - ':size' => 28800, - ':fmt' => 'wav', - ], - ]; - - foreach ($demoSounds as $ds) { - $stmt->execute($ds); - } - } + // Aucun enregistrement de démonstration auto-injecté pour conserver une base propre } private static function migrateSoundSitesTable(PDO $db): void @@ -762,8 +558,6 @@ class Database if ($count === 0) { $stmt = $db->prepare('INSERT INTO sound_sites (name, description) VALUES (:n, :d)'); $stmt->execute([':n' => 'Global', ':d' => 'Fichiers généraux partagés par tout le PBX']); - $stmt->execute([':n' => 'Site Nice', ':d' => 'Annonces et musiques spécifiques au site de Nice']); - $stmt->execute([':n' => 'Site Paris', ':d' => 'Annonces et musiques spécifiques au site de Paris']); } } @@ -954,25 +748,7 @@ class Database ); "); - $count = (int)$db->query('SELECT COUNT(*) FROM paging_groups')->fetchColumn(); - if ($count === 0) { - $exts = $db->query('SELECT extension FROM extensions ORDER BY CAST(extension AS INTEGER) ASC')->fetchAll(PDO::FETCH_COLUMN); - $members = !empty($exts) ? $exts : ['101', '102']; - $stmt = $db->prepare(' - INSERT INTO paging_groups (extension, name, description, members, duplex, busy_mode, play_beep, timeout, enabled) - VALUES (:ext, :name, :desc, :members, :duplex, :busy_mode, :play_beep, :timeout, 1) - '); - $stmt->execute([ - ':ext' => '100', - ':name' => 'Téléavertissement Général', - ':desc' => 'Diffusion générale sur haut-parleur de tous les postes', - ':members' => json_encode($members), - ':duplex' => 0, - ':busy_mode' => 'skip', - ':play_beep' => 1, - ':timeout' => 120, - ]); - } + // Aucun groupe de paging par défaut pour conserver une base propre } } diff --git a/src/PhonebookManager.php b/src/PhonebookManager.php index 79f029d..a84ecb3 100644 --- a/src/PhonebookManager.php +++ b/src/PhonebookManager.php @@ -110,6 +110,8 @@ class PhonebookManager if (!empty($activeExtIds)) { $inClause = implode(',', $activeExtIds); $db->exec("DELETE FROM phonebook_contacts WHERE is_internal = 1 AND extension_id IS NOT NULL AND extension_id NOT IN ({$inClause})"); + } else { + $db->exec("DELETE FROM phonebook_contacts WHERE is_internal = 1"); } } diff --git a/version.json b/version.json index 4651951..6df52c2 100644 --- a/version.json +++ b/version.json @@ -1,13 +1,12 @@ { - "version": "1.3.1", + "version": "1.3.2", "codename": "Helios", "release_date": "2026-11-04", "min_php_version": "8.2", "changelog": [ - "Badge de notification automatique de mise à jour dans l'en-tête (à côté du test AMI)", - "Vérification intelligente en tâche de fond toutes les 24h sans solliciter le serveur", - "Accès direct 1-clic aux détails et à l'installation des mises à jour", - "Gestion avancée des passerelles analogiques / FXO (Grandstream HT813, Cisco SPA)", - "Message vocal d'indisponibilité / congestion configurable sur les routes sortantes" + "Suppression complète des données de démonstration au déploiement (base 100% propre)", + "Résolution du bug de réapparition intempestive des postes, groupes, IVR, paging et routes supprimés", + "Synchronisation robuste de l'annuaire d'entreprise lors de la suppression des extensions", + "Destination entrante par défaut configurée sur raccrochage propre (terminate-hangup)" ] }