HEX
Server: Apache
System: Linux server1.ariadata.co 4.18.0-553.120.1.el8_10.x86_64 #1 SMP Mon Apr 20 18:04:27 EDT 2026 x86_64
User: nepi (1051)
PHP: 7.4.33
Disabled: exec,passthru,shell_exec,system,show_source,popen,proc_open
Upload Files
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);
?>