/** * Site Schema API (prototype) * Returns a simple site overview + mermaid diagram. */ session_name('CUSTOMER_PORTAL_SESSION'); ini_set('session.cookie_path', '/'); ini_set('session.cookie_httponly', '1'); session_start(); header('Content-Type: application/json; charset=utf-8'); if (!isset($_SESSION['customer_logged_in']) || $_SESSION['customer_logged_in'] !== true) { echo json_encode(['success' => false, 'error' => 'Niet ingelogd']); exit; } $customer_id = (int)($_SESSION['customer_info']['id'] ?? 0); if ($customer_id <= 0) { echo json_encode(['success' => false, 'error' => 'Geen klant ID']); exit; } require_once __DIR__ . '/../../includes/storage-helpers.php'; $db = @new mysqli('localhost', 'itlive_portal', 'ItLive_Secure_2024', 'itlive_portal'); if ($db->connect_error) { $db = @new mysqli('localhost', 'root', '', 'itlive_portal'); } if ($db->connect_error) { echo json_encode(['success' => false, 'error' => 'Database verbinding mislukt']); exit; } $db->set_charset('utf8mb4'); function guess_page_from_path($path) { $p = strtolower(str_replace('\\', '/', (string)$path)); if (preg_match('/\b(home|index)\b/', $p)) return ['home', 'Home']; if (preg_match('/\b(about|over)\b/', $p)) return ['over-ons', 'Over ons']; if (preg_match('/\b(service|diensten)\b/', $p)) return ['diensten', 'Diensten']; if (preg_match('/\b(contact)\b/', $p)) return ['contact', 'Contact']; if (preg_match('/\b(blog|news|nieuws)\b/', $p)) return ['blog', 'Blog']; if (preg_match('/\b(faq|vragen)\b/', $p)) return ['faq', 'FAQ']; return ['overig', 'Overig']; } function guess_section_from_file($filename) { $f = strtolower((string)$filename); if (strpos($f, 'hero') !== false) return 'hero'; if (strpos($f, 'footer') !== false) return 'footer'; if (strpos($f, 'header') !== false) return 'header'; if (strpos($f, 'cta') !== false) return 'cta'; if (strpos($f, 'service') !== false || strpos($f, 'diensten') !== false) return 'services'; if (strpos($f, 'about') !== false || strpos($f, 'over') !== false) return 'about'; if (strpos($f, 'contact') !== false) return 'contact'; return 'content'; } function media_items($customer_id) { $base = customer_storage_path($customer_id); $media_dir = $base . '/media'; $meta_file = $media_dir . '/.media_meta.json'; $meta = []; if (is_file($meta_file)) { $raw = @file_get_contents($meta_file); $data = json_decode($raw, true); if (is_array($data)) $meta = $data; } $items = []; if (is_dir($media_dir)) { foreach (scandir($media_dir) as $f) { if ($f === '.' || $f === '..' || $f === '.media_meta.json' || $f === 'originals') continue; $full = $media_dir . '/' . $f; if (!is_file($full)) continue; $items[] = [ 'filename' => $f, 'url' => '/customer_portal/api/media-bibliotheek-serve.php?f=' . rawurlencode($f), 'alt' => $meta[$f]['alt'] ?? '', 'tags' => isset($meta[$f]['tags']) && is_array($meta[$f]['tags']) ? $meta[$f]['tags'] : [] ]; } } return $items; } function pick_thumbnail($media, $page_slug, $page_title) { $needle = strtolower($page_slug . ' ' . $page_title); foreach ($media as $m) { $alt = strtolower($m['alt'] ?? ''); if ($alt !== '' && strpos($alt, $page_slug) !== false) return $m['url']; if ($alt !== '' && strpos($alt, strtolower($page_title)) !== false) return $m['url']; if (!empty($m['tags'])) { foreach ($m['tags'] as $t) { if (strpos($needle, strtolower($t)) !== false) return $m['url']; } } } return isset($media[0]['url']) ? $media[0]['url'] : ''; } function calc_seo_score($sections) { $score = 50; $has = array_flip($sections); if (isset($has['hero'])) $score += 15; if (isset($has['cta'])) $score += 10; if (isset($has['services'])) $score += 10; if (isset($has['contact'])) $score += 10; if (isset($has['footer'])) $score += 5; return min(100, $score); } function page_status($sections) { $has = array_flip($sections); if (!isset($has['hero']) || !isset($has['cta'])) return 'attention'; if (!isset($has['footer'])) return 'partial'; return 'ok'; } $action = $_GET['action'] ?? 'overview'; // Latest project for customer (prototype) $project = null; $st = $db->prepare("SELECT id, project_name, project_path, domain_name, indexed_at FROM customer_ai_projects WHERE customer_id = ? ORDER BY indexed_at DESC LIMIT 1"); if ($st) { $st->bind_param('i', $customer_id); $st->execute(); $res = $st->get_result(); $project = $res->fetch_assoc(); $st->close(); } // Build page map from indexed files $pages = []; if ($project) { $st = $db->prepare("SELECT file_path, file_name, file_type FROM customer_ai_index WHERE customer_id = ? AND index_type IN ('project','file') ORDER BY indexed_at DESC LIMIT 300"); if ($st) { $st->bind_param('i', $customer_id); $st->execute(); $res = $st->get_result(); while ($row = $res->fetch_assoc()) { $path = $row['file_path'] ?? ''; $file = $row['file_name'] ?? basename($path); [$slug, $title] = guess_page_from_path($path); if (!isset($pages[$slug])) { $pages[$slug] = [ 'slug' => $slug, 'title' => $title, 'files' => [], 'sections' => [] ]; } $pages[$slug]['files'][] = $file; $section = guess_section_from_file($file); $pages[$slug]['sections'][$section] = true; } $st->close(); } } $page_list = []; foreach ($pages as $p) { $sections = array_values(array_keys($p['sections'])); $page_list[] = [ 'slug' => $p['slug'], 'title' => $p['title'], 'files' => array_values(array_unique($p['files'])), 'sections' => $sections, 'thumbnail' => pick_thumbnail($media, $p['slug'], $p['title']), 'seo_score' => calc_seo_score($sections), 'status' => page_status($sections) ]; } $media = media_items($customer_id); if ($action === 'save' && $_SERVER['REQUEST_METHOD'] === 'POST') { $payload = json_decode(file_get_contents('php://input'), true); if (!is_array($payload)) $payload = $_POST; $schema = $payload['schema'] ?? null; $diagram = $payload['diagram'] ?? ''; $base = customer_storage_path($customer_id); $dir = $base . '/site_schema'; if (!is_dir($dir)) @mkdir($dir, 0755, true); $saved = [ 'saved_at' => date('c'), 'schema' => $schema, 'diagram' => $diagram ]; @file_put_contents($dir . '/schema.json', json_encode($saved, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); if ($diagram !== '') { @file_put_contents($dir . '/schema.mmd', $diagram); } echo json_encode(['success' => true, 'saved_at' => $saved['saved_at']]); $db->close(); exit; } if ($action === 'saved') { $base = customer_storage_path($customer_id); $file = $base . '/site_schema/schema.json'; if (!is_file($file)) { echo json_encode(['success' => true, 'saved' => null]); $db->close(); exit; } $raw = @file_get_contents($file); $data = json_decode($raw, true); echo json_encode(['success' => true, 'saved' => $data]); $db->close(); exit; } if ($action === 'mermaid') { $lines = ["flowchart TD"]; $lines[] = "site[\"Site\"]"; foreach ($page_list as $p) { $node = $p['slug']; $lines[] = "site --> {$node}[\"{$p['title']}\"]"; foreach ($p['sections'] as $s) { $sec = $node . '_' . $s; $label = ucfirst($s); $lines[] = "{$node} --> {$sec}[\"{$label}\"]"; } } echo json_encode(['success' => true, 'diagram' => implode("\n", $lines), 'project' => $project]); $db->close(); exit; } echo json_encode([ 'success' => true, 'project' => $project, 'pages' => $page_list, 'media' => $media ]); $db->close();