108 lines
4.9 KiB
PHP
108 lines
4.9 KiB
PHP
<?php
|
||
/**
|
||
* WEVAL SITEMAP API
|
||
* Énumère exhaustivement les 250+ pages HTML
|
||
* Détecte orphelins (pas de href vers cette page depuis autre page)
|
||
* Catégorise via patterns de nom
|
||
* Source unique pour /weval-sitemap.html
|
||
*/
|
||
header('Content-Type: application/json; charset=utf-8');
|
||
header('Cache-Control: max-age=300');
|
||
|
||
$ROOT = '/var/www/html';
|
||
$pages = [];
|
||
$all_html = glob($ROOT . '/*.html');
|
||
|
||
// Build set of all referenced pages (to detect orphans)
|
||
$referenced = [];
|
||
foreach ($all_html as $f) {
|
||
$name = basename($f);
|
||
$content = @file_get_contents($f);
|
||
if (!$content) continue;
|
||
if (preg_match_all('#href\s*=\s*["\']\/?([a-zA-Z0-9_\-]+\.html)["\']#', $content, $m)) {
|
||
foreach ($m[1] as $ref) {
|
||
$referenced[$ref] = ($referenced[$ref] ?? 0) + 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Categorize via patterns
|
||
function categorize($name) {
|
||
$n = strtolower($name);
|
||
// PRIORITY 1: Entry points / Catalogs (les portail/sitemap/index)
|
||
if (preg_match('/^(weval-portal|pages-index|weval-sitemap|all-screens|weval-master-inventory|cartographie|weval-wiring|plan-du-site|integrations-marketplace|ia-registre|index\.html|apps\.html|solution-finder)/', $n)) return 'Entry·Portal';
|
||
if (preg_match('/^(wevia|wedroid|wevcode|claw|droid-terminal)/', $n)) return 'WEVIA·Brain';
|
||
if (preg_match('/(erp|launchpad)/', $n)) return 'ERP·Unified';
|
||
if (preg_match('/(architecture|archi(?!ve)|sitemap)/', $n)) return 'Architecture';
|
||
if (preg_match('/(agent|persona|avatar)/', $n)) return 'Agents';
|
||
if (preg_match('/(dashboard|hub|center|cockpit)/', $n)) return 'Dashboards/Hubs';
|
||
// PRIORITY 2: Lean Six Sigma + Quality (avant Admin)
|
||
if (preg_match('/(value-stream|value-chain|vsm|dmaic|bpmn|kaizen|gemba|kanban|lean|kpi|maturity|mgmt|management|methodologie|mthodologie|playbook|ultimate-quality)/', $n)) return 'Lean·6σ·Quality';
|
||
if (preg_match('/(test|nonreg|sigma|l99|playwright|living|proof|qa|debug|monitor|monitoring|sessions-monitor|sso-monitor|cyber-monitor|realtime-monitor|world-map-live|nl-autowire-status|wevads-performance)/', $n)) return 'Quality/Monitoring';
|
||
if (preg_match('/(admin|director|manager|control|cron|maintenance|onboarding-em|tasks-live)/', $n)) return 'Admin/Ops';
|
||
if (preg_match('/(crm|ethica|hcp|business|growth|pipeline|deal|consultant|candidate|kaouther|partners-emails|mission-billing|medreach)/', $n)) return 'Business/CRM';
|
||
// PRIORITY 3: Email/Office Operations
|
||
if (preg_match('/(office|gmail|gws-setup|azure|decision-gmail|smtp|warmup|sender|email)/', $n)) return 'Email·Office';
|
||
if (preg_match('/(arena)/', $n)) return 'Operations·Arena';
|
||
if (preg_match('/(deepseek|openclaw|mistral|ollama|gemini|nvidia|provider|sovereign|claude|ai-benchmark|oss-discovery|wiki(?!-)|faq|doctrine)/', $n)) return 'IA·Providers·Docs';
|
||
if (preg_match('/(blade|gpu|infra(?!ction)|server|hetzner|cloudflare|huawei|google-hub|github-hub|caps|keys-hub|api-key)/', $n)) return 'Infrastructure';
|
||
if (preg_match('/(visual)/', $n)) return 'Visual·Mgmt';
|
||
if (preg_match('/(api|token|catalog|registry|capability)/', $n)) return 'APIs/Capabilities';
|
||
if (preg_match('/(login|booking|cgu|consent|data-deletion|signup|register|pricing|privacy|terms|404|gosignup|googlecba|maintenance|pitch|pain-points|ecosysteme)/', $n)) return 'Public/Marketing';
|
||
if (preg_match('/(deer|paperclip|qdrant|n8n|mattermost|listmonk|loki|plausible|arsenal)/', $n)) return 'Infra·Tools';
|
||
if (preg_match('/(case|study|model|enterprise|wtp|technology|platform|golive|value-streaming|sales)/', $n)) return 'Marketing/Sales';
|
||
return 'Autre';
|
||
}
|
||
|
||
// Build pages list
|
||
foreach ($all_html as $f) {
|
||
$name = basename($f);
|
||
$size = filesize($f);
|
||
$mtime = filemtime($f);
|
||
$is_orphan = !isset($referenced[$name]);
|
||
$ref_count = $referenced[$name] ?? 0;
|
||
$cat = categorize($name);
|
||
$pages[] = [
|
||
'name' => $name,
|
||
'url' => '/' . $name,
|
||
'category' => $cat,
|
||
'size' => $size,
|
||
'size_kb' => round($size / 1024, 1),
|
||
'mtime' => $mtime,
|
||
'mtime_iso' => date('c', $mtime),
|
||
'mtime_human' => date('Y-m-d H:i', $mtime),
|
||
'is_orphan' => $is_orphan,
|
||
'ref_count' => $ref_count,
|
||
];
|
||
}
|
||
|
||
// Sort: by category, then by mtime desc
|
||
usort($pages, function($a, $b) {
|
||
$c = strcmp($a['category'], $b['category']);
|
||
if ($c !== 0) return $c;
|
||
return $b['mtime'] - $a['mtime'];
|
||
});
|
||
|
||
// Group by category
|
||
$by_cat = [];
|
||
foreach ($pages as $p) {
|
||
$by_cat[$p['category']][] = $p;
|
||
}
|
||
|
||
// Stats
|
||
$stats = [
|
||
'total_pages' => count($pages),
|
||
'total_categories' => count($by_cat),
|
||
'orphan_count' => count(array_filter($pages, fn($p) => $p['is_orphan'])),
|
||
'by_category_count' => array_map('count', $by_cat),
|
||
];
|
||
|
||
echo json_encode([
|
||
'ok' => true,
|
||
'ts' => date('c'),
|
||
'source' => 'live filesystem scan',
|
||
'stats' => $stats,
|
||
'pages' => $pages,
|
||
'by_category' => $by_cat,
|
||
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|