Compare commits

...

1 Commits

Author SHA1 Message Date
Flatlogic Bot
fba6335153 Autosave: 20260304-162416 2026-03-04 16:24:17 +00:00
17 changed files with 375 additions and 0 deletions

0
account.php Normal file
View File

63
api/auth.php Normal file
View File

@ -0,0 +1,63 @@
<?php
require_once __DIR__ . '/../includes/db.php';
require_once __DIR__ . '/../includes/auth.php';
header('Content-Type: application/json');
$action = $_GET['action'] ?? '';
switch ($action) {
case 'register':
$data = json_decode(file_get_contents('php://input'), true);
if (empty($data['username']) || empty($data['password'])) {
echo json_encode(['error' => 'Missing credentials']);
exit;
}
try {
$stmt = $pdo->prepare("INSERT INTO users (username, password_hash) VALUES (?, ?)");
$stmt->execute([$data['username'], password_hash($data['password'], PASSWORD_DEFAULT)]);
$userId = $pdo->lastInsertId();
$_SESSION['user_id'] = $userId;
$_SESSION['username'] = $data['username'];
echo json_encode(['success' => true, 'user' => ['id' => $userId, 'username' => $data['username']]]);
} catch (PDOException $e) {
echo json_encode(['error' => 'Registration failed: ' . $e->getMessage()]);
}
break;
case 'login':
$data = json_decode(file_get_contents('php://input'), true);
$stmt = $pdo->prepare("SELECT id, username, password_hash FROM users WHERE username = ?");
$stmt->execute([$data['username'] ?? '']);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user && password_verify($data['password'] ?? '', $user['password_hash'])) {
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
echo json_encode(['success' => true, 'user' => ['id' => $user['id'], 'username' => $user['username']]]);
} else {
http_response_code(401);
echo json_encode(['error' => 'Invalid credentials']);
}
break;
case 'logout':
session_destroy();
echo json_encode(['success' => true]);
break;
case 'me':
if (isLoggedIn()) {
echo json_encode(['user' => currentUser()]);
} else {
echo json_encode(['user' => null]);
}
break;
default:
http_response_code(400);
echo json_encode(['error' => 'Invalid action']);
}

0
api/directions.php Normal file
View File

81
api/generate.php Normal file
View File

@ -0,0 +1,81 @@
<?php
require_once __DIR__ . '/../includes/db.php';
require_once __DIR__ . '/../includes/auth.php';
header('Content-Type: application/json');
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['error' => 'Method not allowed']);
exit;
}
$input = json_decode(file_get_contents('php://input'), true);
// 1. Generate Itinerary (Mock fallback if API keys are missing)
function getMockItinerary($input) {
return [
'days' => [
[
'day' => 1,
'items' => [
['place_name' => 'Göreme Açık Hava Müzesi', 'category' => 'History', 'estimated_duration_minutes' => 120, 'description' => 'Historical cave churches.'],
['place_name' => 'Paşabağları', 'category' => 'Nature', 'estimated_duration_minutes' => 90, 'description' => 'Fairy chimneys.']
]
]
]
];
}
// 2. Google Places Lookup (Cache Check)
function getPlaceDetails($pdo, $placeName) {
$normalized = strtolower(trim($placeName));
$stmt = $pdo->prepare("SELECT * FROM places_cache WHERE place_name_normalized = ?");
$stmt->execute([$normalized]);
$cached = $stmt->fetch(PDO::FETCH_ASSOC);
if ($cached) return $cached;
$apiKey = getenv('GOOGLE_MAPS_API_KEY');
if (!$apiKey) return null;
$url = "https://maps.googleapis.com/maps/api/place/textsearch/json?query=" . urlencode($placeName . " Cappadocia") . "&key=" . $apiKey;
$response = json_decode(file_get_contents($url), true);
if (!empty($response['results'])) {
$r = $response['results'][0];
$data = [
'place_name_normalized' => $normalized,
'place_id' => $r['place_id'],
'name' => $r['name'],
'formatted_address' => $r['formatted_address'],
'lat' => $r['geometry']['location']['lat'],
'lng' => $r['geometry']['location']['lng'],
'rating' => $r['rating'] ?? 0,
'photo_reference' => $r['photos'][0]['photo_reference'] ?? null
];
$stmt = $pdo->prepare("INSERT INTO places_cache (place_name_normalized, place_id, name, formatted_address, lat, lng, rating, photo_reference) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute(array_values($data));
return $data;
}
return null;
}
// Logic: Attempt OpenAI, fallback to mock
$itinerary = getMockItinerary($input); // Simplified for now
// Enrich with Places
foreach ($itinerary['days'] as &$day) {
foreach ($day['items'] as &$item) {
$details = getPlaceDetails($pdo, $item['place_name']);
if ($details) {
$item['place_id'] = $details['place_id'];
$item['lat'] = $details['lat'];
$item['lng'] = $details['lng'];
}
}
}
echo json_encode(['success' => true, 'itinerary' => $itinerary]);

67
api/place-details.php Normal file
View File

@ -0,0 +1,67 @@
<?php
require_once __DIR__ . '/../includes/db.php';
header('Content-Type: application/json');
$place_id = $_GET['place_id'] ?? '';
$name = $_GET['name'] ?? '';
$category = $_GET['category'] ?? '';
if (empty($place_id)) {
echo json_encode(['error' => 'place_id is required']);
exit;
}
// 1. Check Cache
$stmt = $pdo->prepare("SELECT details FROM place_details_cache WHERE place_id = ?");
$stmt->execute([$place_id]);
$cached = $stmt->fetchColumn();
if ($cached) {
echo json_encode(json_decode($cached));
exit;
}
// 2. Google Places Details API
$apiKey = getenv('GOOGLE_MAPS_API_KEY');
$url = "https://maps.googleapis.com/maps/api/place/details/json?place_id=$place_id&fields=name,rating,user_ratings_total,reviews,opening_hours,editorial_summary&language=tr&key=$apiKey";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
if (!isset($data['result'])) {
echo json_encode(['error' => 'Failed to fetch details']);
exit;
}
$result = $data['result'];
// 3. Generate Content (Placeholder / Logic for AI)
// In a real production app, call OpenAI API here if configured.
// Using static fallback as requested for now.
$aiContent = [
'why_visit' => ["Kapadokya'nın eşsiz güzelliklerini keşfedin", "Tarihi dokusuyla büyülenin", "Unutulmaz fotoğraflar çekin"],
'tips' => ["Sabah erken saatlerde ziyaret etmenizi öneririz.", "Rahat ayakkabılar giyin.", "Güneş kreminizi yanınıza alın.", "Yerel rehberlerden bilgi alabilirsiniz."],
'summary' => "{$result['name']}, bölgedeki en ilgi çekici ve kültürel açıdan zengin noktalardan biridir. Ziyaretçilerine hem doğal güzellikler hem de tarihi deneyimler sunmaktadır."
];
$finalResponse = [
'place_id' => $place_id,
'name' => $result['name'] ?? $name,
'summary' => $aiContent['summary'],
'rating' => $result['rating'] ?? 0,
'total_ratings' => $result['user_ratings_total'] ?? 0,
'is_open_now' => $result['opening_hours']['open_now'] ?? null,
'opening_hours' => $result['opening_hours']['weekday_text'] ?? [],
'why_visit' => $aiContent['why_visit'],
'tips' => $aiContent['tips'],
'reviews' => $result['reviews'] ?? []
];
// 5. Cache
$stmt = $pdo->prepare("INSERT IGNORE INTO place_details_cache (place_id, details) VALUES (?, ?)");
$stmt->execute([$place_id, json_encode($finalResponse)]);
// 6. Respond
echo json_encode($finalResponse);

30
api/place-photo.php Normal file
View File

@ -0,0 +1,30 @@
<?php
/**
* api/place-photo.php
* Handles image redirection based on photo_reference and API key availability.
*/
$photoReference = $_GET['photo_reference'] ?? null;
$apiKey = getenv('GOOGLE_MAPS_API_KEY');
$unsplashUrls = [
'https://images.unsplash.com/photo-1544833316-64d88e00182a?w=800',
'https://images.unsplash.com/photo-1570168007204-dfb528c6958f?w=800',
'https://images.unsplash.com/photo-1524231757912-21f4fe3a7200?w=800'
];
if (empty($photoReference)) {
// Redirect to random Unsplash Kapadokya photo
header('Location: ' . $unsplashUrls[array_rand($unsplashUrls)]);
exit;
}
if (!empty($apiKey)) {
// Redirect to Google Places Photo
$url = "https://maps.googleapis.com/maps/api/place/photo?maxwidth=800&photo_reference=" . urlencode($photoReference) . "&key=" . urlencode($apiKey);
header('Location: ' . $url);
exit;
}
// Fallback: Redirect to random Unsplash photo if no API key
header('Location: ' . $unsplashUrls[array_rand($unsplashUrls)]);
exit;

73
api/trips.php Normal file
View File

@ -0,0 +1,73 @@
<?php
require_once __DIR__ . '/../includes/db.php';
require_once __DIR__ . '/../includes/auth.php';
header('Content-Type: application/json');
if (!isLoggedIn()) {
http_response_code(401);
echo json_encode(['error' => 'Unauthorized']);
exit;
}
$action = $_GET['action'] ?? '';
$user_id = $_SESSION['user_id'];
try {
switch ($action) {
case 'list':
$stmt = $pdo->prepare("SELECT * FROM trips WHERE user_id = ? ORDER BY created_at DESC");
$stmt->execute([$user_id]);
echo json_encode(['trips' => $stmt->fetchAll(PDO::FETCH_ASSOC)]);
break;
case 'get':
$id = $_GET['id'] ?? '';
$stmt = $pdo->prepare("SELECT * FROM trips WHERE id = ? AND user_id = ?");
$stmt->execute([$id, $user_id]);
$trip = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$trip) {
http_response_code(404);
echo json_encode(['error' => 'Trip not found']);
} else {
echo json_encode(['trip' => $trip]);
}
break;
case 'create':
$data = json_decode(file_get_contents('php://input'), true);
$stmt = $pdo->prepare("INSERT INTO trips (user_id, title, start_date, end_date, preferences, itinerary) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->execute([
$user_id,
$data['title'],
$data['start_date'],
$data['end_date'],
json_encode($data['preferences']),
json_encode($data['itinerary'])
]);
echo json_encode(['success' => true, 'trip_id' => $pdo->lastInsertId()]);
break;
case 'update':
$id = $_GET['id'] ?? '';
$data = json_decode(file_get_contents('php://input'), true);
$stmt = $pdo->prepare("UPDATE trips SET itinerary = ? WHERE id = ? AND user_id = ?");
$stmt->execute([json_encode($data['itinerary']), $id, $user_id]);
echo json_encode(['success' => true]);
break;
case 'delete':
$id = $_GET['id'] ?? '';
$stmt = $pdo->prepare("DELETE FROM trips WHERE id = ? AND user_id = ?");
$stmt->execute([$id, $user_id]);
echo json_encode(['success' => true]);
break;
default:
http_response_code(400);
echo json_encode(['error' => 'Invalid action']);
}
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['error' => $e->getMessage()]);
}

0
assets/css/style.css Normal file
View File

View File

@ -0,0 +1,44 @@
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS trips (
id VARCHAR(36) PRIMARY KEY,
user_id INT NOT NULL,
title VARCHAR(255) NOT NULL,
destination VARCHAR(255) DEFAULT 'Cappadocia',
start_date DATE NOT NULL,
end_date DATE NOT NULL,
preferences JSON,
itinerary JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS places_cache (
place_name_normalized VARCHAR(255) PRIMARY KEY,
place_id VARCHAR(255),
name VARCHAR(255),
formatted_address TEXT,
lat FLOAT,
lng FLOAT,
rating FLOAT,
photo_reference TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS place_details_cache (
place_id VARCHAR(255) PRIMARY KEY,
details JSON NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS directions_cache (
cache_key VARCHAR(500) PRIMARY KEY,
response JSON NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

0
explore.php Normal file
View File

10
includes/auth.php Normal file
View File

@ -0,0 +1,10 @@
<?php
session_start();
function isLoggedIn() { return isset($_SESSION['user_id']); }
function requireLogin() {
if (!isLoggedIn()) {
header('Location: /login.php?redirect=' . urlencode($_SERVER['REQUEST_URI']));
exit;
}
}
function currentUser() { return ['id' => $_SESSION['user_id'], 'username' => $_SESSION['username']]; }

7
includes/db.php Normal file
View File

@ -0,0 +1,7 @@
<?php
$host = $_ENV['DB_HOST'] ?? 'localhost';
$db = $_ENV['DB_NAME'] ?? 'kapadokya';
$user = $_ENV['DB_USER'] ?? 'root';
$pass = $_ENV['DB_PASS'] ?? '';
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8mb4", $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

0
includes/footer.php Normal file
View File

0
includes/header.php Normal file
View File

0
login.php Normal file
View File

0
planner.php Normal file
View File

0
trip/view.php Normal file
View File