<?php
/**
 * فایل مبدأ — ساخته‌شده توسط ابزار انتقال پشتیبان
 * این فایل را در ریشهٔ سایت مبدأ (کنار wp-content) آپلود کنید.
 * فقط پوشهٔ duplicator-backups را برای ابزار مقصد در دسترس می‌گذارد.
 * بعد از پایان انتقال این فایل را حذف کنید.
 */
@set_time_limit(0);
@ini_set('display_errors', '0');
error_reporting(0);

$TOKEN = '';

$cands = array(
    __DIR__ . '/wp-content/duplicator-backups',
    __DIR__ . '/public_html/wp-content/duplicator-backups',
    dirname(__DIR__) . '/wp-content/duplicator-backups',
    dirname(__DIR__) . '/public_html/wp-content/duplicator-backups',
);
if (!empty($_SERVER['DOCUMENT_ROOT'])) {
    array_unshift($cands, rtrim(str_replace('\\', '/', $_SERVER['DOCUMENT_ROOT']), '/') . '/wp-content/duplicator-backups');
}
$base = '';
foreach ($cands as $c) {
    if (is_dir($c)) { $base = realpath($c); break; }
}

function out_json($a, $code = 200) {
    http_response_code($code);
    header('Content-Type: application/json; charset=utf-8');
    header('Cache-Control: no-store');
    echo json_encode($a);
    exit;
}

if ($TOKEN !== '') {
    $t = isset($_GET['t']) ? (string)$_GET['t'] : '';
    $same = function_exists('hash_equals') ? hash_equals($TOKEN, $t) : ($TOKEN === $t);
    if (!$same) { out_json(array('ok' => 0, 'err' => 'forbidden'), 403); }
}

$a = isset($_GET['a']) ? (string)$_GET['a'] : 'list';

if ($a === 'ping') { out_json(array('ok' => 1, 'dir' => ($base !== '') ? 1 : 0)); }
if ($a === 'del')  { $r = @unlink(__FILE__); out_json(array('ok' => $r ? 1 : 0)); }
if ($base === '')  { out_json(array('ok' => 0, 'err' => 'duplicator-backups folder not found'), 404); }

if ($a === 'list') {
    $files = array();
    $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($base, FilesystemIterator::SKIP_DOTS));
    foreach ($it as $f) {
        if (!$f->isFile()) { continue; }
        $rel = str_replace('\\', '/', substr($f->getPathname(), strlen($base) + 1));
        $bn  = basename($rel);
        if ($bn[0] === '.' || strtolower($bn) === 'index.php' || substr($bn, -5) === '.part') { continue; }
        $files[] = array('name' => $rel, 'size' => (int)$f->getSize(), 'date' => date('Y-m-d H:i:s', $f->getMTime()));
    }
    usort($files, function($x, $y) { return strcmp($x['name'], $y['name']); });
    out_json(array('ok' => 1, 'dir' => basename($base), 'files' => $files));
}

if ($a === 'get') {
    $rel = isset($_GET['f']) ? str_replace('\\', '/', (string)$_GET['f']) : '';
    $p = ($rel !== '') ? realpath($base . '/' . $rel) : false;
    if ($p === false || !is_file($p) || strpos($p, $base . DIRECTORY_SEPARATOR) !== 0) {
        out_json(array('ok' => 0, 'err' => 'not found'), 404);
    }
    $size = filesize($p);
    $start = 0; $end = $size - 1; $code = 200;
    if (isset($_SERVER['HTTP_RANGE']) && preg_match('/bytes=(\d*)-(\d*)/', $_SERVER['HTTP_RANGE'], $m)) {
        if ($m[1] !== '') {
            $start = (int)$m[1];
            if ($m[2] !== '') { $end = min((int)$m[2], $size - 1); }
        } elseif ($m[2] !== '') {
            $start = max(0, $size - (int)$m[2]);
        }
        if ($start > $end || $start >= $size) {
            header('Content-Range: bytes */' . $size);
            http_response_code(416);
            exit;
        }
        $code = 206;
    }
    while (ob_get_level() > 0) { @ob_end_clean(); }
    http_response_code($code);
    header('Content-Type: application/octet-stream');
    header('Accept-Ranges: bytes');
    header('Content-Length: ' . ($end - $start + 1));
    if ($code === 206) { header('Content-Range: bytes ' . $start . '-' . $end . '/' . $size); }
    header('Content-Disposition: attachment; filename="' . basename($p) . '"');
    $fh = fopen($p, 'rb');
    fseek($fh, $start);
    $left = $end - $start + 1;
    while ($left > 0 && !feof($fh)) {
        $d = fread($fh, min(1048576, $left));
        if ($d === false || $d === '') { break; }
        echo $d;
        $left -= strlen($d);
        flush();
    }
    fclose($fh);
    exit;
}

out_json(array('ok' => 0, 'err' => 'bad action'), 400);