17. Sık Yapılan Hatalar

Bu sayfa, DLE 21.0 kaynak kodu incelenerek çıkarılmış gerçek tuzakların listesidir. Her madde, ya sessizce başarısız olan ya da beklenmedik sonuç üreten bir davranışı anlatır.

i
Bu sayfayı yazdırın Eklenti geliştirmeye başlamadan önce bir kez baştan sona okuyun. Buradaki maddelerin çoğu, saatler süren hata ayıklamanın önüne geçer.

1. Kurulum ve manifest tuzakları

1.1 Giriş noktalarını yamalamak

Hata: index.php, admin.php veya cron.php dosyasına yama yazmak.
Neden çalışmaz: Bu dosyalar DLEPlugins::Check() ile yüklenmez. Yama diske başarıyla yazılır, hata da vermez — ama hiç çalışmaz.
Çözüm: En erken nokta olarak engine/init.php kullanın.

1.2 create / replaceall ile dosyayı ezmek

Hata: Var olan bir dosyaya action="create" uygulamak.
Neden: create ve replaceall aynı kod yoludur ve dosyanın tüm içeriğini replacecode ile değiştirir. "Dosya yoksa oluştur" anlamına gelmez.
Çözüm: Mevcut dosyaları düzenlemek için replace, before veya after kullanın.

1.3 PHP bloklarının içine <?php yazmak

Hata: <phpinstall> içine <?php ile başlayan kod yazmak.
Neden: Bu bloklar eval() edilir; kapanış/etiketler sözdizimi hatası üretir.
Çözüm: Doğrudan kodun kendisini yazın, etiketsiz.

1.4 Dosya yolunu yanlış yere yazmak

Hata: <file><name>engine/modules/x.php</name></file>
Neden: Dosya yolu bir özniteliktir; alt etiket değildir.
Çözüm: <file name="engine/modules/x.php">

1.5 searchcount'u unutmak

Hata: Kısa bir çapa seçip searchcount yazmamak.
Neden: Çapa dosyada kaç kez geçiyorsa yama o kadar kez uygulanır.
Çözüm: Uzun çapa seçin ve <searchcount>1</searchcount> yazın.

1.6 versioncompare için uydurma değer yazmak

Hata: <versioncompare>bigger</versioncompare> gibi bir değer.
Neden: Tanınmayan değerler boş kabul edilir; sürüm kapısı sessizce devre dışı kalır.
Çözüm: Yalnızca greater, less, >=, <=, == kullanın.

1.7 Güncellemede mysqlinstall beklemek

Hata: Tablo oluşturmayı yalnızca mysqlinstall içine yazmak, sonra eklentiyi güncellemek.
Neden: Güncelleme yolunda yalnızca mysqlupgrade çalışır; mysqlinstall çalışmaz.
Çözüm: CREATE TABLE IF NOT EXISTS kullanın veya SQL'i iki bloğa da yazın.

1.8 Silmede mysqldisable beklemek

Hata: Tabloyu mysqldisable içinde düşürmek.
Neden: Silme işlemi mysqldisable'ı çalıştırmaz; yalnızca mysqldelete çalışır.
Çözüm: DROP TABLE ifadenizi mysqldelete içine koyun.

1.9 filedelete'in her zaman çalışacağını sanmak

Hata: <filedelete>1</filedelete> yazıp dosyaların silineceğini varsaymak.
Neden: Silinecek dosya listesi yalnızca ZIP ile kurulumda dolar. Manifesti yapıştırarak kurduysanız liste boştur.
Çözüm: Garanti için <phpdelete> içinde @unlink() kullanın.

1.10 Şablon, CSS ve JS'i yamalamaya çalışmak

Hata: templates/x/main.tpl dosyasına <operation> yazmak.
Neden: Yama motoru yalnızca .php ve .lng uzantılarını kabul eder. Diğerleri sessizce atlanır.
Çözüm: Bu dosyaları ZIP içinde normal dosya olarak gönderin.

2. Çapa (anchor) tuzakları

2.1 Çapayı elle yazmak

Hata: Çapayı ezberden veya elle yazmak.
Neden: Boşluklar esnektir, ama harfler değildir. Tek harflik bir fark eşleşmeyi bozar ve hiçbir uyarı çıkmaz.
Çözüm: Hedef dosyadan seçip kopyalayın.

2.2 Başka bir eklentinin kodunu çapa yapmak

Hata: Başka bir eklentinin eklediği satırı searchcode yapmak.
Neden: O eklenti kapatıldığında/ silindiğinde sizinki de sessizce çalışmaz hâle gelir.
Çözüm: Yalnızca DLE çekirdeğine ait satırları çapa seçin.

2.3 Çok satırlı çapada araya kod girmesi

Hata: İki satırlı çapa yazmak; ama dosyada bu iki satırın arasında başka bir satır var.
Neden: Satırlar arasına yalnızca boşluk girebilir; kod giremez.
Çözüm: Tek satırlık çapa kullanın veya aralarında hiçbir şey olmayan satırları seçin.

2.4 Çapada regex beklemek

Hata: <searchcode>$\w+-\>query\( gibi desen yazmak.
Neden: preg_quote() tüm özel karakterleri kaçırır; çapa her zaman düz metin olarak aranır.
Çözüm: Tam, gerçek kodu yazın. Ayrıntı: Çapa Sanatı.

3. Kod ve mimari tuzakları

3.1 Check()'in aktiflik kontrol ettiğini sanmak

Hata: if (DLEPlugins::Check($dosya)) ile "bu eklenti aktif mi?" sorgulamak.
Neden: Check() her zaman bir yol döndürür (yamalı kopya ya da orijinal). Aktiflik kontrolü yapmaz.
Çözüm: Aktiflik için DLEPlugins::CheckIFActive('eklenti-adi') kullanın. Check() yalnızca include/require içinde kullanılmalıdır.

3.2 Önbellek klasörünün yazılamaması

Hata: Sunucuda engine/cache/system/plugins/ klasörü yazılamaz.
Neden: DLE yamaları bu klasöre gerçek dosya olarak yazar. Klasör yazılamıyorsa hiçbir eklenti çalışmaz.
Çözüm: engine/cache/system/ ve engine/cache/system/plugins/ klasörlerine 777 verin. Panel ana sayfasında kırmızı bir uyarı görünür.

3.3 Şablon etiketini eklemeyi unutmak

Hata: Modül {benim_kutum} etiketini üretiyor, ama şablonda bu etiket yok.
Neden: DLE etiketi yalnızca şablonda yer tutucu varsa değiştirir.
Çözüm: Etiketi phpinstall bloğunda şablona otomatik ekleyin veya kurulum adımlarında kullanıcıya açıkça söyleyin.

3.4 Hedef dosyayı elle düzenlemek

Hata: Çalışan eklentinin kodunu engine/modules/x.php içinde elle değiştirmek.
Neden: DLE, orijinal dosyadan yamalı kopya üretir. Orijinali elle değiştirirseniz bir sonraki önbellek yenilemesinde değişikliğiniz kaybolur veya kopyaya yansımaz.
Çözüm: Tüm değişiklikleri manifest üzerinden yapın, sonra eklentiyi yeniden kurun.

3.5 Kurulumdan sonra önbelleği yenilememek

Hata: Manifestte değişiklik yapıp eklentiyi yeniden kurmamak.
Neden: Yamalar önbellekte tutulur ve yalnızca kurulum/güncelleme/açma-kapama sırasında yeniden üretilir.
Çözüm: Manifest değiştiyse eklentiyi yeniden yükleyin.

4. Güvenlik tuzakları

4.1 AJAX işleyicisinde user_hash denetimi yapmamak

Hata: engine/ajax/benim.php dosyasında CSRF korumasını atlamak.
Neden: DLE'nin AJAX yönlendiricisi merkezî bir CSRF denetimi yapmaz. Her modül kendi user_hash kontrolünü kendisi yapar. Bunu atlarsanız işleyiciniz siteler arası istek sahteciliğine açık olur.
Çözüm: Her işleyicinin başına şu denetimi koyun:

if (!isset($_REQUEST['user_hash']) || !$_REQUEST['user_hash'] || $_REQUEST['user_hash'] != $dle_login_hash) {
    die('error');
}

4.2 Yönetim modülünde yetki grubu denetimi yapmamak

Hata: engine/inc/benim-eklentim.php dosyasını, hangi kullanıcı grubunun erişebileceğini kontrol etmeden çalıştırmak.
Neden: Yönetim paneli modülleri, _admin_sections tablosundaki allow_groups alanına göre kısıtlanır. Kendi denetiminizi koymazsanız modülünüz herkese açık kalabilir.
Çözüm: allow_groups alanını doğru doldurun ve modül başında yetki denetimi yapın.

4.3 SQL'de kullanıcı girdisini doğrudan kullanmak

Hata: "... WHERE id = '{$_GET['id']}'"
Neden: SQL enjeksiyonu.
Çözüm: Değerleri $db->safesql() ile süzün, sayısal değerleri intval() ile zorlayın.

4.4 cron.php'yi açarken korumayı unutmak

Durum: cron.php varsayılan olarak kapalıdır ($allow_cron = 0) ve çağrılırsa 403 döner. Dosya "açıkta" gelmez.
Risk: Onu açtığınızda ($allow_cron = 1) dosya hiçbir ek kimlik doğrulaması yapmaz — ne anahtar ister, ne oturum kontrol eder. Adrese erişen herkes görevi tetikleyebilir.
Çözüm: DLE'nin kendi önerisine uyun: görevi komut satırından çalıştırın ve dosyayı tahmin edilemez bir adla yeniden adlandırın. Ek olarak IP kısıtlaması koyun.

5. Yanlış bilgi (mit) listesi

İnternetteki DLE eklenti rehberlerinde sık tekrarlanan, ama DLE 21.0 kaynak kodunda karşılığı olmayan ifadeler:

Yanlış iddiaGerçek
"Modern Shell" diye bir katman var. Böyle bir sınıf veya kavram yoktur. Mekanizmanın adı yamalı kopya'dır.
"Sanal dosya sistemi" / "Virtual FS" eklentileri izole eder. Böyle bir sistem yoktur. Eklenti, dosyanın kopyasını yamalar.
Eklentiler /public/assets/ klasörüne yüklenir. Böyle bir klasör yoktur. Statik dosyalar public/ altındaki ilgili klasörlere gider.
Ek alanlar (xfields) artık JSON olarak saklanıyor. Yanlıştır. Veri hâlâ alan|deger||alan2|deger2 biçiminde, çoklu değerler \x01 ile ayrılmış olarak metin sütununda durur.
Bildirim için DLEPush.success() kullanılır. Böyle bir metot yoktur. Yalnızca DLEPush.info, DLEPush.warning ve DLEPush.error vardır. Başarı mesajı için info kullanın.
AJAX'ta merkezî CSRF koruması vardır. Yoktur. Her modül user_hash kontrolünü kendi yapar. Ayrıca AJAX yanıt başlığı sabit text/html'dir.
Eklenti sistemi tüm dosyaları yamalayabilir. Yalnızca .php ve .lng; ayrıca giriş noktaları ve korumalı dosyalar hariç.

Hızlı kontrol listesi

Yayına almadan önce şunları doğrulayın:

  • Manifest ZIP'in kökünde ve adı *.xml.
  • Tüm <file name="..."> yolları site köküne göreli ve .php/.lng.
  • Hedef dosyaların hiçbiri giriş noktası veya korumalı dosya değil.
  • Her <operation> için doğru action ve gerekli alanlar var.
  • Çapalar kopyalanmış, uzun ve (tercihen) searchcount verilmiş.
  • PHP bloklarında <?php yok.
  • SQL bloklarında yer tutucular ({prefix}, {engine}, …) kullanılmış.
  • Güncelleme senaryosu test edildi (mysqlupgrade).
  • Silme senaryosu test edildi (mysqldelete, phpdelete).
  • Kurulumdan sonra Eklentiler → Hataları göster temiz.
  • AJAX işleyicilerinde user_hash denetimi var.
  • SQL sorgularında $db->safesql() kullanılmış.

Doğrulamayı otomatikleştirmek için: Doğrulama Araçları.