SMF Forumlar İçin Print Screen İle Resmi Yükleme

Print screen tuşuyla ekran görüntüsü alıyoruz. Bu görüntüyü Windows işletim sisteminde Paint gibi programlarda yapıştır tuşunu kullanarak ve kaydederek, sonra da bir yere yükleyerek paylaşabiliyoruz.

Peki bu işlemi SMF forumlarda nasıl yaparız?

Yani görüntüyü alıp, Paint'i kullanıp, en son kaydedilen resmi bir yere yüklemekle uğraşmak yerine; doğrudan print screen tuşuna basıp görüntüyü Ctrl+V ile yapıştır yaparak foruma görüntüyü yüklemek aşağıdaki kod ile mümkün. Kod benim eserim.

ÖNEMLİ: Aşağıda verdiğim kodlar hızlı cevapta çalışmıyor!

Yapacağınız şey şu: temanızın script.js dosyasına aşağıdaki kodu ekleyin.

JavaScript
//print screen
document.addEventListener('paste', function(e) {
    // Panodan veri al
    const items = (e.clipboardData || e.originalEvent.clipboardData).items;
    for (let item of items) {
        if (item.type.indexOf('image') !== -1) {
            // Görüntü dosyasını al
            const blob = item.getAsFile();
            const formData = new FormData();
            formData.append('image', blob, 'screenshot.png');

            // AJAX ile sunucuya yükle
            fetch('upload_image.php', {
			method: 'POST',
			body: formData,
			headers: {
			'X-SMF-Token': smf_session_id || ''
			},
			credentials: 'same-origin'
			})
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    // BBCode formatını [url][img][/url] olarak güncelle
                    const bbcode = `[url=${data.url}][img]${data.url}[/img][/url]`;
                    
                    // SCEditor kontrolü
                    const editor = typeof sceditor !== 'undefined' ? sceditor.instance(document.querySelector('textarea[name="message"]')) : null;
                    if (editor) {
                        // Normal yanıt için SCEditor'a ekle
                        editor.insert(bbcode);
                    } else {
                        // Hızlı yanıt için textarea'ya ekle
                        const textarea = document.querySelector('textarea[name="message"], textarea[name="quickReply"]');
                        if (textarea) {
                            textarea.value += bbcode + '\n';
                        } else {
                            alert('Metin alanı bulunamadı.');
                        }
                    }
                } else {
                    alert('Görüntü yüklenemedi: ' + data.error);
                }
            })
            .catch(error => {
                console.error('Hata:', error);
                alert('Bir hata oluştu.');
            });
        }
    }
});

Ardından bir upload_image.php dosyası oluşturup yine aşağıdaki ikinci kodu bu dosya içine ekleyin ve bu dosyayı forum ana dizinine atın.

upload_image.php:

PHP
<?php
require_once('SSI.php');

// Yanıtı JSON formatında göndereceğimizi belirtelim.
header('Content-Type: application/json');

// Güvenlik kontrolü: Sadece oturum açmış kullanıcılar dosya yükleyebilir.
if ($context['user']['is_guest']) {
    // Oturum açılmamışsa yetkisiz erişim hatası ver ve işlemi sonlandır.
    http_response_code(401); // Unauthorized
    die(json_encode(['success' => false, 'error' => 'Bu işlemi yapmak için oturum açmanız gerekiyor.']));
}

// CSRF token kontrolü
if (!isset($_SERVER['HTTP_X_SMF_TOKEN']) || $_SERVER['HTTP_X_SMF_TOKEN'] !== $context['session_id']) {
    http_response_code(403); // Forbidden
    die(json_encode(['success' => false, 'error' => 'Geçersiz oturum tokenı.']));
}

// Temel dosya yükleme kontrolü
if (!isset($_FILES['image']) || !is_uploaded_file($_FILES['image']['tmp_name'])) {
    http_response_code(400); // Bad Request
    die(json_encode(['success' => false, 'error' => 'Yüklenecek dosya bulunamadı.']));
}

// Yükleme sırasında bir hata oluşup oluşmadığını kontrol et
if ($_FILES['image']['error'] !== UPLOAD_ERR_OK) {
    http_response_code(400); // Bad Request
    die(json_encode(['success' => false, 'error' => 'Dosya yüklenirken bir hata oluştu.']));
}

// Rate limiting kontrolü (isteğe bağlı, gerekirse aktif edin)
// Örnek: Kullanıcı başına son 1 dakikada max 5 yükleme
// if (checkRateLimit($context['user']['id'], 5, 60)) {
//     http_response_code(429); // Too Many Requests
//     die(json_encode(['success' => false, 'error' => 'Çok fazla yükleme denemesi. Lütfen bir süre bekleyin.']));
// }

try {
    // 1. Dosya Boyutu Kontrolü
    $max_size = 5 * 1024 * 1024; // 5 MB
    if ($_FILES['image']['size'] > $max_size) {
        throw new RuntimeException('Dosya boyutu çok büyük. Maksimum 5 MB olmalıdır.');
    }

    // 2. Güvenilir Dosya Türü Kontrolü (MIME ve içerik analizi)
    // getimagesize() fonksiyonu, dosyanın gerçekten bir resim olup olmadığını kontrol eder.
    // Eğer dosya geçerli bir resim değilse 'false' döndürür.
    $image_info = @getimagesize($_FILES['image']['tmp_name']);
    if ($image_info === false) {
        throw new RuntimeException('Geçersiz dosya formatı. Yalnızca resim dosyaları yüklenebilir.');
    }

    // İzin verilen MIME türleri ve uzantılar
    $allowed_mime_types = [
        'image/jpeg' => 'jpg',
        'image/png' => 'png',
        'image/gif' => 'gif'
    ];
    
    // Dosyanın MIME türü izin verilenler listesinde mi?
    $file_mime_type = $image_info['mime'];
    if (!isset($allowed_mime_types[$file_mime_type])) {
        throw new RuntimeException('İzin verilmeyen resim türü. Sadece JPG, PNG veya GIF formatları kabul edilmektedir.');
    }
    
    // Dosya uzantısını doğrulanmış MIME türünden alalım.
    $file_extension = $allowed_mime_types[$file_mime_type];

    // Dosya adındaki uzantıyı kontrol et (ek güvenlik katmanı)
    $original_filename = strtolower($_FILES['image']['name']);
    if (!preg_match('/\.' . preg_quote($file_extension, '/') . '$/', $original_filename)) {
        throw new RuntimeException('Dosya uzantısı MIME türüyle eşleşmiyor.');
    }

} catch (Exception $e) {
    // Herhangi bir güvenlik kontrolü başarısız olursa hata mesajı göster ve çık.
    http_response_code(400); // Bad Request
    die(json_encode(['success' => false, 'error' => $e->getMessage()]));
}

// $boarddir ve $boardurl değişkenlerinin tanımlı olduğunu kontrol et
if (!isset($boarddir) || !isset($boardurl)) {
    http_response_code(500); // Internal Server Error
    die(json_encode(['success' => false, 'error' => 'Sunucu yapılandırması eksik.']));
}

// Dosya yükleme dizini ve URL'si
$upload_dir = rtrim($boarddir, '/') . '/uploads/';
$upload_url = rtrim($boardurl, '/') . '/uploads/';

// Dizin mevcut değilse, güvenli izinlerle oluştur
if (!is_dir($upload_dir)) {
    if (!mkdir($upload_dir, 0755, true) || !chmod($upload_dir, 0755)) {
        http_response_code(500); // Internal Server Error
        die(json_encode(['success' => false, 'error' => 'Yükleme dizini oluşturulamadı.']));
    }
}

// Benzersiz ve güvenli bir dosya adı oluştur
$random_string = bin2hex(random_bytes(8));
$file_name = 'img_' . time() . '_' . preg_replace('/[^a-zA-Z0-9]/', '', $random_string) . '.' . $file_extension;
$file_path = $upload_dir . $file_name;

// Dizin traversal saldırılarını önlemek için dosya yolunu kontrol et
if (strpos(realpath($upload_dir), realpath($boarddir)) !== 0) {
    http_response_code(500); // Internal Server Error
    die(json_encode(['success' => false, 'error' => 'Geçersiz dosya yolu.']));
}

// Güvenlik kontrollerinden geçmiş dosyayı geçici dizinden kalıcı dizine taşı
if (move_uploaded_file($_FILES['image']['tmp_name'], $file_path)) {
    // Başarılı: Dosyanın tam URL'sini döndür
    echo json_encode(['success' => true, 'url' => $upload_url . $file_name]);
} else {
    // Dosya taşıma sırasında bir sorun olursa
    http_response_code(500); // Internal Server Error
    die(json_encode(['success' => false, 'error' => 'Dosya sunucuya taşınırken bir hata oluştu.']));
}

Bu işlemleri yaptıktan sonra artık print screen tuşuna basıp, gelişmiş cevap alanında Ctrl+V yaptığınızda resim otomatik olarak foruma yüklenecek ve görünecek.

Videoyu izleyiniz: