feat : SearchLogParser supporte tar.gz + config log dans onglet Recherches
- logFiles() utilise glob() au lieu d'un range fixe 1-14 - Support .tar.gz via PharData - Champ apache_access_log déplacé du tab Site vers un bloc dédié dans le tab Recherches (action admin_save_searches_config) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2810,6 +2810,16 @@ switch ($action) {
|
|||||||
header('Location: /admin/site?' . ($ok ? 'saved=1' : 'error=write'));
|
header('Location: /admin/site?' . ($ok ? 'saved=1' : 'error=write'));
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
case 'admin_save_searches_config':
|
||||||
|
requireAuth();
|
||||||
|
if (!isAdmin() || $_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
|
http_response_code(403);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$ok = saveSiteSettings(['apache_access_log' => $_POST['apache_access_log'] ?? '']);
|
||||||
|
header('Location: /admin/searches?' . ($ok ? 'saved=1' : 'error=write'));
|
||||||
|
exit;
|
||||||
|
|
||||||
case 'admin_create_role':
|
case 'admin_create_role':
|
||||||
requireAuth();
|
requireAuth();
|
||||||
if (!isAdmin() || $_SERVER['REQUEST_METHOD'] !== 'POST') {
|
if (!isAdmin() || $_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
|
|||||||
+28
-10
@@ -57,23 +57,26 @@ class SearchLogParser
|
|||||||
&& (time() - filemtime($this->cacheFile)) < $this->cacheTtl;
|
&& (time() - filemtime($this->cacheFile)) < $this->cacheTtl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return list<array{path:string,gz:bool}> */
|
/** @return list<array{path:string,type:string}> type: plain|gz|tgz */
|
||||||
private function logFiles(): array
|
private function logFiles(): array
|
||||||
{
|
{
|
||||||
$base = $this->logDir . '/' . $this->vhostBase;
|
$base = $this->logDir . '/' . $this->vhostBase;
|
||||||
$files = [];
|
$files = [];
|
||||||
|
|
||||||
if (file_exists($base) && is_readable($base)) {
|
if (file_exists($base) && is_readable($base)) {
|
||||||
$files[] = ['path' => $base, 'gz' => false];
|
$files[] = ['path' => $base, 'type' => 'plain'];
|
||||||
}
|
}
|
||||||
|
|
||||||
for ($i = 1; $i <= 14; $i++) {
|
foreach (glob($base . '.*') ?: [] as $path) {
|
||||||
$plain = $base . '.' . $i;
|
if (!is_readable($path)) {
|
||||||
$gz = $plain . '.gz';
|
continue;
|
||||||
if (file_exists($plain) && is_readable($plain)) {
|
}
|
||||||
$files[] = ['path' => $plain, 'gz' => false];
|
if (str_ends_with($path, '.tar.gz')) {
|
||||||
} elseif (file_exists($gz) && is_readable($gz)) {
|
$files[] = ['path' => $path, 'type' => 'tgz'];
|
||||||
$files[] = ['path' => $gz, 'gz' => true];
|
} elseif (str_ends_with($path, '.gz')) {
|
||||||
|
$files[] = ['path' => $path, 'type' => 'gz'];
|
||||||
|
} else {
|
||||||
|
$files[] = ['path' => $path, 'type' => 'plain'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +85,22 @@ class SearchLogParser
|
|||||||
|
|
||||||
private function parseFile(array $file, array &$counts): void
|
private function parseFile(array $file, array &$counts): void
|
||||||
{
|
{
|
||||||
if ($file['gz']) {
|
if ($file['type'] === 'tgz') {
|
||||||
|
try {
|
||||||
|
$phar = new PharData($file['path']);
|
||||||
|
foreach ($phar as $entry) {
|
||||||
|
$content = @file_get_contents('phar://' . $file['path'] . '/' . $entry->getFilename());
|
||||||
|
if ($content === false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
foreach (explode("\n", $content) as $line) {
|
||||||
|
$this->parseLine($line, $counts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// archive illisible, on ignore
|
||||||
|
}
|
||||||
|
} elseif ($file['type'] === 'gz') {
|
||||||
$h = @gzopen($file['path'], 'rb');
|
$h = @gzopen($file['path'], 'rb');
|
||||||
if (!$h) {
|
if (!$h) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
+23
-8
@@ -507,14 +507,6 @@ function adminStatusBadge(array $a, int $now): string
|
|||||||
value="<?= postsPerPage() ?>"
|
value="<?= postsPerPage() ?>"
|
||||||
min="1" max="100">
|
min="1" max="100">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
|
||||||
<label for="apache-access-log" class="form-label small fw-semibold">Log d'accès Apache</label>
|
|
||||||
<input type="text" id="apache-access-log" name="apache_access_log"
|
|
||||||
class="form-control form-control-sm font-monospace"
|
|
||||||
value="<?= htmlspecialchars(apacheAccessLog()) ?>"
|
|
||||||
maxlength="200" placeholder="ex : lan.acegrp.monsite-access.log">
|
|
||||||
<div class="form-text">Nom du fichier dans <code>/var/log/apache2/</code>, utilisé par l'onglet Recherches.</div>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="site-license-label" class="form-label small fw-semibold">Licence (libellé)</label>
|
<label for="site-license-label" class="form-label small fw-semibold">Licence (libellé)</label>
|
||||||
<input type="text" id="site-license-label" name="site_license_label"
|
<input type="text" id="site-license-label" name="site_license_label"
|
||||||
@@ -1070,6 +1062,29 @@ foreach (COLOR_PALETTE_16 as $_i => $_rgb):
|
|||||||
<!-- ─────────────────────────── RECHERCHES ─────────────────────────── -->
|
<!-- ─────────────────────────── RECHERCHES ─────────────────────────── -->
|
||||||
<?php if ($tab === 'searches' && isAdmin()): ?>
|
<?php if ($tab === 'searches' && isAdmin()): ?>
|
||||||
|
|
||||||
|
<?php if (isset($_GET['saved'])): ?>
|
||||||
|
<div class="alert alert-success py-2 mb-3">Configuration enregistrée.</div>
|
||||||
|
<?php elseif (($_GET['error'] ?? '') === 'write'): ?>
|
||||||
|
<div class="alert alert-danger py-2 mb-3">Impossible d'enregistrer : le fichier n'est pas accessible en écriture.</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="card mb-4" style="max-width:540px">
|
||||||
|
<div class="card-header bg-transparent py-2 small fw-semibold">Configuration des logs</div>
|
||||||
|
<div class="card-body py-3">
|
||||||
|
<form method="post" action="/?action=admin_save_searches_config">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="apache-access-log" class="form-label small fw-semibold">Log d'accès Apache</label>
|
||||||
|
<input type="text" id="apache-access-log" name="apache_access_log"
|
||||||
|
class="form-control form-control-sm font-monospace"
|
||||||
|
value="<?= htmlspecialchars(apacheAccessLog()) ?>"
|
||||||
|
maxlength="200" placeholder="ex : lan.acegrp.monsite-access.log">
|
||||||
|
<div class="form-text">Nom du fichier dans <code>/var/log/apache2/</code>. Supporte <code>.gz</code> et <code>.tar.gz</code>.</div>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary btn-sm">Enregistrer</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="d-flex align-items-center justify-content-between mb-3 flex-wrap gap-2">
|
<div class="d-flex align-items-center justify-content-between mb-3 flex-wrap gap-2">
|
||||||
<h5 class="mb-0">Termes recherchés
|
<h5 class="mb-0">Termes recherchés
|
||||||
<span class="badge bg-secondary ms-1"><?= count($adminData['search_terms'] ?? []) ?></span>
|
<span class="badge bg-secondary ms-1"><?= count($adminData['search_terms'] ?? []) ?></span>
|
||||||
|
|||||||
Reference in New Issue
Block a user