Files
Superfice_Website/api/helpers.php
2026-04-30 16:12:30 +02:00

113 lines
3.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Superfice API Helpers
*
* Shared utility functions for API endpoints.
* Not directly accessible (no public entry point).
*/
// -------------------------------------------------------
// CORS
// -------------------------------------------------------
function cors_headers(): void {
$allowed = defined('SITE_ORIGIN') ? SITE_ORIGIN : '*';
header('Access-Control-Allow-Origin: ' . $allowed);
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
}
// -------------------------------------------------------
// JSON error response
// -------------------------------------------------------
function json_error(string $msg, int $code = 400): never {
http_response_code($code);
echo json_encode(['error' => $msg]);
exit;
}
// -------------------------------------------------------
// Client IP (respects proxy headers cautiously)
// -------------------------------------------------------
function client_ip(): string {
// Only trust X-Forwarded-For if behind a known proxy
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
return trim($ips[0]);
}
return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}
// -------------------------------------------------------
// File-based rate limiting
// -------------------------------------------------------
function rate_limit(string $key, int $maxRequests, int $window): void {
$dir = defined('RATE_LIMIT_DIR') ? RATE_LIMIT_DIR : sys_get_temp_dir() . '/sf_rl';
if (!is_dir($dir)) {
@mkdir($dir, 0700, true);
}
$file = $dir . '/' . hash('sha256', $key) . '.json';
$now = time();
$data = ['count' => 0, 'reset' => $now + $window];
if (file_exists($file)) {
$stored = json_decode(file_get_contents($file), true);
if (is_array($stored) && $stored['reset'] > $now) {
$data = $stored;
}
}
$data['count']++;
file_put_contents($file, json_encode($data), LOCK_EX);
if ($data['count'] > $maxRequests) {
http_response_code(429);
echo json_encode(['error' => 'Zu viele Anfragen. Bitte versuchen Sie es später erneut.']);
exit;
}
}
// -------------------------------------------------------
// Haversine distance (km)
// -------------------------------------------------------
function haversine(float $lat1, float $lon1, float $lat2, float $lon2): int {
$R = 6371;
$dLat = deg2rad($lat2 - $lat1);
$dLon = deg2rad($lon2 - $lon1);
$a = sin($dLat / 2) ** 2
+ cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLon / 2) ** 2;
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
return (int) round($R * $c);
}
// -------------------------------------------------------
// SMTP send (basic, without PHPMailer)
// For production, install PHPMailer via Composer and
// replace this function body accordingly.
// -------------------------------------------------------
function send_smtp(string $subject, string $body, string $headers): void {
// Placeholder integrate PHPMailer here:
//
// require __DIR__ . '/../vendor/autoload.php';
// $mail = new PHPMailer\PHPMailer\PHPMailer(true);
// $mail->isSMTP();
// $mail->Host = SMTP_HOST;
// $mail->SMTPAuth = true;
// $mail->Username = SMTP_USER;
// $mail->Password = SMTP_PASS;
// $mail->SMTPSecure = SMTP_SECURE;
// $mail->Port = SMTP_PORT;
// $mail->setFrom(MAIL_FROM, MAIL_FROM_NAME);
// $mail->addAddress(MAIL_TO);
// $mail->Subject = $subject;
// $mail->Body = $body;
// $mail->send();
// Fallback to mail() until PHPMailer is integrated
$sent = @mail(MAIL_TO, $subject, $body, $headers);
if (!$sent) {
error_log('Superfice SMTP fallback mail() failed');
json_error('Beim Senden ist ein Fehler aufgetreten. Bitte schreiben Sie uns direkt.');
}
}