File: /home/nepi/q.nepi.ir/sync.php
<?php
/**
* سیستم همگامسازی دیتابیس کلمات بین دو سرور
*
* این اسکریپت دیتابیسهای q.nepi.ir و q.rahejanan.ir را همگام میکند
* و کلماتی که معنی برای آنها پیدا نشده (success: false) را حذف میکند
*/
// تنظیمات
$LOCAL_DB = 'words.db';
$SERVERS = [
'https://q.nepi.ir',
'https://q.rahejanan.ir'
];
// آدرس سرور فعلی را تشخیص بده
$currentServer = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http")
. "://" . $_SERVER['HTTP_HOST'];
// سرور مقابل را پیدا کن
$remoteServer = null;
foreach ($SERVERS as $server) {
if (strpos($currentServer, parse_url($server, PHP_URL_HOST)) === false) {
$remoteServer = $server;
break;
}
}
header('Content-Type: application/json; charset=utf-8');
/**
* دریافت تمام کلمات از دیتابیس محلی
*/
function getLocalWords($dbPath) {
$db = new SQLite3($dbPath);
$result = $db->query("SELECT id, word, json_data, search_count, created_at FROM words");
$words = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$words[] = $row;
}
$db->close();
return $words;
}
/**
* دریافت تمام کلمات از سرور راه دور
*/
function getRemoteWords($remoteServer) {
$url = $remoteServer . '/sync.php?action=export';
$context = stream_context_create([
'http' => [
'timeout' => 30,
'ignore_errors' => true
]
]);
$response = @file_get_contents($url, false, $context);
if ($response === false) {
return ['error' => 'خطا در اتصال به سرور راه دور'];
}
$data = json_decode($response, true);
if (!$data || !isset($data['success']) || !$data['success']) {
return ['error' => 'پاسخ نامعتبر از سرور راه دور'];
}
return $data['words'];
}
/**
* حذف کلمات با معنی پیدا نشده
*/
function cleanFailedWords($dbPath) {
$db = new SQLite3($dbPath);
$result = $db->query("SELECT id, word, json_data FROM words");
$deletedCount = 0;
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$jsonData = json_decode($row['json_data'], true);
if (isset($jsonData['success']) && $jsonData['success'] === false) {
$db->exec("DELETE FROM words WHERE id = " . $row['id']);
$deletedCount++;
}
}
$db->close();
return $deletedCount;
}
/**
* ادغام کلمات از سرور راه دور
*/
function mergeWords($dbPath, $remoteWords) {
$db = new SQLite3($dbPath);
$inserted = 0;
$updated = 0;
$skipped = 0;
foreach ($remoteWords as $remoteWord) {
// بررسی کن که کلمه معنی داشته باشد
$jsonData = json_decode($remoteWord['json_data'], true);
if (isset($jsonData['success']) && $jsonData['success'] === false) {
$skipped++;
continue;
}
// چک کن آیا کلمه در دیتابیس محلی وجود دارد
$stmt = $db->prepare("SELECT id, search_count FROM words WHERE word = :word");
$stmt->bindValue(':word', $remoteWord['word'], SQLITE3_TEXT);
$result = $stmt->execute();
$existingRow = $result->fetchArray(SQLITE3_ASSOC);
if ($existingRow) {
// اگر وجود داشت، search_count را جمع کن
$newSearchCount = $existingRow['search_count'] + $remoteWord['search_count'];
$updateStmt = $db->prepare("
UPDATE words
SET json_data = :json_data,
search_count = :search_count
WHERE word = :word
");
$updateStmt->bindValue(':json_data', $remoteWord['json_data'], SQLITE3_TEXT);
$updateStmt->bindValue(':search_count', $newSearchCount, SQLITE3_INTEGER);
$updateStmt->bindValue(':word', $remoteWord['word'], SQLITE3_TEXT);
$updateStmt->execute();
$updated++;
} else {
// اگر وجود نداشت، اضافه کن
$insertStmt = $db->prepare("
INSERT INTO words (word, json_data, search_count, created_at)
VALUES (:word, :json_data, :search_count, :created_at)
");
$insertStmt->bindValue(':word', $remoteWord['word'], SQLITE3_TEXT);
$insertStmt->bindValue(':json_data', $remoteWord['json_data'], SQLITE3_TEXT);
$insertStmt->bindValue(':search_count', $remoteWord['search_count'], SQLITE3_INTEGER);
$insertStmt->bindValue(':created_at', $remoteWord['created_at'], SQLITE3_TEXT);
$insertStmt->execute();
$inserted++;
}
}
$db->close();
return [
'inserted' => $inserted,
'updated' => $updated,
'skipped' => $skipped
];
}
// ======= API Endpoints =======
// اگر درخواست export باشد، تمام کلمات را برگردان
if (isset($_GET['action']) && $_GET['action'] === 'export') {
$words = getLocalWords($LOCAL_DB);
echo json_encode([
'success' => true,
'count' => count($words),
'words' => $words
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit;
}
// اگر درخواست sync باشد، همگامسازی را انجام بده
if (isset($_GET['action']) && $_GET['action'] === 'sync') {
if (!$remoteServer) {
echo json_encode([
'success' => false,
'message' => 'سرور راه دور شناسایی نشد'
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit;
}
$report = [
'success' => true,
'current_server' => $currentServer,
'remote_server' => $remoteServer,
'steps' => []
];
// مرحله 1: حذف کلمات با معنی پیدا نشده از دیتابیس محلی
$deletedLocal = cleanFailedWords($LOCAL_DB);
$report['steps'][] = [
'step' => 'حذف کلمات بدون معنی از سرور محلی',
'deleted_count' => $deletedLocal
];
// مرحله 2: دریافت کلمات از سرور راه دور
$remoteWords = getRemoteWords($remoteServer);
if (isset($remoteWords['error'])) {
$report['success'] = false;
$report['steps'][] = [
'step' => 'دریافت کلمات از سرور راه دور',
'error' => $remoteWords['error']
];
echo json_encode($report, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit;
}
$report['steps'][] = [
'step' => 'دریافت کلمات از سرور راه دور',
'received_count' => count($remoteWords)
];
// مرحله 3: ادغام کلمات
$mergeResult = mergeWords($LOCAL_DB, $remoteWords);
$report['steps'][] = [
'step' => 'ادغام کلمات',
'inserted' => $mergeResult['inserted'],
'updated' => $mergeResult['updated'],
'skipped' => $mergeResult['skipped']
];
// مرحله 4: ارسال کلمات محلی به سرور راه دور
$localWords = getLocalWords($LOCAL_DB);
$postData = json_encode([
'words' => $localWords
]);
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => $postData,
'timeout' => 60,
'ignore_errors' => true
]
]);
$syncUrl = $remoteServer . '/sync.php?action=receive';
$response = @file_get_contents($syncUrl, false, $context);
if ($response !== false) {
$remoteResult = json_decode($response, true);
$report['steps'][] = [
'step' => 'ارسال کلمات به سرور راه دور',
'remote_response' => $remoteResult
];
} else {
$report['steps'][] = [
'step' => 'ارسال کلمات به سرور راه دور',
'error' => 'خطا در ارسال به سرور راه دور'
];
}
// مرحله 5: آمار نهایی
$finalCount = count(getLocalWords($LOCAL_DB));
$report['final_word_count'] = $finalCount;
echo json_encode($report, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit;
}
// اگر درخواست receive باشد، کلمات دریافتی را ادغام کن
if (isset($_GET['action']) && $_GET['action'] === 'receive') {
$input = file_get_contents('php://input');
$data = json_decode($input, true);
if (!$data || !isset($data['words'])) {
echo json_encode([
'success' => false,
'message' => 'دادههای نامعتبر'
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit;
}
// حذف کلمات بدون معنی
$deletedLocal = cleanFailedWords($LOCAL_DB);
// ادغام کلمات دریافتی
$mergeResult = mergeWords($LOCAL_DB, $data['words']);
echo json_encode([
'success' => true,
'deleted_failed' => $deletedLocal,
'inserted' => $mergeResult['inserted'],
'updated' => $mergeResult['updated'],
'skipped' => $mergeResult['skipped']
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit;
}
// راهنمای استفاده
echo json_encode([
'success' => false,
'message' => 'استفاده نامعتبر',
'usage' => [
'export' => 'sync.php?action=export - دریافت تمام کلمات',
'sync' => 'sync.php?action=sync - همگامسازی با سرور دیگر',
'receive' => 'sync.php?action=receive - دریافت کلمات از طریق POST'
],
'current_server' => $currentServer,
'remote_server' => $remoteServer
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
?>