diff --git a/.gitignore b/.gitignore index f896d71..ee10a71 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,9 @@ mentions-legales.php tmp/ temp/ +# Fichiers de cache +cache/ + # Fichiers de dépendances (si nécessaire) # vendor/ -# node_modules/ \ No newline at end of file +# node_modules/ diff --git a/includes/config.php b/includes/config.php index 2ec8a30..93dd2c2 100644 --- a/includes/config.php +++ b/includes/config.php @@ -3,6 +3,9 @@ // Charger les fonctions de sécurité require_once __DIR__ . '/security.php'; +// Charger le système de cache simple +require_once __DIR__ . '/simple-cache.php'; + // Charger d'abord la configuration locale si elle existe $config_local_file = __DIR__ . '/config.local.php'; if (file_exists($config_local_file)) { @@ -77,13 +80,14 @@ function initCategories() { } /** - * Fonction utilitaire pour appeler l'API PeerTube + * Version originale pour appeler l'API PeerTube (sans cache) + * Cette fonction est maintenant utilisée en interne par callPeerTubeApi * * @param string $endpoint Point de terminaison de l'API * @param array $params Paramètres optionnels pour la requête * @return array Données retournées par l'API */ -function callPeerTubeApi($endpoint, $params = []) { +function callPeerTubeApiOriginal($endpoint, $params = []) { // Validation de l'URL de base PeerTube pour prévenir SSRF if (!isValidPeerTubeUrl(PEERTUBE_URL)) { error_log('SECURITY: Invalid PeerTube URL detected: ' . PEERTUBE_URL); @@ -146,6 +150,23 @@ function callPeerTubeApi($endpoint, $params = []) { return $data ?: []; } +/** + * Fonction utilitaire pour appeler l'API PeerTube avec cache + * + * @param string $endpoint Point de terminaison de l'API + * @param array $params Paramètres optionnels pour la requête + * @return array Données retournées par l'API + */ +function callPeerTubeApi($endpoint, $params = []) { + // Utiliser la fonction cachée si disponible + if (function_exists('callPeerTubeApiCached')) { + return callPeerTubeApiCached($endpoint, $params); + } + + // Fallback vers la version originale + return callPeerTubeApiOriginal($endpoint, $params); +} + /** * Valide l'URL PeerTube pour prévenir les attaques SSRF * diff --git a/includes/simple-cache.php b/includes/simple-cache.php new file mode 100644 index 0000000..a3245f0 --- /dev/null +++ b/includes/simple-cache.php @@ -0,0 +1,130 @@ +cacheDir = __DIR__ . '/../cache/api'; + $this->enabled = true; + + // Créer le répertoire de cache s'il n'existe pas + if (!is_dir($this->cacheDir)) { + mkdir($this->cacheDir, 0755, true); + } + } + + /** + * Génère une clé de cache + */ + private function getCacheKey($endpoint, $params = []) { + $key = $endpoint; + if (!empty($params)) { + ksort($params); + $key .= '_' . md5(serialize($params)); + } + return 'cache_' . md5($key) . '.json'; + } + + /** + * Récupère depuis le cache + */ + public function get($endpoint, $params = []) { + if (!$this->enabled) return null; + + $file = $this->cacheDir . '/' . $this->getCacheKey($endpoint, $params); + + if (!file_exists($file)) { + return null; + } + + $data = json_decode(file_get_contents($file), true); + + // Vérifier l'expiration + if (isset($data['expires']) && time() > $data['expires']) { + unlink($file); + return null; + } + + return $data['content'] ?? null; + } + + /** + * Stocke dans le cache + */ + public function set($endpoint, $params, $content, $ttl = 300) { + if (!$this->enabled) return; + + $file = $this->cacheDir . '/' . $this->getCacheKey($endpoint, $params); + + $data = [ + 'content' => $content, + 'expires' => time() + $ttl, + 'created' => time() + ]; + + file_put_contents($file, json_encode($data)); + } + + /** + * Nettoie le cache expiré + */ + public function cleanup() { + $files = glob($this->cacheDir . '/cache_*.json'); + $cleaned = 0; + + foreach ($files as $file) { + $data = json_decode(file_get_contents($file), true); + if (isset($data['expires']) && time() > $data['expires']) { + unlink($file); + $cleaned++; + } + } + + return $cleaned; + } +} + +// Instance globale +$GLOBALS['simple_api_cache'] = new SimpleAPICache(); + +/** + * Version cachée de callPeerTubeApi - remplace l'originale + */ +function callPeerTubeApiCached($endpoint, $params = []) { + $cache = $GLOBALS['simple_api_cache']; + + // TTL selon le type de contenu + $ttlMap = [ + 'videos/categories' => 3600, // 1 heure + 'videos' => 300, // 5 minutes + 'search/videos' => 600 // 10 minutes + ]; + + $ttl = $ttlMap[$endpoint] ?? 300; + + // Essayer le cache d'abord + $cached = $cache->get($endpoint, $params); + if ($cached !== null) { + return $cached; + } + + // Appeler l'API originale + $data = callPeerTubeApiOriginal($endpoint, $params); + + // Mettre en cache si on a des données + if (!empty($data)) { + $cache->set($endpoint, $params, $data, $ttl); + } + + return $data; +} + +// Nettoyage automatique occasionnel +if (rand(1, 100) === 1) { + $GLOBALS['simple_api_cache']->cleanup(); +} +?> \ No newline at end of file