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'] );
}
}
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.
| Dosya | Adres |
|---|---|
engine/inc/mymod.php | admin.php?mod=mymod |
engine/inc/benim-eklentim.php | admin.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 |
|---|---|
name | Modü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). |
title | Menüde görünen başlık |
descr | Modülün kısa açıklaması (menüde başlığın altında görünür) |
icon | Simge dosyasının adı. DLE'nin resmî dokümanında önerilen boyut 70×70 pikseldir. |
allow_groups | all (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şken | Açıklama |
|---|---|
$db | Veritabanı nesnesi. |
$config | Sistem ayarları dizisi. |
$lang | Panel dil değişkenleri (adminpanel.lng). |
$member_id | Panele giriş yapan yöneticinin bilgileri. |
$user_group | Üye gruplarının izin dizisi. |
$cat_info | Kategoriler. |
$mod / $action | İstek parametreleri (süzülmüş). |
$dle_login_hash | CSRF anahtarı. Formlara gizli alan olarak konur. |
$_TIME / $_IP | Sunucu zamanı ve yöneticinin IP'si. |
$js_array / $css_array | Sayfaya eklenecek JS/CSS dosyaları. |
$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
$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ı.
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);
| $type | Görünüm |
|---|---|
"error" | Kırmızı uyarı |
"warning" | Sarı uyarı |
"success" | Yeşil onay |
| diğer | Mavi 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}>";
}
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öntem | Değ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();
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>.phpve adıadmin_sections.nameile 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_hashdoğrulanıyor. - Kurulumda
admin_sectionskaydı ekleniyor, silmede kaldırılıyor. - Tablo adlarında sabit önek yerine
{prefix}/PREFIXkullanılıyor. - Panel metinleri
adminpanel.lng'de tanımlı. - Form ve çıktılar
htmlspecialchars()ile kaçırılmış. - Kullanıcı girdileri
intval()veyasafesql()ile süzülmüş.
Sırada: AJAX İşleyicisi.