132 lines
5.3 KiB
PHP
132 lines
5.3 KiB
PHP
<?php
|
|
ini_set('display_errors', 1);
|
|
ini_set('display_startup_errors', 1);
|
|
error_reporting(E_ALL);
|
|
|
|
header('Content-Type: application/json');
|
|
|
|
require_once __DIR__ . '/../ai/LocalAIApi.php';
|
|
require_once __DIR__ . '/../includes/pexels.php';
|
|
require_once __DIR__ . '/../db/config.php';
|
|
|
|
$action = $_GET['action'] ?? 'get_suggestion';
|
|
|
|
switch ($action) {
|
|
case 'get_suggestion':
|
|
handle_get_suggestion();
|
|
break;
|
|
case 'save_suggestion':
|
|
handle_save_suggestion();
|
|
break;
|
|
default:
|
|
echo json_encode(['error' => 'Invalid action']);
|
|
break;
|
|
}
|
|
|
|
function handle_get_suggestion() {
|
|
$requestBody = file_get_contents('php://input');
|
|
$data = json_decode($requestBody, true);
|
|
|
|
$query = $data['query'] ?? '';
|
|
$persona = $data['persona'] ?? 'travel_agent';
|
|
$conversation = $data['conversation'] ?? [];
|
|
|
|
if (empty($query)) {
|
|
echo json_encode(['error' => 'Query is empty']);
|
|
exit;
|
|
}
|
|
|
|
$conversation[] = ['role' => 'user', 'content' => $query];
|
|
|
|
$persona_prompts = [
|
|
'travel_agent' => 'You are a helpful travel agent specializing in Poland.',
|
|
'historian' => 'You are a historian specializing in Polish history. Your responses should be informative, detailed, and focus on the historical significance of places and events.',
|
|
'foodie' => 'You are a food critic and blogger with a passion for Polish cuisine. Your responses should be enthusiastic, descriptive, and focus on food, restaurants, and culinary experiences.',
|
|
'adventurer' => 'You are an adventure travel guide who loves exploring the wild side of Poland. Your responses should be exciting, energetic, and focus on outdoor activities, hiking, and unique experiences.'
|
|
];
|
|
|
|
$system_prompt = $persona_prompts[$persona] . ' Provide a travel suggestion with a title, a short description, a 3-day itinerary, and the latitude and longitude of the location. Your response must be in JSON format, like this: {"title": "...", "description": "...", "itinerary": [{"day": 1, "activities": ["...", "..."]}, {"day": 2, "activities": ["...", "..."]}, {"day": 3, "activities": ["...", "..."]}], "location": {"lat": ..., "lng": ...}}. The user is on a conversation, so answer the last query based on the context of the conversation.';
|
|
|
|
$messages = array_merge([['role' => 'system', 'content' => $system_prompt]], $conversation);
|
|
|
|
$resp = LocalAIApi::createResponse(
|
|
[
|
|
'input' => $messages
|
|
]
|
|
);
|
|
|
|
if (!empty($resp['success'])) {
|
|
$text = LocalAIApi::extractText($resp);
|
|
$aiResponse = json_decode($text, true);
|
|
|
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
|
preg_match('/"title":\s*"(.*?)"/', $text, $title_matches);
|
|
preg_match('/"description":\s*"(.*?)"/', $text, $description_matches);
|
|
$title = $title_matches[1] ?? 'AI Generated Response';
|
|
$description = $description_matches[1] ?? $text;
|
|
$itinerary = [];
|
|
$location = null;
|
|
} else {
|
|
$title = $aiResponse['title'] ?? 'AI Generated Response';
|
|
$description = $aiResponse['description'] ?? 'No description available.';
|
|
$itinerary = $aiResponse['itinerary'] ?? [];
|
|
$location = $aiResponse['location'] ?? null;
|
|
}
|
|
|
|
$pexelsUrl = 'https://api.pexels.com/v1/search?query=' . urlencode($title) . '&orientation=landscape&per_page=1&page=1';
|
|
$pexelsData = pexels_get($pexelsUrl);
|
|
|
|
$imageUrl = 'https://images.pexels.com/photos/1699030/pexels-photo-1699030.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1';
|
|
if ($pexelsData && !empty($pexelsData['photos'])) {
|
|
$photo = $pexelsData['photos'][0];
|
|
$imageUrl = $photo['src']['large2x'] ?? ($photo['src']['large'] ?? $photo['src']['original']);
|
|
}
|
|
|
|
echo json_encode([
|
|
'title' => $title,
|
|
'description' => $description,
|
|
'itinerary' => $itinerary,
|
|
'location' => $location,
|
|
'image' => $imageUrl
|
|
]);
|
|
} else {
|
|
error_log('AI error: ' . ($resp['error'] ?? 'unknown'));
|
|
echo json_encode(['error' => 'Failed to get AI response']);
|
|
}
|
|
}
|
|
|
|
function handle_save_suggestion() {
|
|
$requestBody = file_get_contents('php://input');
|
|
$data = json_decode($requestBody, true);
|
|
|
|
$title = $data['title'] ?? null;
|
|
$description = $data['description'] ?? null;
|
|
$itinerary = $data['itinerary'] ?? null;
|
|
$location = $data['location'] ?? null;
|
|
$image_url = $data['image'] ?? null;
|
|
|
|
if (empty($title)) {
|
|
echo json_encode(['error' => 'Title is required to save a suggestion.']);
|
|
exit;
|
|
}
|
|
|
|
try {
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("
|
|
INSERT INTO saved_suggestions (title, description, itinerary, location, image_url)
|
|
VALUES (:title, :description, :itinerary, :location, :image_url)
|
|
");
|
|
$stmt->execute([
|
|
':title' => $title,
|
|
':description' => $description,
|
|
':itinerary' => json_encode($itinerary),
|
|
':location' => json_encode($location),
|
|
':image_url' => $image_url
|
|
]);
|
|
echo json_encode(['success' => true, 'id' => $pdo->lastInsertId()]);
|
|
} catch (PDOException $e) {
|
|
error_log('DB error: ' . $e->getMessage());
|
|
echo json_encode(['error' => 'Failed to save suggestion to the database.']);
|
|
}
|
|
}
|