Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b2533695e | ||
|
|
07b53b8002 |
No files matched your search
+52
-3
@@ -140,7 +140,7 @@ try {
|
||||
$installedVerData = file_exists("{$appDir}/version.json")
|
||||
? json_decode((string)file_get_contents("{$appDir}/version.json"), true)
|
||||
: [];
|
||||
$installedVer = $installedVerData['version'] ?? '1.4.3';
|
||||
$installedVer = $installedVerData['version'] ?? '1.4.5';
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
@@ -369,6 +369,13 @@ try {
|
||||
// Synchronisation automatique de l'annuaire d'entreprise
|
||||
PhonebookManager::syncExtensions($db);
|
||||
|
||||
// Régénération automatique des fichiers Asterisk et rechargement PJSIP/Dialplan en direct
|
||||
$generator->writeAllConfigs();
|
||||
try {
|
||||
$ami = AmiClient::fromDatabase($db);
|
||||
$ami->reloadPjsipAndDialplan();
|
||||
} catch (\Throwable $e) {}
|
||||
|
||||
$modeBadge = $transport === 'tls' ? 'Distant (TLS + SRTP)' : ($encryption ? 'Interne (UDP + SRTP)' : 'Interne (UDP)');
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
@@ -381,6 +388,13 @@ try {
|
||||
$stmt = $db->prepare('DELETE FROM extensions WHERE id = :id');
|
||||
$stmt->execute([':id' => $id]);
|
||||
PhonebookManager::syncExtensions($db);
|
||||
|
||||
$generator->writeAllConfigs();
|
||||
try {
|
||||
$ami = AmiClient::fromDatabase($db);
|
||||
$ami->reloadPjsipAndDialplan();
|
||||
} catch (\Throwable $e) {}
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => 'Poste téléphonique supprimé de la base SQLite.',
|
||||
@@ -440,6 +454,12 @@ try {
|
||||
]);
|
||||
}
|
||||
|
||||
$generator->writeAllConfigs();
|
||||
try {
|
||||
$ami = AmiClient::fromDatabase($db);
|
||||
$ami->reloadPjsipAndDialplan();
|
||||
} catch (\Throwable $e) {}
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => "Groupe d'appel {$extension} ({$name}) sauvegardé.",
|
||||
@@ -449,6 +469,12 @@ try {
|
||||
case 'delete_group':
|
||||
$id = (int)($payload['id'] ?? 0);
|
||||
$db->prepare('DELETE FROM groups WHERE id = :id')->execute([':id' => $id]);
|
||||
$generator->writeAllConfigs();
|
||||
try {
|
||||
$ami = AmiClient::fromDatabase($db);
|
||||
$ami->reloadPjsipAndDialplan();
|
||||
} catch (\Throwable $e) {}
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => "Groupe de sonnerie supprimé.",
|
||||
@@ -540,6 +566,12 @@ try {
|
||||
]);
|
||||
}
|
||||
|
||||
$generator->writeAllConfigs();
|
||||
try {
|
||||
$ami = AmiClient::fromDatabase($db);
|
||||
$ami->reloadPjsipAndDialplan();
|
||||
} catch (\Throwable $e) {}
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => "Groupe de téléavertissement {$extension} ({$name}) sauvegardé.",
|
||||
@@ -549,6 +581,12 @@ try {
|
||||
case 'delete_paging_group':
|
||||
$id = (int)($payload['id'] ?? 0);
|
||||
$db->prepare('DELETE FROM paging_groups WHERE id = :id')->execute([':id' => $id]);
|
||||
$generator->writeAllConfigs();
|
||||
try {
|
||||
$ami = AmiClient::fromDatabase($db);
|
||||
$ami->reloadPjsipAndDialplan();
|
||||
} catch (\Throwable $e) {}
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => "Groupe de téléavertissement supprimé.",
|
||||
@@ -2311,14 +2349,25 @@ try {
|
||||
|
||||
$newVerJson = file_exists("{$appDir}/version.json")
|
||||
? json_decode((string)file_get_contents("{$appDir}/version.json"), true)
|
||||
: ['version' => '1.3.8'];
|
||||
: ['version' => '1.4.3'];
|
||||
|
||||
while (ob_get_level() > 0) {
|
||||
@ob_end_clean();
|
||||
}
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('Cache-Control: no-cache, no-store, must-revalidate');
|
||||
|
||||
echo json_encode([
|
||||
'success' => ($code === 0),
|
||||
'new_version' => $newVerJson['version'] ?? '1.3.8',
|
||||
'new_version' => $newVerJson['version'] ?? '1.4.3',
|
||||
'output' => $outputStr,
|
||||
'message' => ($code === 0) ? "Mise à jour réussie !" : "Erreur lors de la mise à jour",
|
||||
]);
|
||||
|
||||
if (function_exists('fastcgi_finish_request')) {
|
||||
fastcgi_finish_request();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
+53
-19
@@ -5962,18 +5962,8 @@ async function executeSystemUpdate() {
|
||||
localStorage.removeItem('nexus_update_last_check_ts');
|
||||
localStorage.removeItem('nexus_update_cached_data');
|
||||
|
||||
try {
|
||||
const res = await fetch('/api.php?action=run_update&_t=' + Date.now(), {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({})
|
||||
});
|
||||
const data = await res.json();
|
||||
|
||||
if (data.success) {
|
||||
const newVer = data.new_version || '';
|
||||
|
||||
// 1. Mettre à jour immédiatement le cache avec l'état à jour
|
||||
function finalizeUpdateSuccess(newVer) {
|
||||
newVer = String(newVer || '').replace(/^v/, '');
|
||||
localStorage.setItem('nexus_update_last_check_ts', Date.now().toString());
|
||||
localStorage.setItem('nexus_update_cached_data', JSON.stringify({
|
||||
success: true,
|
||||
@@ -5984,7 +5974,6 @@ async function executeSystemUpdate() {
|
||||
release_date: ''
|
||||
}));
|
||||
|
||||
// 2. Mettre à jour visuellement les badges immédiatement
|
||||
const verTag = document.getElementById('system-version-tag');
|
||||
const appBadge = document.getElementById('app-version-badge');
|
||||
const headerUpdateBadge = document.getElementById('header-update-badge');
|
||||
@@ -6001,20 +5990,53 @@ async function executeSystemUpdate() {
|
||||
statusText.className = 'text-emerald-400 font-bold';
|
||||
statusText.textContent = `Mise à jour terminée avec succès (v${newVer}) ! Rechargement...`;
|
||||
}
|
||||
|
||||
if (btnModalConfirm) {
|
||||
btnModalConfirm.className = 'px-5 py-2.5 rounded-xl text-xs font-bold bg-emerald-600 text-white flex items-center gap-2';
|
||||
btnModalConfirm.innerHTML = '✓ Mise à jour terminée ! Rechargement...';
|
||||
}
|
||||
|
||||
// 3. Rechargement avec paramètre anti-cache pour forcer le navigateur à récupérer le nouveau DOM
|
||||
setTimeout(() => {
|
||||
closeUpdateConfirmModal();
|
||||
window.location.href = window.location.origin + window.location.pathname + '?_t=' + Date.now();
|
||||
}, 1800);
|
||||
} else {
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await fetch('/api.php?action=run_update&_t=' + Date.now(), {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({})
|
||||
});
|
||||
|
||||
const rawText = await res.text();
|
||||
let data = null;
|
||||
try {
|
||||
data = JSON.parse(rawText);
|
||||
} catch (_) {
|
||||
data = null;
|
||||
}
|
||||
|
||||
if (data && data.success) {
|
||||
finalizeUpdateSuccess(data.new_version);
|
||||
return;
|
||||
}
|
||||
|
||||
// Si la réponse n'était pas un JSON valide ou a été interrompue par le rechargement de php-fpm/nginx,
|
||||
// on sonde le serveur pour vérifier si la mise à jour a en réalité bien été appliquée sur le disque
|
||||
await new Promise(r => setTimeout(r, 2000));
|
||||
try {
|
||||
const probeRes = await fetch('/api.php?action=check_update&_t=' + Date.now());
|
||||
const probeData = await probeRes.json();
|
||||
if (probeData && probeData.success && probeData.current_version) {
|
||||
finalizeUpdateSuccess(probeData.current_version);
|
||||
return;
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
// En cas d'échec réel avéré
|
||||
closeUpdateConfirmModal();
|
||||
alert("Erreur lors de la mise à jour :\n\n" + (data.output || data.message));
|
||||
const errMsg = (data && (data.output || data.message)) ? (data.output || data.message) : (rawText.slice(0, 150) || "Erreur inconnue");
|
||||
alert("Erreur lors de la mise à jour :\n\n" + errMsg);
|
||||
if (btnRun) {
|
||||
btnRun.disabled = false;
|
||||
btnRun.innerHTML = 'Réessayer la mise à jour';
|
||||
@@ -6024,10 +6046,22 @@ async function executeSystemUpdate() {
|
||||
btnModalConfirm.classList.remove('opacity-75', 'cursor-not-allowed');
|
||||
btnModalConfirm.innerHTML = '<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/></svg><span>Lancer la mise à jour (1-Clic)</span>';
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
// En cas d'interruption réseau du socket (Safari WebKit DOMException ou timeout),
|
||||
// on vérifie avant d'alerter si le serveur a quand même réussi à déployer les fichiers
|
||||
await new Promise(r => setTimeout(r, 2000));
|
||||
try {
|
||||
const probeRes = await fetch('/api.php?action=check_update&_t=' + Date.now());
|
||||
const probeData = await probeRes.json();
|
||||
if (probeData && probeData.success && probeData.current_version) {
|
||||
finalizeUpdateSuccess(probeData.current_version);
|
||||
return;
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
closeUpdateConfirmModal();
|
||||
alert("Erreur réseau lors de la mise à jour : " + e.message);
|
||||
alert("Erreur réseau lors de la mise à jour : " + (e.message || "Connexion interrompue"));
|
||||
if (btnRun) {
|
||||
btnRun.disabled = false;
|
||||
btnRun.innerHTML = 'Réessayer la mise à jour';
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ $companyLogo = trim($branding['company_logo'] ?? '');
|
||||
$hasBranding = !empty($companyName) || !empty($companyLogo);
|
||||
|
||||
$appVerData = file_exists(__DIR__ . '/../version.json') ? json_decode((string)file_get_contents(__DIR__ . '/../version.json'), true) : [];
|
||||
$appVersion = $appVerData['version'] ?? '1.4.3';
|
||||
$appVersion = $appVerData['version'] ?? '1.4.5';
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr" class="h-full">
|
||||
|
||||
@@ -139,8 +139,14 @@ echo -e "${C_GRAY}[6/6] Rechargement à chaud d'Asterisk et des services web...$
|
||||
asterisk -rx "core reload" >/dev/null 2>&1 || true
|
||||
asterisk -rx "pjsip reload" >/dev/null 2>&1 || true
|
||||
asterisk -rx "dialplan reload" >/dev/null 2>&1 || true
|
||||
|
||||
# Rechargement des services web : différé si exécuté depuis l'interface web pour éviter de couper la requête HTTP
|
||||
if [ -t 1 ]; then
|
||||
systemctl reload php8.4-fpm 2>/dev/null || systemctl reload php8.2-fpm 2>/dev/null || systemctl reload php*-fpm 2>/dev/null || true
|
||||
systemctl reload nginx 2>/dev/null || true
|
||||
else
|
||||
(nohup bash -c "sleep 2 && (systemctl reload php8.4-fpm 2>/dev/null || systemctl reload php8.2-fpm 2>/dev/null || systemctl reload php*-fpm 2>/dev/null || true); systemctl reload nginx 2>/dev/null || true" >/dev/null 2>&1 &)
|
||||
fi
|
||||
|
||||
NEW_VER="Inconnue"
|
||||
if [ -f "$APP_DIR/version.json" ]; then
|
||||
|
||||
+5
-5
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"version": "1.4.3",
|
||||
"version": "1.4.5",
|
||||
"codename": "Helios",
|
||||
"release_date": "2026-11-04",
|
||||
"min_php_version": "8.2",
|
||||
"changelog": [
|
||||
"Nouvelle boîte modale élégante et personnalisée pour confirmer le lancement des mises à jour (remplacement du confirm natif)",
|
||||
"Rendu serveur natif garanti du logo et nom de l'exploitant sur la page de connexion",
|
||||
"Boîte de connexion allégée en style verre dépoli transparent (Glassmorphism backdrop-blur)",
|
||||
"Nouveau fond d'écran immersif haute définition (réseau constellation)"
|
||||
"Application instantanée des mots de passe SIP et configurations des postes dans Asterisk (rechargement PJSIP en temps réel)",
|
||||
"Suppression du délai d'application sur les postes, groupes de sonnerie et groupes de téléavertissement",
|
||||
"Fiabilisation maximale de la mise à jour (rechargement web asynchrone non-bloquant et gestion d'erreurs tolérante)",
|
||||
"Nouvelle boîte modale élégante et personnalisée pour confirmer le lancement des mises à jour"
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user