$message]); exit; } return [ 'pattern' => ['(:any)/(:any)/download', 'en/(:any)/(:any)/download'], 'method' => 'POST', 'action' => function (string $parent, string $slug) { $page = page($parent . '/' . $slug); if (!$page || $page->intendedTemplate()->name() !== 'white-paper') { wpReject(404, 'Not found'); } $body = kirby()->request()->body()->toArray(); // ── Honeypot ────────────────────────────────────────────── if (!empty($body['_hp'])) { wpReject(400, 'Bad request'); } // ── Rate limiting (5 req / hour / IP) ───────────────────── $ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? 'unknown'; $cacheKey = 'wp-dl-' . md5($ip); $cache = kirby()->cache('pages'); $hits = (int)($cache->get($cacheKey) ?? 0); if ($hits >= 5) { wpReject(429, 'Too many requests'); } $cache->set($cacheKey, $hits + 1, 60); // TTL 60 min // ── Validation des champs requis ────────────────────────── $firstName = trim($body['firstName'] ?? ''); $lastName = trim($body['lastName'] ?? ''); $email = trim($body['email'] ?? ''); if ($firstName === '' || $lastName === '' || $email === '') { wpReject(422, 'Missing required fields'); } if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { wpReject(422, 'Invalid email'); } // ── Stocker le lead dans contactDatabase ────────────────── $company = trim($body['company'] ?? ''); $role = trim($body['role'] ?? ''); $entries = $page->contactDatabase()->toStructure()->toArray(); $existingIndex = null; foreach ($entries as $i => $entry) { if (strtolower($entry['email'] ?? '') === strtolower($email)) { $existingIndex = $i; break; } } if ($existingIndex !== null) { // Contact déjà présent — on enrichit les champs vides uniquement if ($company !== '' && empty($entries[$existingIndex]['company'])) { $entries[$existingIndex]['company'] = $company; } if ($role !== '' && empty($entries[$existingIndex]['role'])) { $entries[$existingIndex]['role'] = $role; } } else { $entries[] = [ 'firstName' => $firstName, 'lastName' => $lastName, 'email' => $email, 'company' => $company, 'role' => $role, 'downloadedAt' => date('d/m/Y H:i'), ]; } kirby()->impersonate('kirby', function () use ($page, $entries) { page('livres-blancs')->update(['contactDatabase' => \Kirby\Data\Data::encode($entries, 'yaml')]); }); header('Content-Type: application/json'); echo json_encode([ 'success' => true, 'fileUrl' => $page->downloadFile()->toFile()?->url(), ]); exit; } ];