Files
image-pichost/config.php
2025-12-01 12:17:10 +00:00

402 lines
14 KiB
PHP
Raw Permalink 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
session_start();
error_reporting(E_ALL);
ini_set('display_errors', 1);
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
require_once 'phpmailer/src/Exception.php';
require_once 'phpmailer/src/PHPMailer.php';
require_once 'phpmailer/src/SMTP.php';
define('DB_HOST', 'HOST');
define('DB_NAME', 'NAME');
define('DB_USER', 'USER');
define('DB_PASS', 'PASS');
define('SITE_URL', 'WEB');
define('SITE_NAME', 'SITE');
define('MAX_FILE_SIZE', 5 * 1024 * 1024);
define('ALLOWED_TYPES', ['jpg', 'jpeg', 'png', 'gif', 'webp']);
define('API_KEY_LENGTH', 32);
define('SMTP_HOST', 'EHOST');
define('SMTP_PORT', NUM);
define('SMTP_USERNAME', 'EUSER');
define('SMTP_PASSWORD', 'EPASS');
define('SMTP_FROM_EMAIL', 'FUSER');
define('SMTP_FROM_NAME', 'FNAME');
define('SMTP_SECURE', 'SECURE');
define('SMTP_DEBUG', false);
define('BING_API_URL', 'https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN');
define('CAPTCHA_ENABLED', true);
define('PASSWORD_RESET_EXPIRE', 3600);
define('DEFAULT_LANGUAGE', 'zh-CN');
$supported_languages = ['zh-CN', 'en'];
try {
$pdo = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4", DB_USER, DB_PASS);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
die("数据库连接失败: " . $e->getMessage());
}
if (!file_exists('uploads')) {
mkdir('uploads', 0755, true);
file_put_contents('uploads/index.html', '');
file_put_contents('uploads/.htaccess', 'Deny from all');
}
if (!file_exists('languages')) mkdir('languages', 0755, true);
if (!file_exists('admin')) mkdir('admin', 0755, true);
if (!file_exists('components')) mkdir('components', 0755, true);
if (!file_exists('api')) mkdir('api', 0755, true);
function getLanguage() {
global $supported_languages;
if (isset($_SESSION['language'])) {
return $_SESSION['language'];
}
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
$browser_lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
if ($browser_lang === 'zh') return 'zh-CN';
if ($browser_lang === 'en') return 'en';
}
return DEFAULT_LANGUAGE;
}
function loadLanguage($lang) {
$lang_file = "languages/{$lang}.php";
if (file_exists($lang_file)) {
return include $lang_file;
}
return include "languages/" . DEFAULT_LANGUAGE . ".php";
}
$lang = getLanguage();
$translations = loadLanguage($lang);
$_SESSION['language'] = $lang;
function t($key) {
global $translations;
return $translations[$key] ?? $key;
}
function getUserSettings($user_id) {
global $pdo;
$stmt = $pdo->prepare("SELECT * FROM user_settings WHERE user_id = ?");
$stmt->execute([$user_id]);
$settings = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$settings) {
$stmt = $pdo->prepare("INSERT INTO user_settings (user_id) VALUES (?)");
$stmt->execute([$user_id]);
return [
'dark_mode' => false,
'language' => 'zh-CN',
'items_per_page' => 20,
'email_notifications' => true,
'browser_notifications' => true
];
}
return $settings;
}
function updateUserSettings($user_id, $settings) {
global $pdo;
$stmt = $pdo->prepare("INSERT INTO user_settings (user_id, dark_mode, language, items_per_page, email_notifications, browser_notifications)
VALUES (?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
dark_mode = VALUES(dark_mode),
language = VALUES(language),
items_per_page = VALUES(items_per_page),
email_notifications = VALUES(email_notifications),
browser_notifications = VALUES(browser_notifications)");
return $stmt->execute([
$user_id,
$settings['dark_mode'] ? 1 : 0,
$settings['language'],
$settings['items_per_page'],
$settings['email_notifications'] ? 1 : 0,
$settings['browser_notifications'] ? 1 : 0
]);
}
function getUserNotificationSettings($user_id) {
global $pdo;
$stmt = $pdo->prepare("SELECT nt.name, uns.enabled FROM user_notification_settings uns
JOIN notification_types nt ON uns.notification_type_id = nt.id
WHERE uns.user_id = ?");
$stmt->execute([$user_id]);
$settings = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
if (empty($settings)) {
initUserNotificationSettings($user_id);
return getUserNotificationSettings($user_id);
}
return $settings;
}
function initUserNotificationSettings($user_id) {
global $pdo;
$stmt = $pdo->prepare("INSERT INTO user_notification_settings (user_id, notification_type_id, enabled)
SELECT ?, id, TRUE FROM notification_types");
return $stmt->execute([$user_id]);
}
function updateUserNotificationSettings($user_id, $settings) {
global $pdo;
foreach ($settings as $type_id => $enabled) {
$stmt = $pdo->prepare("INSERT INTO user_notification_settings (user_id, notification_type_id, enabled)
VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE enabled = VALUES(enabled)");
$stmt->execute([$user_id, $type_id, $enabled ? 1 : 0]);
}
return true;
}
function sendNotification($user_id, $type_name, $title, $message, $related_url = null) {
global $pdo;
$stmt = $pdo->prepare("SELECT uns.enabled FROM user_notification_settings uns
JOIN notification_types nt ON uns.notification_type_id = nt.id
WHERE uns.user_id = ? AND nt.name = ?");
$stmt->execute([$user_id, $type_name]);
$setting = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$setting || !$setting['enabled']) return false;
$stmt = $pdo->prepare("SELECT id FROM notification_types WHERE name = ?");
$stmt->execute([$type_name]);
$type = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$type) return false;
$stmt = $pdo->prepare("INSERT INTO notifications (user_id, type_id, title, message, related_url)
VALUES (?, ?, ?, ?, ?)");
return $stmt->execute([$user_id, $type['id'], $title, $message, $related_url]);
}
function getUnreadNotificationCount($user_id) {
global $pdo;
$stmt = $pdo->prepare("SELECT COUNT(*) as count FROM notifications WHERE user_id = ? AND is_read = FALSE");
$stmt->execute([$user_id]);
return $stmt->fetch(PDO::FETCH_ASSOC)['count'];
}
function getUserNotifications($user_id, $limit = 10) {
global $pdo;
$stmt = $pdo->prepare("SELECT n.*, nt.name as type_name FROM notifications n
JOIN notification_types nt ON n.type_id = nt.id
WHERE n.user_id = ?
ORDER BY n.created_at DESC
LIMIT ?");
$stmt->bindValue(1, $user_id, PDO::PARAM_INT);
$stmt->bindValue(2, $limit, PDO::PARAM_INT);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
function generateRandomString($length = 10) {
return substr(str_shuffle(str_repeat($x = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
ceil($length / strlen($x)))), 1, $length);
}
function formatFileSize($bytes) {
if ($bytes >= 1073741824) return number_format($bytes / 1073741824, 2) . ' GB';
elseif ($bytes >= 1048576) return number_format($bytes / 1048576, 2) . ' MB';
elseif ($bytes >= 1024) return number_format($bytes / 1024, 2) . ' KB';
else return $bytes . ' bytes';
}
function getBingDailyImage() {
$response = @file_get_contents(BING_API_URL);
if ($response) {
$data = json_decode($response, true);
if ($data && isset($data['images'][0])) {
$image = $data['images'][0];
return [
'url' => 'https://www.bing.com' . $image['url'],
'title' => $image['title'],
'copyright' => $image['copyright'],
'copyrightlink' => $image['copyrightlink']
];
}
}
return null;
}
function sendEmail($to, $subject, $message) {
$mail = new PHPMailer(true);
try {
// 服务器设置
$mail->isSMTP();
$mail->Host = SMTP_HOST;
$mail->SMTPAuth = true;
$mail->Username = SMTP_USERNAME;
$mail->Password = SMTP_PASSWORD;
$mail->SMTPSecure = SMTP_SECURE;
$mail->Port = SMTP_PORT;
if (SMTP_DEBUG) {
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
}
// 收件人
$mail->setFrom(SMTP_FROM_EMAIL, SMTP_FROM_NAME);
$mail->addAddress($to);
// 内容
$mail->isHTML(true);
$mail->Subject = $subject;
$mail->Body = $message;
$mail->AltBody = strip_tags($message);
return $mail->send();
} catch (Exception $e) {
error_log("邮件发送失败: " . $mail->ErrorInfo);
return false;
}
}
function sendVerificationEmail($email, $username, $verification_code) {
$verification_link = SITE_URL . "/verify.php?code=" . $verification_code;
$subject = SITE_NAME . " - 邮箱验证";
$message = "
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { background: #3498db; color: white; padding: 20px; text-align: center; }
.content { padding: 20px; background: #f9f9f9; }
.button { display: inline-block; padding: 12px 24px; background: #3498db; color: white; text-decoration: none; border-radius: 5px; }
.footer { text-align: center; padding: 20px; color: #666; }
</style>
</head>
<body>
<div class='container'>
<div class='header'>
<h1>" . SITE_NAME . "</h1>
</div>
<div class='content'>
<h2>亲爱的 {$username}</h2>
<p>感谢您注册" . SITE_NAME . "图床!</p>
<p>请点击下面的按钮验证您的邮箱地址:</p>
<p style='text-align: center;'>
<a href='{$verification_link}' class='button'>验证邮箱</a>
</p>
<p>如果按钮无法点击,请复制以下链接到浏览器地址栏:</p>
<p><small>{$verification_link}</small></p>
<p>此验证链接 24 小时内有效。</p>
</div>
<div class='footer'>
<p>&copy; " . date('Y') . " " . SITE_NAME . ". 保留所有权利.</p>
</div>
</div>
</body>
</html>";
return sendEmail($email, $subject, $message);
}
function sendPasswordResetEmail($email, $username, $token) {
$reset_link = SITE_URL . "/reset-password.php?token=" . $token;
$subject = SITE_NAME . " - 密码重置";
$message = "
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { background: #e74c3c; color: white; padding: 20px; text-align: center; }
.content { padding: 20px; background: #f9f9f9; }
.button { display: inline-block; padding: 12px 24px; background: #e74c3c; color: white; text-decoration: none; border-radius: 5px; }
.footer { text-align: center; padding: 20px; color: #666; }
.warning { background: #fff3cd; border: 1px solid #ffeaa7; padding: 10px; border-radius: 5px; margin: 15px 0; }
</style>
</head>
<body>
<div class='container'>
<div class='header'>
<h1>" . SITE_NAME . " - 密码重置</h1>
</div>
<div class='content'>
<h2>亲爱的 {$username}</h2>
<p>我们收到了您重置密码的请求。</p>
<p>请点击下面的按钮重置您的密码:</p>
<p style='text-align: center;'>
<a href='{$reset_link}' class='button'>重置密码</a>
</p>
<p>如果按钮无法点击,请复制以下链接到浏览器地址栏:</p>
<p><small>{$reset_link}</small></p>
<div class='warning'>
<strong>注意:</strong>此链接在 <font color='red'>1</font> 小时内有效。如果您没有请求重置密码,请忽略此邮件。
</div>
</div>
<div class='footer'>
<p>&copy; " . date('Y') . " " . SITE_NAME . ". 保留所有权利.</p>
</div>
</div>
</body>
</html>";
return sendEmail($email, $subject, $message);
}
function sendEmailNotification($user_id, $subject, $message) {
global $pdo;
// 获取用户邮箱和设置
$stmt = $pdo->prepare("
SELECT u.email, us.email_notifications
FROM users u
LEFT JOIN user_settings us ON u.id = us.user_id
WHERE u.id = ?
");
$stmt->execute([$user_id]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$user || !$user['email_notifications']) {
return false;
}
return sendEmail($user['email'], $subject, $message);
}
$currentUserSettings = isset($_SESSION['user_id']) ? getUserSettings($_SESSION['user_id']) : [
'dark_mode' => false,
'language' => $lang,
'items_per_page' => 20,
'email_notifications' => true,
'browser_notifications' => true
];
if (!isset($_SESSION['user_id'])) {
$currentUserSettings['dark_mode'] = isset($_COOKIE['dark_mode']) ? (bool)$_COOKIE['dark_mode'] : false;
$currentUserSettings['language'] = $lang;
}
?>