} */ public static function load(string $manifestDir): array { $path = $manifestDir . '/channels.json'; $base = ['channels' => []]; if (is_file($path)) { $raw = file_get_contents($path); $json = json_decode((string)$raw, true); if (is_array($json) && isset($json['channels']) && is_array($json['channels'])) { $base['channels'] = $json['channels']; } } // Garantit que "default" est toujours présent en tête (immutable depuis la UI). $hasDefault = false; foreach ($base['channels'] as $c) { if (($c['name'] ?? '') === 'default') { $hasDefault = true; break; } } if (!$hasDefault) { array_unshift($base['channels'], [ 'name' => 'default', 'label' => 'Public', 'description' => 'Versions publiques visibles par tous les clients', ]); } return $base; } public static function save(string $manifestDir, array $registry): void { $path = $manifestDir . '/channels.json'; if (!is_dir($manifestDir)) mkdir($manifestDir, 0755, true); file_put_contents( $path, json_encode($registry, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n" ); } /** * Retourne true si $name est un identifiant de channel valide : * lowercase, chiffres, tirets et underscores, 1 à 64 caractères. */ public static function isValidName(string $name): bool { return (bool)preg_match('/^[a-z0-9_-]{1,64}$/', $name); } /** * Normalise un nom saisi par l'admin : lowercase, espaces → tirets, retire * les chars hors whitelist, compresse les tirets multiples, trim. * Identique à ps_normalize_channel() dans versions.php — centralisé ici * pour les futurs ajouts. */ public static function normalizeName(string $raw): string { $s = strtolower(trim($raw)); $s = (string)preg_replace('/[\s\x{2010}-\x{2015}]+/u', '-', $s); $s = (string)preg_replace('/[^a-z0-9_-]/', '', $s); $s = (string)preg_replace('/-+/', '-', $s); $s = trim($s, '-_'); return substr($s, 0, 64); } /** * @return list Liste des noms de channel pour les dropdowns. */ public static function listNames(string $manifestDir): array { $reg = self::load($manifestDir); return array_map(fn($c) => (string)($c['name'] ?? ''), $reg['channels']); } }