7. Admin Panel Modülü

Yönetim paneli modülü, eklentinizin ayar ekranıdır. DLE'nin kendi paneli de aynı mekanizmayla çalışır: ?mod=<dosya adı> isteği, engine/inc/<dosya adı>.php dosyasını çalıştırır.

Panel isteği nasıl işlenir?

admin.php yalnızca 26 satırdır; asıl akış engine/inc/include/init.php içindedir:

// admin.php:25-26
require_once(ENGINE_DIR . '/classes/plugins.class.php');
require_once(DLEPlugins::Check(ENGINE_DIR . '/inc/include/init.php'));

Modül dosyasının çalıştırılması:

// engine/inc/include/init.php:637-650
} elseif ($is_loged_in) {
    if ( !$mod ) {
        include_once (DLEPlugins::Check(ENGINE_DIR . '/inc/main.php'));
    } elseif ( file_exists( DLEPlugins::Check(ENGINE_DIR . '/inc/' . $mod . '.php') ) ) {
        include_once (DLEPlugins::Check(ENGINE_DIR . '/inc/' . $mod . '.php'));
    } else {
        msg ( "error", $lang['index_denied'], $lang['mod_not_found'] );
    }
}
★
İyi haber: admin modülleri de yamalanabilir Yukarıda DLEPlugins::Check() kullanıldığına dikkat edin. Yani engine/inc/… dosyaları da eklenti yamasına açıktır. Yeni bir dosya oluşturmak yerine mevcut bir panele kod eklemek de mümkündür (ama önerilmez).

$mod değeri okunurken totranslit($mod, true, false) ile süzülür. Bu yüzden modül dosya adınız ASCII ve dosya adı güvenli olmalıdır: benim-eklentim.php iyi, Benim Eklentim.php kötü.

Modülü yönetim paneline bağlama

DLE, çekirdek dosyalarını düzenlemenize gerek kalmadan panele modül eklemenize izin verir. Bağlama iki parçadan oluşur: dosyayı doğru klasöre koymak ve menü kaydını açmak.

1. Zorunlu yerleşim: engine/inc/

Modül dosyanızı mutlaka engine/inc/ klasörüne koymalısınız. Yalnızca bu klasörde bulunan dosyalar bağlanabilir; başka bir klasördeki dosyaya ?mod= ile erişilemez.

DosyaAdres
engine/inc/mymod.phpadmin.php?mod=mymod
engine/inc/benim-eklentim.phpadmin.php?mod=benim-eklentim

Adres otomatik oluşur: dosya adını .php uzantısı olmadan ?mod= değerine yazmanız yeterlidir. Çekirdek dosyalarda (engine/engine.php, admin.php vb.) hiçbir değişiklik yapmanız gerekmez. Bu yaklaşımın en büyük avantajı güncellemeye dayanıklılıktır: DLE yeni sürüme güncellendiğinde, çekirdek dosyalara dokunmadığınız için modülünüz çalışmaya devam eder.

2. Menü kaydı: {prefix}_admin_sections

Modülünüz ?mod=mymod adresinden çalışsa bile, kullanıcı bu adresi elle yazmak zorunda kalır ve panel gezinmesinde görünmez. Panelde menüde çıkması için {prefix}_admin_sections tablosuna kayıt gerekir; panel menüsü tam olarak bu tablodan üretilir:

Sütunİçerik
nameModül dosyasının uzantısız adı; engine/inc/<name>.php ile birebir aynı olmalıdır. Tekildir (tabloda bu sütunda UNIQUE anahtar vardır).
titleMenüde görünen başlık
descrModülün kısa açıklaması (menüde başlığın altında görünür)
iconSimge dosyasının adı. DLE'nin resmî dokümanında önerilen boyut 70×70 pikseldir.
allow_groupsall (panele erişimi olan herkes) veya virgülle ayrılmış grup kimlikleri: 1,2,3

Tablo öneki (PREFIX) kurulumdan kuruluma değişebilir. Sabit yazmak yerine değeri engine/data/dbconfig.php dosyasından okuyun; eklenti paketlerinde ise {prefix} yer tutucusu kullanılır.

// engine/data/dbconfig.php içinde tanımlıdır
// (kurulumda yazılır: kurulum sırasında girdiğiniz önek)
define("PREFIX", "dle_");
define("USERPREFIX", "dle_");

tek bir kayıt eklemek için örnek sorgu:

INSERT INTO `dle_admin_sections` (`name`, `title`, `descr`, `icon`, `allow_groups`)
VALUES ('mymod', 'Test modülü', 'Burada test modülünün açıklaması yer alır', 'mymod.png', '1');

Bu sorgu çalıştıktan sonra modül, yönetim panelinde yalnızca yöneticiler için kaydedilmiş olur. Eklenti paketinde aynı işlem mysqlinstall bloğunda {prefix} yer tutucusuyla yapılır:

<mysqlinstall><![CDATA[
DELETE FROM `{prefix}_admin_sections` WHERE `name` = 'mymod';
INSERT INTO `{prefix}_admin_sections` (`name`, `title`, `descr`, `icon`, `allow_groups`)
VALUES ('mymod', 'Test modülü', 'Test modülü açıklaması', 'mymod.png', '1');
]]></mysqlinstall>
!
allow_groups bir yetki denetimi DEĞİLDİR Veritabanında grup belirtmek, diğer gruplardaki kullanıcıların modülü çalıştırmasını yasaklamaz ve engellemez. Bu alan yalnızca bölümün panel gezinmesinde ve bölüm listelerinde gösterilip gösterilmeyeceğini belirler. Adresi bilen yetkisiz bir yönetici admin.php?mod=mymod yazarak modülü yine açabilir.

Bu yüzden erişim ayrımını modül dosyanızın kendisi yapmak zorundadır: grup denetimini modül içinde yapın ve yalnızca izin verilen gruplar için çalışmasına izin verin. Ayrıntısı aşağıdaki Yetkilendirme bölümünde.

Modülde hazır gelen değişkenler

DeğişkenAçıklama
$dbVeritabanı nesnesi.
$configSistem ayarları dizisi.
$langPanel dil değişkenleri (adminpanel.lng).
$member_idPanele giriş yapan yöneticinin bilgileri.
$user_groupÜye gruplarının izin dizisi.
$cat_infoKategoriler.
$mod / $actionİstek parametreleri (süzülmüş).
$dle_login_hashCSRF anahtarı. Formlara gizli alan olarak konur.
$_TIME / $_IPSunucu zamanı ve yöneticinin IP'si.
$js_array / $css_arraySayfaya eklenecek JS/CSS dosyaları.
!
Hazır GELMEYEN iki nesne $tpl ve $parse panel modüllerine otomatik gelmez. Şablon veya BBCode işleme kullanacaksanız kendiniz oluşturun: $tpl = new dle_template(); ve $parse = new ParseFilter();

CSRF anahtarı nasıl üretilir?

// engine/inc/include/init.php:121-123
$_IP = get_ip();
$_TIME = time ();
$dle_login_hash = sha1(SECURE_AUTH_KEY . $_SERVER['HTTP_USER_AGENT']);

Yetkilendirme — iki katmanlıdır

DLE'de modül erişimi iki ayrı katmanda ele alınır ve ikisini de yapmak zorundasınız: biri menüde görünmeyi, diğeri doğrudan URL çağrısının engellenmesini belirler. Menü kaydı yetki yerine geçmez.

1. Kod içi izin denetimi (zorunlu)

Modülünüzün en başında, hiçbir şey yapmadan önce:

if (!defined('DATALIFEENGINE')) die('Hacking attempt!');

if (!$user_group[$member_id['user_group']]['admin_addnews']) {
    msg("error", $lang['index_denied'], $lang['index_denied']);
}

// veya yalnızca tam yönetici (grup 1) girsin:
// if ($member_id['user_group'] != 1) msg("error", $lang['addnews_denied'], $lang['db_denied']);

Kullanabileceğiniz hazır izin anahtarları (üye grupları tablosundaki admin_ alanları):

admin_addnews, admin_editnews, admin_comments, admin_categories, admin_editusers, admin_wordfilter, admin_xfields, admin_userfields, admin_static, admin_editvote, admin_newsletter, admin_blockip, admin_banners, admin_rss, admin_iptools, admin_rssinform, admin_googlemap, admin_tagscloud, admin_complaint, admin_links, admin_redirects, admin_meta

i
Kendi modülünüz için en pratik yol Kendinize yeni bir izin anahtarı eklemek yerine, çoğu eklenti $member_id['user_group'] != 1 denetimiyle yalnızca tam yöneticiye izin verir. Böylece üye grupları tablosuna dokunmanıza gerek kalmaz.

2. Menü görünürlüğü

Bu katman kullanıcı deneyimiyle ilgilidir: {prefix}_admin_sections kaydı olmayan bir modül panel menüsünde görünmez. Kaydın nasıl oluşturulacağı ve allow_groups alanının neden bir yetki denetimi olmadığı yukarıdaki Modülü yönetim paneline bağlama bölümünde anlatıldı.

!
Silmede menü kaydını unutmayın Eklenti kaldırılırken mysqldelete içinde admin_sections kaydını silmezseniz, panelde kırık bir menü bağlantısı kalır.

Başlık, breadcrumb ve mesajlar

echoheader($lang['benim_eklentim_baslik'], $lang['benim_eklentim_altbaslik']);

// … sayfa içeriği …

echofooter();

echoheader($header_title, $header_subtitle) panel başlığını ve breadcrumb'ı basar; $header_subtitle dizi verilirse her anahtar bir bağlantı olur. echofooter() parametre almaz. İkisi de engine/inc/include/functions.inc.php içinde tanımlıdır.

msg() — hazır mesaj ekranı

msg($type, $title, $text, $back = false);
$typeGörünüm
"error"Kırmızı uyarı
"warning"Sarı uyarı
"success"Yeşil onay
diğerMavi bilgi

msg() kendi başına echoheader() ve echofooter() çağırır ve betiği sonlandırır (die()). Yani ondan sonra kod yazmayın. $back parametresi bir "geri dön" bağlantısı ekler.

Panel formu ve ayar kaydetme

showRow() ve makeCheckBox() gibi yardımcılar global değildir — her modül bunları kendi içinde tanımlar. İhtiyacınız olanı kendi modülünüze kopyalayabilirsiniz; kaynak örnekleri engine/inc/options.php içindedir.

// Panel tablosu satırı basar
function showRow($title = "", $description = "", $field = "", $class = "") {
    if( $class ) { $class = " class=\"{$class}\""; }
    echo "<tr{$class}><td>{$title} {$description}</td><td>{$field}</td></tr>";
}

// Onay kutusu üretir
function makeCheckBox($name, $selected, $optional = false) {
    if (!$optional) { $optional = ""; }
    $selected = $selected ? "checked" : "";
    return "<input class=\"switch\" type=\"checkbox\" name=\"{$name}\" value=\"1\" {$selected} {$optional}>";
}
✕
Form gönderiminde CSRF denetimi şart DLE panelde user_hash olmadan hiçbir kaydetme işlemi yapmaz. Formunuza gizli alan ekleyin ve işleyicide doğrulayın:
<input type="hidden" name="user_hash" value="{$dle_login_hash}">

// İşleyicide:
if (!isset($_REQUEST['user_hash']) || !$_REQUEST['user_hash'] || $_REQUEST['user_hash'] != $dle_login_hash) {
    die("Hacking attempt! User not found");
}

Ayarlar nerede saklanır?

YöntemDeğerlendirme
Kendi tablonuz Önerilen Temiz, silinebilir, çakışmaz. {prefix}_benim_ayarlarim gibi bir tablo açın.
engine/data/config.php Dikkatli DLE'nin kendi paneli ayarlarını buraya yazar (var_export + file_put_contents + clear_cache()). Ancak bu dosya korunmalı çekirdek dosyasıdır ve yanlış yazılırsa site tamamen çöker.
Şablon içi gizli alan Önerilmez Kullanıcı şablonu güncellediğinde ayar kaybolur.

Tam örnek: ayar modülü

engine/inc/benim-eklentim.php:

if (!defined('DATALIFEENGINE')) die('Hacking attempt!');

if ($member_id['user_group'] != 1) {
    msg("error", $lang['addnews_denied'], $lang['db_denied']);
}

// --- Kaydetme ---
if ($action == "kaydet") {

    if (!isset($_REQUEST['user_hash']) || !$_REQUEST['user_hash'] || $_REQUEST['user_hash'] != $dle_login_hash) {
        die("Hacking attempt! User not found");
    }

    $limit = isset($_POST['limit']) ? intval($_POST['limit']) : 5;

    $db->query("DELETE FROM " . PREFIX . "_benim_ayarlarim WHERE `key` = 'limit'");
    $db->query("INSERT INTO " . PREFIX . "_benim_ayarlarim (`key`, `value`) VALUES ('limit', '{$limit}')");

    msg("success", $lang['benim_eklentim_baslik'], "Ayarlar kaydedildi.", "?mod=benim-eklentim");
}

// --- Formu göster ---
echoheader($lang['benim_eklentim_baslik'], $lang['benim_eklentim_altbaslik']);

$row   = $db->super_query("SELECT value FROM " . PREFIX . "_benim_ayarlarim WHERE `key` = 'limit'");
$limit = isset($row['value']) ? intval($row['value']) : 5;

echo "<form action=\"?mod=benim-eklentim&action=kaydet\" method=\"post\">";
echo "<input type=\"hidden\" name=\"user_hash\" value=\"{$dle_login_hash}\">";
echo "<label>Kutu kayıt sayısı: <input type=\"number\" name=\"limit\" value=\"{$limit}\" min=\"1\" max=\"50\"></label>";
echo "<button type=\"submit\" class=\"btn bg-primary-400\">Kaydet</button>";
echo "</form>";

echofooter();
★
Panel dil metinlerini adminpanel.lng'ye ekleyin $lang['benim_eklentim_baslik'] gibi anahtarları dil dosyanıza eklemezseniz panelde boş görünür. Ayrıntısı: Çok Dillilik.

Admin modül kontrol listesi

  • Dosya engine/inc/<ascii-ad>.php ve adı admin_sections.name ile aynı.
  • allow_groups'un bir yetki olmadığını biliyorum; erişimi kod içinde denetliyorum.
  • En başta yetki denetimi var.
  • Kaydetme işlemlerinde user_hash doğrulanıyor.
  • Kurulumda admin_sections kaydı ekleniyor, silmede kaldırılıyor.
  • Tablo adlarında sabit önek yerine {prefix} / PREFIX kullanılıyor.
  • Panel metinleri adminpanel.lng'de tanımlı.
  • Form ve çıktılar htmlspecialchars() ile kaçırılmış.
  • Kullanıcı girdileri intval() veya safesql() ile süzülmüş.

Sırada: AJAX İşleyicisi.