$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);