13. Zamanlanmış Görevler

DLE'de zamanlanmış işler iki ayrı sistemle çalışır. Hangisini kullanacağınızı bilmek önemlidir, çünkü eklentinizin yalnızca birine bağlanabilirsiniz.

Dış cronİç (ziyaret bazlı) cron
Dosya cron.php (site kökünde) engine/modules/cron.php
Tetikleyen Sunucu zamanlayıcısı (crontab) veya URL çağrısı Siteye gelen bir ziyaret
Varsayılan durum Kapalı ($allow_cron = 0) Açık
Eklenti yamalayabilir mi? Hayır — giriş noktası Evet — Check() ile yüklenir
★
Sonuç: eklentiniz İÇ cron'a bağlanmalı cron.php bir giriş noktasıdır ve yamalanamaz; görev listesi de sabittir. engine/modules/cron.php ise yamalanabilir. Kendi zamanlanmış işinizi oraya bağlayacaksınız.

Dış cron (cron.php)

Dosyanın başındaki iki değişken her şeyi belirler:

// GÜVENLİK: varsayılan 0'dır — dosya kendini kapatır
$allow_cron = 0;

// Yedekleme görevi için saklanacak maksimum dosya sayısı
$max_count_files = 5;

// …

if (!$allow_cron) {
    header('HTTP/1.1 403 Forbidden');
    die('Cron not allowed');
}
!
DLE bu dosyayı açıkça "kapatık" gönderir DLE'nin kendi yorumu şöyle der: "Güvenlik nedeniyle bu dosyayı cron.php adından başka bir php uzantılı adla yeniden adlandırın." Yani $allow_cron = 1 yapmak, dosyayı internete açmak demektir. Açacaksanız mutlaka adını değiştirin ve/veya IP kısıtlaması koyun.

Sabit görev listesi

Görev, ?cronmode= parametresi veya komut satırı argümanıyla seçilir:

# URL ile cron.php?cronmode=sitemap|optimize|antivirus|newsletter # Komut satırı ile php cron.php sitemap # Parametre verilmezse varsayılan görev: backup (veritabanı yedeği, $max_count_files kadar saklanır)

Liste cron.php içindeki bir diziyle sınırlıdır, yani genişletilemez. Eklentinizin kendi görevini buraya eklemesi mümkün değildir.

İçeride CSRF nasıl atlatılıyor?

Dış cron, DLE'nin panel fonksiyonlarını çağırdığı için arada ilginç bir yöntem kullanır:

function resetCronRequestContext() {
    global $dle_login_hash;

    $_REQUEST = $_POST = $_GET = array();

    $_REQUEST['user_hash'] = 1;
    $dle_login_hash        = 1;
}

Yani istek değişkenleri sıfırlanır ve CSRF anahtarı geçici olarak 1 yapılır — böylece çağrılan sistem fonksiyonlarının user_hash denetiminden geçer. Benzer şekilde yönetici yetkisi de elle kurulur: $member_id['user_group'] = 1 ve ilgili admin_* izinleri 1 yapılır.

İç cron (ziyaret bazlı)

Bu sistem her ziyarette kontrol edilir. Kaynağı engine/init.php'dir:

$cron_time = get_vars ( "cron" );

// Kilit varsa, kilidin zamanını "son başarılı çalışma" ile değiştir
if( isset($cron_time['locked']) AND $cron_time['locked'] AND $cron_time['time'] ) {
    $cron_time['lasttime'] = $cron_time['time'];
    $cron_time['time']     = $cron_time['successtime'];
}

if( !isset($cron_time['time']) ) $cron = 2;
elseif( isset($cron_time['time']) AND date ( "Y-m-d", $cron_time['time'] ) != date ( "Y-m-d", $_TIME )) $cron = 2;
elseif( isset($cron_time['time']) AND ( ($cron_time['time'] + (3600 * 2) ) < $_TIME) ) $cron = 1;

if ($cron) {
    include_once (DLEPlugins::Check(ENGINE_DIR . '/modules/cron.php'));
}

$cron değerleri

DeğerAnlamıDLE'nin yaptığı işler
false Çalışma zamanı gelmedi. Hiçbir şey.
1 Son çalışmadan 2 saatten fazla geçti. Spam kayıtlarının temizliği.
2 Hiç çalışmamış veya son çalışma başka bir güne ait. Log tablolarının sıfırlanması, süreli haber işlemleri (_post_log), hareketsiz üyelerin silinmesi, eski görsellerin temizliği.

Her iki değerde de, $config['cache_count'] açıksa görüntülenme sayaçları toplanır (_views → news_read) ve ilgili önbellek temizlenir.

Kilit mekanizması

Aynı görevin üst üste çalışmasını engellemek için bir kilit yazılır:

$cron_data = array( 'time' => $_TIME, 'locked' => true);
// …
set_vars( "cron", $cron_data );

İç cron, kilidin 120 saniyeden uzun süre açık kalmasını "takılmış" sayar ve kilidi yok sayarak çalışır. Yani göreviniz 120 saniyeden uzun sürerse ikinci bir kopyası başlayabilir. Uzun süren işlerinizi buna göre tasarlayın.

Eklentinizi iç cron'a bağlamak

engine/modules/cron.php içinde iki benzersiz çapa vardır: if( $cron == 1 ) { ve if( $cron == 2 ) {. Bunlardan birinin üstüne kendi modülünüzü ekleyin:

<file name="engine/modules/cron.php">
    <operation action="before">
        <searchcode><![CDATA[if( $cron == 1 ) {]]></searchcode>
        <replacecode><![CDATA[include_once(DLEPlugins::Check(ENGINE_DIR . '/modules/benim_cron.php'));]]></replacecode>
        <searchcount>1</searchcount>
        <enabled>1</enabled>
    </operation>
</file>

Modülünüzde $cron değeri hazırdır (1 veya 2):

// engine/modules/benim_cron.php
if (!defined('DATALIFEENGINE')) die('Hacking attempt!');

// Hazır: $db, $config, $cron

// Kendi zamanlayıcınızı tutun — $cron'a bağımlı kalmayın.
$durum = get_vars('benim_eklenti_cron');
$son   = (is_array($durum) && isset($durum['last'])) ? intval($durum['last']) : 0;

if (($_TIME - $son) < 3600) {
    return; // 1 saatten sık çalışma
}

// --- İşinizi yapın ---
$db->query("DELETE FROM " . PREFIX . "_benim_log WHERE tarih < '" . ($_TIME - 86400 * 7) . "'");

// Son çalışma zamanını kaydet
set_vars('benim_eklenti_cron', array('last' => $_TIME));
★
Kendi zamanlayıcınızı tutmak neden önemli? $cron değeri site trafiğine bağlıdır: az ziyaretçili bir sitede iç cron seyrek çalışır, çok ziyaretli bir sitede ise sık. Görevinizin sıklığını garanti etmek için $_TIME ile kendi zaman damganızı karşılaştırın.

set_vars / get_vars — DLE'nin JSON önbelleği

Bu iki fonksiyon, eklenti geliştiricisi için çok kullanışlıdır: veriyi engine/cache/system/<ad>.json dosyasına yazar/okur.

set_vars($file, $data);   // yazar
$data = get_vars($file);  // okur (yoksa false döner)
  • Dosya adı totranslit() ile süzülür — ASCII ad kullanın.
  • Dizi, sayı veya metin saklayabilirsiniz.
  • Hem ön yüzde (engine/modules/functions.php) hem panelde (engine/inc/include/functions.inc.php) tanımlıdır.
// Kaydet
set_vars('benim_eklenti_durum', array(
    'last'  => $_TIME,
    'sayac' => 42,
));

// Oku
$durum = get_vars('benim_eklenti_durum');

if (is_array($durum)) {
    echo $durum['sayac'];
}
!
Önbellek temizliği bunları silebilir engine/cache/system/ altındaki dosyalar DLE'nin önbellek temizleme işlemlerinden etkilenebilir (cron.json özellikle korunur, sizinki korunmayabilir). Kalıcı veri için veritabanı kullanın; bu yöntemi yalnızca yeniden üretilebilir durum bilgisi için tercih edin.

Zamanlanmış görev kontrol listesi

  • Görev engine/modules/cron.php'ye bağlandı (dış cron.php'ye değil).
  • Çapa if( $cron == 1 ) { veya if( $cron == 2 ) { ve searchcount verildi.
  • Görev, kendi $_TIME kontrolüyle sıklığı garanti ediyor.
  • Uzun süren işler için 120 saniyelik kilit davranışı hesaba katıldı.
  • Kalıcı veriler veritabanında; set_vars yalnızca durum bilgisi için.
  • Görev ağır değil (bir ziyaretçinin sayfa yükleme süresini uzatıyor).

Sırada: Çok Dillilik.