<?php

if (!function_exists('m_setting')) {
    function m_setting($data)
    {
        $db = new DB();
        if ($data == 'logo' or $data == 'favicon') {
            $return = m_image_url($db->table('settings')->where('id', '=', '1')->get_var($data));
        } else {
            $return = $db->table('settings')->where('id', '=', '1')->get_var($data);
        }
        return $return;
    }
}

function csrf_token ($csrf_token){
    if (isset($csrf_token)) {
        $submittedToken = $csrf_token;
        if (isset($_SESSION['csrf_token']) && time() < $_SESSION['csrf_token']['expiry_time']) {
            $expectedToken = $_SESSION['csrf_token']['value'];
            if ($submittedToken === $expectedToken) {
                $respone = [true, lang('form_success_message', [], 'Değişiklikler Başarıyla Uygulandı!')];
            } else {
                $respone = [false, lang('form_token_error', [], 'Token eşleşmiyor, lütfen sayfayı yenileyip tekrar deneyin')];
            }
        } else {
            $respone = [false, lang('form_token_time_error', [], 'Token süresi dolmuş, lütfen sayfayı yenileyip tekrar deneyin')];
        }
    }
    return $respone;
}
function csrf_token_fronted ($csrf_token_fronted){
   
    if (isset($csrf_token_fronted)) {
        $submittedToken = $csrf_token_fronted;
        if (isset($_SESSION['csrf_token_fronted']) && time() < $_SESSION['csrf_token_fronted']['expiry_time']) {
            $expectedToken = $_SESSION['csrf_token_fronted']['value'];
            if ($submittedToken === $expectedToken) {
                $respone = [true, lang('form_success_message', [], 'Değişiklikler Başarıyla Uygulandı!')];
            } else {
                $respone = [false, lang('form_token_error', [], 'Token eşleşmiyor, lütfen sayfayı yenileyip tekrar deneyin')];
            }
        } else {
            $respone = [false, lang('form_token_time_error', [], 'Token süresi dolmuş, lütfen sayfayı yenileyip tekrar deneyin')];
        }
    }
    return $respone;
}

if (!function_exists('old')) {

    function old($key = null, $default = null)
    {
        if (isset($_SESSION['_old_input'])) {
            return isset($_SESSION['_old_input'][$key]) ? $_SESSION['_old_input'][$key] : $default;
        }

        return $default;
    }
}


if (!function_exists('lang_is_default')) {

    function lang_is_default($col){
        $db = new DB();
        $lang_is_default =  $db->table('languages')->where('lang_is_default', '=', 1)->get();

        return $lang_is_default['data'][0][$col];
    }
}

if (!function_exists('languages')) {

    function languages($index){
        $db = new DB();
        $languages =  $db->table('languages')->order('lang_is_default','desc')->get();

        return $languages[$index];
    }
}



if (!function_exists('posts_lang')) {

    function posts_langs($lang_ref_id, $lang){
        $db = new DB();


        $query = "SELECT * FROM posts WHERE lang_ref_id = :lang_ref_id ORDER BY CASE WHEN lang = :lang THEN 0 ELSE 1 END, lang DESC";
        $result = $db->query($query, [':lang_ref_id' => $lang_ref_id, ':lang' => $lang]);

        if ($result) {
            return $result->fetchAll(PDO::FETCH_ASSOC);
        }
        return false;
    }
}
if (!function_exists('lang_name')) {

    function lang_name($lang_code){
        $db = new DB();
        $languages =  $db->table('languages')->where('lang_code','=', $lang_code)->get();

        return $languages['data'][0]['lang_name'];
    }
}

if (!function_exists('settings')) {
    function settings($key, $lang = 'tr'){
        $db = new DB();
        
        // Eğer active_theme aranıyorsa, özel işlem yap
        if ($key === 'active_theme') {
            $theme_key = 'active_theme_' . $lang;
            $setting = $db->table('settings')->where('key_word', '=', $theme_key)->get();
            
            if ($setting['total_count'] == 0) {
                $theme_key_default = 'active_theme_' . lang_is_default('lang_code');
                $setting = $db->table('settings')->where('key_word', '=', $theme_key_default)->get();
            }
            
            return $setting['total_count'] > 0 ? $setting['data'][0]['value'] : 'tema1';
        }
        
        // Diğer ayarlar için tema önceliği
        $active_theme = get_active_theme();
        $theme_key = $active_theme . '_' . $key . '_' . $lang;
        $setting = $db->table('settings')->where('key_word', '=', $theme_key)->get();
        
        if ($setting['total_count'] == 0) {
            // Tema ayarı yoksa, varsayılan dilde tema ayarını ara
            $theme_key_default = $active_theme . '_' . $key . '_' . lang_is_default('lang_code');
            $setting = $db->table('settings')->where('key_word', '=', $theme_key_default)->get();
        }
        
        if ($setting['total_count'] == 0) {
            // Tema ayarı yoksa, genel ayarı ara
            $general_key = $key . '_' . $lang;
            $setting = $db->table('settings')->where('key_word', '=', $general_key)->get();
        }
        
        if ($setting['total_count'] == 0) {
            // Genel ayar da yoksa, varsayılan dilde genel ayarı ara
            $general_key_default = $key . '_' . lang_is_default('lang_code');
            $setting = $db->table('settings')->where('key_word', '=', $general_key_default)->get();
        }
        
        return $setting['total_count'] > 0 ? $setting['data'][0]['value'] : null;
    }
}

if (!function_exists('general_settings')) {
    function general_settings($key, $lang = 'tr'){
        $db = new DB();
        
        // Genel ayarlar için sadece dil durumuna göre ara
        $general_key = $key . '_' . $lang;
        $setting = $db->table('settings')->where('key_word', '=', $general_key)->get();
        
        if ($setting['total_count'] == 0) {
            // Varsayılan dilde ara
            $general_key_default = $key . '_' . lang_is_default('lang_code');
            $setting = $db->table('settings')->where('key_word', '=', $general_key_default)->get();
        }
        
        return $setting['total_count'] > 0 ? $setting['data'][0]['value'] : null;
    }
}

if (!function_exists('theme_settings')) {
    function theme_settings($key, $lang = 'tr', $theme_name = null){
        $db = new DB();
        
        // Tema adını belirle
        if ($theme_name === null) {
            $theme_name = get_active_theme();
        }
        
        // Tema ayarları için tema adı ve dil durumuna göre ara
        $theme_key = $theme_name . '_' . $key . '_' . $lang;
        $setting = $db->table('settings')->where('key_word', '=', $theme_key)->get();
        
        if ($setting['total_count'] == 0) {
            // Varsayılan dilde tema ayarını ara
            $theme_key_default = $theme_name . '_' . $key . '_' . lang_is_default('lang_code');
            $setting = $db->table('settings')->where('key_word', '=', $theme_key_default)->get();
        }
        
        return $setting['total_count'] > 0 ? $setting['data'][0]['value'] : null;
    }
}

if (!function_exists('settings_exists')) {

    function settings_exists($key){
        $db = new DB();
        $settings=  $db->table('settings')->where('key_word','=', $key)->get();
        if ($settings['total_count'] != 0){
            return true;
        }else{
            return null;
        }
    }
}

if (!function_exists('save_setting')) {
    function save_setting($key, $value, $lang = 'tr'){
        $db = new DB();
        $key_with_lang = $key . '_' . $lang;
        
        // Ayar var mı kontrol et
        $existing_setting = $db->table('settings')->where('key_word', '=', $key_with_lang)->get();
        
        if ($existing_setting['total_count'] > 0) {
            // Mevcut ayarı güncelle
            $data = ['value' => $value];
            $result = $db->table('settings')->where('key_word', '=', $key_with_lang)->update($data);
        } else {
            // Yeni ayar ekle
            $data = [
                'key_word' => $key_with_lang,
                'value' => $value
            ];
            $result = $db->table('settings')->insert($data);
        }
        
        return $result;
    }
}

if (!function_exists('get_active_theme')) {
    function get_active_theme($lang = 'tr'){
        $db = new DB();
        
        // Önce aktif temaya özgü ayarı ara
        $theme_key = 'active_theme_' . $lang;
        $setting = $db->table('settings')->where('key_word', '=', $theme_key)->get();
        
        if ($setting['total_count'] == 0) {
            // Varsayılan dilde ara
            $theme_key_default = 'active_theme_' . lang_is_default('lang_code');
            $setting = $db->table('settings')->where('key_word', '=', $theme_key_default)->get();
        }
        
        return $setting['total_count'] > 0 ? $setting['data'][0]['value'] : 'tema1';
    }
}

if (!function_exists('posts_ajax')) {

    function posts_ajax($index, $model, $lang, $order = 'id', $direction= 'asc', $limit = null, $category_id = null){
        $db = new DB();
        if ($category_id == 'default' or $category_id == null){
            $posts =  $db->table('posts')->where('module_type','=',$model)->where('lang', '=', $lang)->order($order,$direction)->limit($limit)->get();

        }else{
            $posts =  $db->table('posts')->where('module_type','=',$model)->where('category_id', '=', $category_id)->where('lang', '=', $lang)->order($order,$direction)->limit($limit)->get();

        }


        return $posts[$index];
    }
}

if (!function_exists('posts')) {

    function posts($index, $model, $lang, $limit = null){
        $db = new DB();
        if ($model == 'all'){
            $posts =  $db->table('posts')->where('lang', '=', $lang)->order('id','asc')->limit($limit)->get();

        }else{
            $posts =  $db->table('posts')->where('module_type','=',$model)->where('lang', '=', $lang)->order('id','asc')->limit($limit)->get();

        }

        return $posts[$index];
    }
}
if (!function_exists('post')) {

    function post($id){
        $db = new DB();
            $post =  $db->table('posts')->where('id', '=', $id)->get();

        return $post['data'][0];
    }
}

if (!function_exists('category')) {

    function category($id, $lang){
        $db = new DB();
        $post =  $db->table('posts')->where('id', '=', $id)->where('lang', '=', $lang)->get();

        return $post['data'][0];
    }
}

if (!function_exists('post_with_id')) {

    function post_with_id($id){
        $db = new DB();
        $post =  $db->table('posts')->where('id', '=', $id)->get();
        $post_with_lang =  $db->table('posts')->where('lang_ref_id', '=', $post['data'][0]['lang_ref_id'])->where('status', '=', 1)->get();

        return $post_with_lang['data'];
    }
}
if (!function_exists('post_with_slug')) {

    function post_with_slug($slug, $lang){
        $db = new DB();
        $post =  $db->table('posts')->where('sef', '=', $slug)->get();
        
        // Eğer post bulunamadıysa boş array döndür
        if ($post['total_count'] == 0) {
            return ['sef' => '', 'content' => '', 'title' => ''];
        }
        
        $post_with_lang =  $db->table('posts')->where('lang_ref_id', '=', $post['data'][0]['lang_ref_id'])->where('lang', '=', $lang)->where('status', '=', 1)->get();

        // Eğer dil versiyonu bulunamadıysa boş array döndür
        if ($post_with_lang['total_count'] == 0) {
            return ['sef' => '', 'content' => '', 'title' => ''];
        }

        return $post_with_lang['data'][0];
    }
}
if (!function_exists('slider_item')) {

    function slider_item($id){
        $db = new DB();
        $post =  $db->table('slideritems')->where('id', '=', $id)->get();

        return $post['data'][0];
    }
}
if (!function_exists('slider_Items')) {

    function slider_Items($index, $id){
        $db = new DB();

        $menuitems =  $db->table('slideritems')->where('slider_id', '=', $id)->order('short','asc')->get();

        return $menuitems[$index];
    }
}

if (!function_exists('menu_Items')) {

    function menu_Items($index, $id){
        $db = new DB();

        $menuitems =  $db->table('menuitems')->where('menu_id', '=', $id)->get();

        return $menuitems[$index];
    }
}


if (!function_exists('post_content_save')) {

    function post_content_save($id, $html){
        $data = ['content' => $html];
        $db = new DB();
        $result = $db->table('posts')->where('id', '=', $id)->update($data);
        if ($result) {
            return true;
        } else {
            return false;
        }
    }
}

if (!function_exists('menu_type')) {
    function menu_type($menu_type){
        // Try dot-notation first (array/json i18n), then legacy underscore key, finally raw type
        $label = lang('menu.type.' . $menu_type, [], null);
        if ($label === 'menu.type.' . $menu_type) {
            $label = lang('menu_type_' . $menu_type, [], $menu_type);
        }
        echo $label;
    }
}
if (!function_exists('module_title')) {
    function module_title($menu_title){
        $key = 'page_title_' . $menu_title;
        echo lang($key, [], ucfirst(str_replace('_',' ',$menu_title)));
    }
}
if (!function_exists('image')) {
    function image($image){
        $image = DOMAIN.'/media'.$image;
        return $image;

    }
}
if (!function_exists('sitemap_posts')) {

    function sitemap_posts($excludeModuleTypes = array()){
        $db = new DB();
        $query = $db->table('posts')->where('sef', '!=', '')->where('status', '=', 1)->order('id','asc');
        if (is_array($excludeModuleTypes) && !empty($excludeModuleTypes)) {
            foreach ($excludeModuleTypes as $exclude) {
                $query = $query->where('module_type', '!=', $exclude);
            }
        }
        $posts = $query->get();

        return $posts['data'];
    }
}


if (!function_exists('generate_sitemap')) {
    function generate_sitemap() {
        $db = new DB();
        $now = date('c');
        $domain = rtrim(DOMAIN, '/');
        $root = ROOT_FOLDER;

        // Tek dosya sitemap.xml (urlset)
        $doc = new DOMDocument('1.0', 'UTF-8');
        $doc->formatOutput = true;
        $urlset = $doc->createElement('urlset');
        $urlset->setAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
        $doc->appendChild($urlset);

        // Kök URL
        $uHome = $doc->createElement('url');
        $uHome->appendChild($doc->createElement('loc', $domain . '/'));
        $uHome->appendChild($doc->createElement('lastmod', $now));
        $urlset->appendChild($uHome);

        // Tüm içerikler
        $all = sitemap_posts(['sliders', 'menu', 'feedback', 'request_demo']);
        if (!empty($all)) {
            foreach ($all as $r) {
                $locVal = $domain . '/' . ltrim((string)$r['sef'], '/');
                $lmVal = !empty($r['updated_at']) ? date('c', strtotime($r['updated_at'])) : $now;
                $u = $doc->createElement('url');
                $u->appendChild($doc->createElement('loc', $locVal));
                $u->appendChild($doc->createElement('lastmod', $lmVal));
                $urlset->appendChild($u);
            }
        }

        $savePath = $root . '/sitemap.xml';
        $ok = false;
        try { $ok = (bool) $doc->save($savePath); } catch (Exception $e) { $ok = false; }
        if ($ok) { @file_put_contents($savePath . '.gz', gzencode($doc->saveXML(), 9)); }
        // robots.txt içindeki Sitemap satırını mutlak URL ile garanti et
        if (!function_exists('ensure_robots_sitemap_line')) {
            function ensure_robots_sitemap_line(){
                $robotsPath = ROOT_FOLDER . '/robots.txt';
                $abs = rtrim(DOMAIN,'/') . '/sitemap.xml';
                $line = "Sitemap: " . $abs;
                $raw = is_file($robotsPath) ? @file_get_contents($robotsPath) : '';
                if ($raw === false) { $raw = ''; }
                if ($raw !== '') {
                    $new = preg_replace('/^\s*Sitemap\s*:\s*.*$/im', $line, $raw, -1, $count);
                    if ($new === null) { $new = $raw; $count = 0; }
                    if ($count === 0) { $new = rtrim($new) . "\n\n" . $line . "\n"; }
                    @file_put_contents($robotsPath, $new);
                } else {
                    $template = "User-agent: *\nDisallow: /admin/\nDisallow: /panel/\nDisallow: /*?preview=\nDisallow: /*?session=\nDisallow: /*?token=\n\n" . $line . "\n";
                    @file_put_contents($robotsPath, $template);
                }
            }
        }
        ensure_robots_sitemap_line();
        return $savePath;
    }
}


function pingSearchEngines($minIntervalMinutes = 30) {
    // 1) Önce sitemap'ı üret
    $sitemapUrl = rtrim(DOMAIN,'/').'/sitemap.xml';
    $sitemapPath = generate_sitemap();

    // 2) Sık ping'i engelle (dosya-tabanlı throttle)
    $cacheDir = ROOT_FOLDER . '/cache';
    if (!is_dir($cacheDir)) { @mkdir($cacheDir, 0775, true); }
    $lockFile = $cacheDir . '/sitemap_ping.lock';
    $now = time();
    $last = is_file($lockFile) ? (int)@file_get_contents($lockFile) : 0;
    $interval = max(1, (int)$minIntervalMinutes) * 60;
    if ($last && ($now - $last) < $interval) {
        return $sitemapPath; // Çok sık: ping atlaması
    }

    // 3) Ping hedefleri (Google + Bing klasik). Not: Bing IndexNow ayrı anahtar gerektirir; basit ping yeterli.
    $searchEngines = [
        'Google' => 'https://www.google.com/ping?sitemap=' . urlencode($sitemapUrl),
        'Bing'   => 'https://www.bing.com/ping?sitemap='   . urlencode($sitemapUrl),
    ];

    foreach ($searchEngines as $name => $url) {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        @curl_exec($ch); // Sonucu önemsemiyoruz, hatada sessiz geç
        @curl_close($ch);
    }

    // 4) Son ping zamanını yaz
    @file_put_contents($lockFile, (string)$now);

    return $sitemapPath;
}

// IndexNow helpers (Bing/partners)
if (!function_exists('indexnow_enabled')) {
    function indexnow_enabled($lang = 'tr') {
        $enabled = (string) general_settings('indexnow_enabled', $lang) === '1';
        $key = trim((string) general_settings('indexnow_key', $lang));
        return $enabled && $key !== '';
    }
}

if (!function_exists('indexnow_submit')) {
    function indexnow_submit(array $urls, $lang = 'tr') {
        if (empty($urls)) { return false; }
        if (!indexnow_enabled($lang)) { return false; }
        $key = trim((string) general_settings('indexnow_key', $lang));
        $endpointPref = (string) (general_settings('indexnow_endpoint', $lang) ?: 'api');
        $endpointHost = $endpointPref === 'bing' ? 'www.bing.com' : 'api.indexnow.org';
        $endpoint = 'https://' . $endpointHost . '/indexnow';

        // keyLocation: https://domain/{key}.txt
        $keyLocation = rtrim(DOMAIN,'/') . '/' . $key . '.txt';
        $payload = [
            'host' => HOST,
            'key' => $key,
            'keyLocation' => $keyLocation,
            'urlList' => array_values(array_unique($urls))
        ];
        $ch = curl_init($endpoint);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        @curl_exec($ch);
        @curl_close($ch);
        return true;
    }
}

// Matomo Dashboard Yardımcıları
if (!function_exists('matomo_enabled')) {
	function matomo_enabled($lang = 'tr'){
		$enabled = general_settings('analytics_enabled', $lang) === '1';
		$provider = general_settings('analytics_provider', $lang) === 'matomo';
		$siteId = general_settings('analytics_site_id', $lang);
		$endpoint = rtrim((string) general_settings('analytics_endpoint', $lang), '/');
		$token = general_settings('analytics_api_token', $lang);
		return $enabled && $provider && !empty($endpoint) && !empty($siteId) && !empty($token);
	}
}

if (!function_exists('get_matomo_dashboard_data')) {
	function get_matomo_dashboard_data($lang = 'tr', $ttlSeconds = 600){
		if (!matomo_enabled($lang)) { return null; }
		$siteId = (int) general_settings('analytics_site_id', $lang);
		$endpoint = rtrim((string) general_settings('analytics_endpoint', $lang), '/');
		$token = (string) general_settings('analytics_api_token', $lang);
		$fetchOnRequest = defined('ANALYTICS_FETCH_ON_REQUEST') ? (bool)ANALYTICS_FETCH_ON_REQUEST : true;

		$cacheDir = ROOT_FOLDER . '/cache';
		if (!is_dir($cacheDir)) { @mkdir($cacheDir, 0775, true); }
		$cacheFile = $cacheDir . '/matomo_' . $siteId . '_dashboard_' . $lang . '.json';
		$cached = null; $hasCache = false; $age = PHP_INT_MAX; $maxStale = $ttlSeconds * 2; // TTL'in 2 katını aşarsa zorunlu tazele
		if (is_file($cacheFile)) {
			$hasCache = true; $age = time() - filemtime($cacheFile);
			$raw = @file_get_contents($cacheFile);
			if ($raw !== false) { $tmp = json_decode($raw, true); if (is_array($tmp)) { $cached = $tmp; } }
			// Paneli bloklamamak için: cache varsa her durumda döndür
			if ($cached !== null) { return $cached; }
		}
		// Cache yoksa ve istek-anında fetch kapalıysa hızlıca dön
		if (!$fetchOnRequest) { return null; }

		$base = $endpoint . '/index.php';
		// Visits summary (last 7 days aggregated)
		$params1 = [
			'module' => 'API', 'method' => 'VisitsSummary.get', 'idSite' => $siteId,
			'period' => 'range', 'date' => 'last7', 'format' => 'JSON', 'token_auth' => $token
		];
		$resp1 = m_url_post($base, $params1, $endpoint . '/');
		$data1 = json_decode($resp1, true);
		if (!is_array($data1) || (isset($data1['result']) && $data1['result'] === 'error')) { return null; }
		$totalVisits = (int) ($data1['nb_visits'] ?? 0);
		$totalActions = (int) ($data1['nb_actions'] ?? 0);
		// Ek metrikler: hemen çıkma ve ort. süre
		$bounceRateRaw = isset($data1['bounce_rate']) ? (string)$data1['bounce_rate'] : '0%';
		$bounceRatePct = (float)str_replace('%', '', $bounceRateRaw);
		$avgTimeSeconds = (int)($data1['avg_time_on_site'] ?? 0);

		// Top pages (last 7 days)
		$params2 = [
			'module' => 'API', 'method' => 'Actions.getPageUrls', 'idSite' => $siteId,
			'period' => 'range', 'date' => 'last7', 'format' => 'JSON', 'token_auth' => $token,
			'filter_limit' => 5, 'flat' => 1,
			'language' => $lang
		];
		$resp2 = m_url_post($base, $params2, $endpoint . '/');
		$data2 = json_decode($resp2, true);
		$topPages = [];
		if (is_array($data2)) {
			foreach ($data2 as $row) {
				if (isset($row['label'])) {
					$label = (string) $row['label'];
					// Admin yollarını hariç tut
					if (strpos($label, '/admin') === 0) { continue; }
					$topPages[] = [
						'label' => $label,
						'nb_visits' => (int) ($row['nb_visits'] ?? 0),
						'nb_hits' => (int) ($row['nb_hits'] ?? 0)
					];
				}
				if (count($topPages) >= 5) { break; }
			}
		}

		// Languages (last 7 days)
		$params3 = [
			'module' => 'API', 'method' => 'UserLanguage.getLanguage', 'idSite' => $siteId,
			'period' => 'range', 'date' => 'last7', 'format' => 'JSON', 'token_auth' => $token,
			'language' => $lang
		];
		$resp3 = m_url_post($base, $params3, $endpoint . '/');
		$data3 = json_decode($resp3, true);
		$languages = [];
		if (is_array($data3)) {
			foreach ($data3 as $row) {
				if (isset($row['label'])) {
					$languages[] = [
						'label' => (string) $row['label'],
						'nb_visits' => (int) ($row['nb_visits'] ?? 0)
					];
				}
			}
		}

		$result = [
			'totals' => ['visits' => $totalVisits, 'actions' => $totalActions],
			'topPages' => $topPages,
			'languages' => $languages,
			'metrics' => ['bounceRatePct' => $bounceRatePct, 'avgTimeSeconds' => $avgTimeSeconds],
			'_generatedAt' => time()
		];
		@file_put_contents($cacheFile, json_encode($result));
		return $result;
	}
}

if (!function_exists('get_matomo_country_map_data')) {
	function get_matomo_country_map_data($lang = 'tr', $ttlSeconds = 600){
		if (!matomo_enabled($lang)) { return null; }
		$siteId = (int) general_settings('analytics_site_id', $lang);
		$endpoint = rtrim((string) general_settings('analytics_endpoint', $lang), '/');
		$token = (string) general_settings('analytics_api_token', $lang);

		$cacheDir = ROOT_FOLDER . '/cache';
		if (!is_dir($cacheDir)) { @mkdir($cacheDir, 0775, true); }
		$cacheFile = $cacheDir . '/matomo_' . $siteId . '_country_' . $lang . '.json';
		$cached = null; $hasCache = false; $age = PHP_INT_MAX; $maxStale = $ttlSeconds * 2;
		if (is_file($cacheFile)) {
			$hasCache = true; $age = time() - filemtime($cacheFile);
			$raw = @file_get_contents($cacheFile);
			if ($raw !== false) { $tmp = json_decode($raw, true); if (is_array($tmp)) { $cached = $tmp; } }
			if ($age < $ttlSeconds && $cached !== null) { return $cached; }
			if ($cached !== null && $age < $maxStale) { return $cached; }
		}

		$params = [
			'module' => 'API', 'method' => 'UserCountry.getCountry', 'idSite' => $siteId,
			'period' => 'range', 'date' => 'last7', 'format' => 'JSON', 'token_auth' => $token,
			'language' => $lang
		];
		$resp = m_url_post($endpoint . '/index.php', $params, $endpoint . '/');
		$data = json_decode($resp, true);
		if (!is_array($data) || (isset($data['result']) && $data['result'] === 'error')) { return null; }
		$series = [];
		$top = [];
		if (is_array($data)) {
			foreach ($data as $row) {
				$code = strtoupper((string) ($row['code'] ?? ''));
				$visits = (int) ($row['nb_visits'] ?? 0);
				if ($code) { $series[$code] = $visits; }
				if (isset($row['label'])) { $top[] = ['label' => (string)$row['label'], 'nb_visits' => $visits]; }
			}
		}
		$result = ['series' => $series, 'top' => $top, '_generatedAt' => time()];
		@file_put_contents($cacheFile, json_encode($result));
		return $result;
	}
}

if (!function_exists('get_matomo_device_types_data')) {
	function get_matomo_device_types_data($lang = 'tr', $ttlSeconds = 600){
		if (!matomo_enabled($lang)) { return null; }
		$siteId = (int) general_settings('analytics_site_id', $lang);
		$endpoint = rtrim((string) general_settings('analytics_endpoint', $lang), '/');
		$token = (string) general_settings('analytics_api_token', $lang);
		$cacheDir = ROOT_FOLDER . '/cache'; if (!is_dir($cacheDir)) { @mkdir($cacheDir, 0775, true); }
		$cacheFile = $cacheDir . '/matomo_' . $siteId . '_devices_' . $lang . '.json';
		$cached = null; $age = PHP_INT_MAX; $maxStale = $ttlSeconds * 2;
		if (is_file($cacheFile)) {
			$age = time() - filemtime($cacheFile);
			$raw = @file_get_contents($cacheFile); if ($raw !== false) { $tmp = json_decode($raw, true); if (is_array($tmp)) { $cached = $tmp; } }
			if ($age < $ttlSeconds && $cached !== null) { return $cached; }
			if ($cached !== null && $age < $maxStale) { return $cached; }
		}
		$params = [
			'module' => 'API', 'method' => 'DevicesDetection.getType', 'idSite' => $siteId,
			'period' => 'range', 'date' => 'last7', 'format' => 'JSON', 'token_auth' => $token,
			'language' => $lang
		];
		$resp = m_url_post($endpoint . '/index.php', $params, $endpoint . '/'); $data = json_decode($resp, true);
		if (!is_array($data) || (isset($data['result']) && $data['result'] === 'error')) { return null; }
		$list = [];
		if (is_array($data)) { foreach ($data as $row) { $list[] = [ 'label' => (string)($row['label'] ?? ''), 'nb_visits' => (int)($row['nb_visits'] ?? 0) ]; } }
		@file_put_contents($cacheFile, json_encode($list));
		return $list;
	}
}

if (!function_exists('get_matomo_referrers_data')) {
	function get_matomo_referrers_data($lang = 'tr', $ttlSeconds = 600){
		if (!matomo_enabled($lang)) { return null; }
		$siteId = (int) general_settings('analytics_site_id', $lang);
		$endpoint = rtrim((string) general_settings('analytics_endpoint', $lang), '/');
		$token = (string) general_settings('analytics_api_token', $lang);
		$cacheDir = ROOT_FOLDER . '/cache'; if (!is_dir($cacheDir)) { @mkdir($cacheDir, 0775, true); }
		$cacheFile = $cacheDir . '/matomo_' . $siteId . '_referrers_' . $lang . '.json';
		$cached = null; $age = PHP_INT_MAX; $maxStale = $ttlSeconds * 2;
		if (is_file($cacheFile)) {
			$age = time() - filemtime($cacheFile);
			$raw = @file_get_contents($cacheFile); if ($raw !== false) { $tmp = json_decode($raw, true); if (is_array($tmp)) { $cached = $tmp; } }
			if ($age < $ttlSeconds && $cached !== null) { return $cached; }
			if ($cached !== null && $age < $maxStale) { return $cached; }
		}
		// Referrer types (Direct, Search, Websites, Campaigns, Social)
		$paramsTypes = [
			'module' => 'API', 'method' => 'Referrers.getReferrerType', 'idSite' => $siteId,
			'period' => 'range', 'date' => 'last7', 'format' => 'JSON', 'token_auth' => $token,
			'language' => $lang
		];
		$respT = m_url_post($endpoint . '/index.php', $paramsTypes, $endpoint . '/'); $dataT = json_decode($respT, true);
		$types = [];
		if (is_array($dataT) && !(isset($dataT['result']) && $dataT['result'] === 'error')) { foreach ($dataT as $row) { $types[] = [ 'label' => (string)($row['label'] ?? ''), 'nb_visits' => (int)($row['nb_visits'] ?? 0) ]; } }
		// Top websites
		$paramsWeb = [
			'module' => 'API', 'method' => 'Referrers.getWebsites', 'idSite' => $siteId,
			'period' => 'range', 'date' => 'last7', 'format' => 'JSON', 'token_auth' => $token, 'filter_limit' => 10,
			'language' => $lang
		];
		$respW = m_url_post($endpoint . '/index.php', $paramsWeb, $endpoint . '/'); $dataW = json_decode($respW, true);
		$websites = [];
		if (is_array($dataW) && !(isset($dataW['result']) && $dataW['result'] === 'error')) { foreach ($dataW as $row) { $websites[] = [ 'label' => (string)($row['label'] ?? ''), 'nb_visits' => (int)($row['nb_visits'] ?? 0) ]; } }
		$result = [ 'types' => $types, 'websites' => $websites ];
		@file_put_contents($cacheFile, json_encode($result));
		return $result;
	}
}

// Events helpers: fetch top event names filtered by category/action via segment
if (!function_exists('get_matomo_events_top_names')) {
    function get_matomo_events_top_names(string $category, string $action, $lang = 'tr', $ttlSeconds = 600, $limit = 10){
        if (!matomo_enabled($lang)) { return []; }
        $siteId = (int) general_settings('analytics_site_id', $lang);
        $endpoint = rtrim((string) general_settings('analytics_endpoint', $lang), '/');
        $token = (string) general_settings('analytics_api_token', $lang);

        $safeCategory = preg_replace('/[^a-zA-Z0-9_\-]/','_', $category);
        $safeAction = preg_replace('/[^a-zA-Z0-9_\-]/','_', $action);
        $cacheDir = ROOT_FOLDER . '/cache'; if (!is_dir($cacheDir)) { @mkdir($cacheDir, 0775, true); }
        $cacheFile = $cacheDir . '/matomo_' . $siteId . '_events_' . strtolower($safeCategory) . '_' . strtolower($safeAction) . '_' . $lang . '.json';
        if (is_file($cacheFile)) { $age = time() - filemtime($cacheFile); if ($age < $ttlSeconds) { $raw = @file_get_contents($cacheFile); if ($raw !== false) { $tmp = json_decode($raw, true); if (is_array($tmp)) return $tmp; } } }

        $segment = 'eventCategory==' . $category . ';eventAction==' . $action;
        $params = [
            'module' => 'API', 'method' => 'Events.getName', 'idSite' => $siteId,
            'period' => 'range', 'date' => 'last7', 'format' => 'JSON', 'token_auth' => $token,
            'language' => $lang, 'filter_limit' => max(1,(int)$limit), 'segment' => $segment
        ];
        $resp = m_url_post($endpoint . '/index.php', $params, $endpoint . '/');
        $data = json_decode($resp, true);
        $list = [];
        if (is_array($data) && !(isset($data['result']) && $data['result'] === 'error')) {
            foreach ($data as $row) {
                $list[] = [
                    'label' => (string)($row['label'] ?? ''),
                    'nb_events' => (int)($row['nb_events'] ?? 0)
                ];
            }
        }
        @file_put_contents($cacheFile, json_encode($list));
        return $list;
    }
}

// Gerçek zamanlı sayaçlar (son X dakika) – Matomo Live API
if (!function_exists('get_matomo_live_counters')) {
	function get_matomo_live_counters($minutes = 30, $lang = 'tr', $ttlSeconds = 30){
		if (!matomo_enabled($lang)) { return null; }
		$siteId = (int) general_settings('analytics_site_id', $lang);
		$endpoint = rtrim((string) general_settings('analytics_endpoint', $lang), '/');
		$token = (string) general_settings('analytics_api_token', $lang);
		$cacheDir = ROOT_FOLDER . '/cache'; if (!is_dir($cacheDir)) { @mkdir($cacheDir, 0775, true); }
		$cacheFile = $cacheDir . '/matomo_' . $siteId . '_live_' . $minutes . '_' . $lang . '.json';
		if (is_file($cacheFile)) {
			$age = time() - filemtime($cacheFile);
			if ($age < $ttlSeconds) { $raw = @file_get_contents($cacheFile); if ($raw !== false) { $tmp = json_decode($raw, true); if (is_array($tmp)) return $tmp; } }
		}
		$params = [
			'module' => 'API', 'method' => 'Live.getCounters', 'idSite' => $siteId,
			'lastMinutes' => max(1, (int)$minutes), 'format' => 'JSON', 'token_auth' => $token,
			'language' => $lang
		];
		$resp = m_url_post($endpoint . '/index.php', $params, $endpoint . '/');
		$data = json_decode($resp, true);
		// Beklenen format: [ { visits: N, actions: M?, visitors: K, ... } ]
		$result = [ 'visits' => 0, 'actions' => 0, 'visitors' => 0 ];
		if (is_array($data) && isset($data[0]) && is_array($data[0])) {
			$row = $data[0];
			$result['visits'] = (int)($row['visits'] ?? 0);
			$result['actions'] = (int)($row['actions'] ?? 0);
			$result['visitors'] = (int)($row['visitors'] ?? 0);
		}
		@file_put_contents($cacheFile, json_encode($result));
		return $result;
	}
}

// Live breakdown helpers (countries / devices / referrers) using Live.getLastVisitsDetails
if (!function_exists('get_matomo_live_details')) {
	function get_matomo_live_details($minutes, $lang, $ttlSeconds){
		if (!matomo_enabled($lang)) { return []; }
		$siteId = (int) general_settings('analytics_site_id', $lang);
		$endpoint = rtrim((string) general_settings('analytics_endpoint', $lang), '/');
		$token = (string) general_settings('analytics_api_token', $lang);
		$cacheDir = ROOT_FOLDER . '/cache'; if (!is_dir($cacheDir)) { @mkdir($cacheDir, 0775, true); }
		$cacheFile = $cacheDir . '/matomo_' . $siteId . '_live_details_' . $minutes . '_' . $lang . '.json';
		if (is_file($cacheFile)) { $age = time() - filemtime($cacheFile); if ($age < $ttlSeconds) { $raw = @file_get_contents($cacheFile); if ($raw !== false) { $tmp = json_decode($raw, true); if (is_array($tmp)) return $tmp; } } }
		$params = [
			'module' => 'API', 'method' => 'Live.getLastVisitsDetails', 'idSite' => $siteId,
			'lastMinutes' => max(1, (int)$minutes), 'format' => 'JSON', 'token_auth' => $token,
			'language' => $lang, 'doNotFetchActions' => 1, 'filter_limit' => 500
		];
		$resp = m_url_post($endpoint . '/index.php', $params, $endpoint . '/');
		$data = json_decode($resp, true);
		if (!is_array($data)) { return []; }
		@file_put_contents($cacheFile, json_encode($data));
		return $data;
	}
}

if (!function_exists('get_matomo_live_countries')) {
	function get_matomo_live_countries($minutes = 30, $lang = 'tr', $ttlSeconds = 30){
		$visits = get_matomo_live_details($minutes, $lang, $ttlSeconds);
		$agg = [];
		foreach ($visits as $v) {
			$label = isset($v['country']) ? (string)$v['country'] : (isset($v['countryCode']) ? (string)$v['countryCode'] : '');
			if ($label === '') { continue; }
			$agg[$label] = ($agg[$label] ?? 0) + 1;
		}
		arsort($agg);
		$out = [];
		foreach ($agg as $k => $count) { $out[] = ['label' => $k, 'nb_visits' => (int)$count]; }
		return $out;
	}
}

if (!function_exists('get_matomo_live_devices')) {
	function get_matomo_live_devices($minutes = 30, $lang = 'tr', $ttlSeconds = 30){
		$visits = get_matomo_live_details($minutes, $lang, $ttlSeconds);
		$agg = [];
		foreach ($visits as $v) {
			$label = isset($v['deviceType']) ? (string)$v['deviceType'] : '';
			if ($label === '') { continue; }
			$agg[$label] = ($agg[$label] ?? 0) + 1;
		}
		arsort($agg);
		$out = [];
		foreach ($agg as $k => $count) { $out[] = ['label' => $k, 'nb_visits' => (int)$count]; }
		return $out;
	}
}

if (!function_exists('get_matomo_live_referrers')) {
	function get_matomo_live_referrers($minutes = 30, $lang = 'tr', $ttlSeconds = 30){
		$visits = get_matomo_live_details($minutes, $lang, $ttlSeconds);
		$agg = [];
		foreach ($visits as $v) {
			$label = isset($v['referrerType']) ? (string)$v['referrerType'] : '';
			if ($label === '') { continue; }
			$agg[$label] = ($agg[$label] ?? 0) + 1;
		}
		arsort($agg);
		$out = [];
		foreach ($agg as $k => $count) { $out[] = ['label' => $k, 'nb_visits' => (int)$count]; }
		return $out;
	}
}

// Live site language distribution using Custom Dimension idDimension=1 (fallback to dimension1 field)
if (!function_exists('get_matomo_live_site_languages')) {
    function get_matomo_live_site_languages($minutes = 30, $lang = 'tr', $ttlSeconds = 30, $dimensionId = 1){
        $visits = get_matomo_live_details($minutes, $lang, $ttlSeconds);
        $aggregate = [];
        foreach ($visits as $visit) {
            $value = '';
            // Direct key like dimension1
            $directKey = 'dimension' . (int)$dimensionId;
            if (isset($visit[$directKey]) && is_string($visit[$directKey]) && $visit[$directKey] !== '') {
                $value = (string)$visit[$directKey];
            } elseif (isset($visit['customDimensions']) && is_array($visit['customDimensions'])) {
                foreach ($visit['customDimensions'] as $cd) {
                    $cdId = (int)($cd['id'] ?? ($cd['idDimension'] ?? 0));
                    if ($cdId === (int)$dimensionId) {
                        $tmp = (string)($cd['value'] ?? '');
                        if ($tmp !== '') { $value = $tmp; }
                        break;
                    }
                }
            }
            if ($value === '') { continue; }
            $aggregate[$value] = ($aggregate[$value] ?? 0) + 1;
        }
        arsort($aggregate);
        $out = [];
        foreach ($aggregate as $k => $count) { $out[] = ['label' => $k, 'nb_visits' => (int)$count]; }
        return $out;
    }
}

// Custom Dimension (site dili) – idDimension=1 varsayımıyla, panelde raporlar için yardımcı
if (!function_exists('get_matomo_language_dimension')) {
	function get_matomo_language_dimension($lang = 'tr', $ttlSeconds = 600){
		if (!matomo_enabled($lang)) { return []; }
		$siteId = (int) general_settings('analytics_site_id', $lang);
		$endpoint = rtrim((string) general_settings('analytics_endpoint', $lang), '/');
		$token = (string) general_settings('analytics_api_token', $lang);
		$cacheDir = ROOT_FOLDER . '/cache'; if (!is_dir($cacheDir)) { @mkdir($cacheDir, 0775, true); }
		$cacheFile = $cacheDir . '/matomo_' . $siteId . '_dim_lang_' . $lang . '.json';
		if (is_file($cacheFile)) { $age = time() - filemtime($cacheFile); if ($age < $ttlSeconds) { $raw = @file_get_contents($cacheFile); if ($raw !== false) { $tmp = json_decode($raw, true); if (is_array($tmp)) return $tmp; } } }
		$params = [
			'module' => 'API', 'method' => 'CustomDimensions.getCustomDimension', 'idSite' => $siteId,
			'idDimension' => 1, 'period' => 'range', 'date' => 'last7', 'format' => 'JSON', 'token_auth' => $token,
			'language' => $lang
		];
		$resp = m_url_post($endpoint . '/index.php', $params, $endpoint . '/');
		$data = json_decode($resp, true);
		$list = [];
		if (is_array($data)) {
			foreach ($data as $row) { $list[] = ['label' => (string)($row['label'] ?? ''), 'nb_visits' => (int)($row['nb_visits'] ?? 0)]; }
		}
		@file_put_contents($cacheFile, json_encode($list));
		return $list;
	}
}

?>
<?php
// ========================================
// Admin Roller ve Yetkiler
// ========================================

if (!function_exists('is_super_admin')) {
	function is_super_admin($adminId = null){
		$aid = $adminId ?? m_get_session('m_admin');
		if (!$aid) { return false; }
		$allowed = defined('SUPER_ADMIN_IDS') && is_array(SUPER_ADMIN_IDS) ? SUPER_ADMIN_IDS : [1];
		return in_array((int)$aid, array_map('intval', $allowed), true);
	}
}

if (!function_exists('admin_has_role')) {
	function admin_has_role($role, $adminId = null){
		// Basit rol kontrolü: admins tablosunda role sütunu varsa onu kullan, yoksa super admin kontrolüne düş
		$aid = $adminId ?? m_get_session('m_admin');
		if (!$aid) { return false; }
		try {
			$db = new DB();
			$rec = $db->table('admins')->where('id', '=', $aid)->get();
			if (!empty($rec['data'])){
				$row = $rec['data'][0];
				if (isset($row['role']) && is_string($row['role']) && $row['role'] !== ''){
					return strtolower($row['role']) === strtolower((string)$role);
				}
			}
		} catch (Exception $e) {}
		// Fallback: super admin ise tüm rolleri varsayalım
		return $role === 'super_admin' ? is_super_admin($aid) : is_super_admin($aid);
	}
}

if (!function_exists('list_super_admin_ids')) {
	function list_super_admin_ids(){
		$ids = [];
		try {
			$db = new DB();
			$res = $db->table('admins')->where('1','=','1')->get();
			if (!empty($res['data'])){
				foreach ($res['data'] as $row){
					if (isset($row['role']) && strtolower((string)$row['role']) === 'super_admin'){
						$ids[] = (int)$row['id'];
					}
				}
			}
		} catch (Exception $e) {}
		if (defined('SUPER_ADMIN_IDS') && is_array(SUPER_ADMIN_IDS)){
			$ids = array_merge($ids, array_map('intval', SUPER_ADMIN_IDS));
		}
		$ids = array_values(array_unique($ids));
		return $ids;
	}
}

if (!function_exists('has_other_super_admins')) {
	function has_other_super_admins($excludeId){
		$ids = list_super_admin_ids();
		foreach ($ids as $id){ if ((int)$id !== (int)$excludeId) return true; }
		return false;
	}
}

// ========================================
// Rol & İzin Yardımcıları
// ========================================
if (!function_exists('role_get')) {
	function role_get($adminId = null){
		$aid = $adminId ?? m_get_session('m_admin');
		if (!$aid) return 'admin';
		try {
			$db = new DB();
			$rec = $db->table('admins')->where('id','=',$aid)->get();
			if (!empty($rec['data'])){
				$val = (string)($rec['data'][0]['role'] ?? 'admin');
				return $val !== '' ? $val : 'admin';
			}
		} catch (Exception $e) {}
		return 'admin';
	}
}

if (!function_exists('can')) {
	function can($action, $module, $adminId = null){
		$aid = $adminId ?? m_get_session('m_admin');
		if (is_super_admin($aid)) { return true; }
		$role = role_get($aid);
		$flagField = null;
		switch ((string)$action){
			case 'view': $flagField = 'can_view'; break;
			case 'create': $flagField = 'can_create'; break;
			case 'edit': $flagField = 'can_edit'; break;
			case 'delete': $flagField = 'can_delete'; break;
			default: $flagField = 'can_view';
		}
		try {
			$db = new DB();
			// Önce modül adına göre bak
			$row = $db->table('role_permissions')
				->where('role_name', '=', $role)
				->where('module', '=', (string)$module)
				->get();
			if (!empty($row['data'])){
				return (int)($row['data'][0][$flagField] ?? 0) === 1;
			}
			// Yoksa wildcard satırına bak
			$row2 = $db->table('role_permissions')
				->where('role_name', '=', $role)
				->where('module', '=', '*')
				->get();
			if (!empty($row2['data'])){
				return (int)($row2['data'][0][$flagField] ?? 0) === 1;
			}
		} catch (Exception $e) {
			// Veri tabanı yoksa engelleme yapmayalım (geri uyumluluk)
			return true;
		}
		return false;
	}
}

// ========================================
// Admin Modül Yönetimi Yardımcıları
// ========================================

if (!function_exists('module_is_enabled')) {
	function module_is_enabled($name){
		$db = new DB();
		$key = 'module_' . trim((string)$name) . '_enabled';
		$result = $db->table('settings')->where('key_word', '=', $key)->get();
		if (($result['total_count'] ?? 0) == 0) {
			return true; // kayıt yoksa geri uyumluluk: etkin kabul et
		}
		return (string)$result['data'][0]['value'] === '1';
	}
}

if (!function_exists('module_set_enabled')) {
	function module_set_enabled($name, $enabled){
		$db = new DB();
		$date = $db->now();
		$key = 'module_' . trim((string)$name) . '_enabled';
		$val = $enabled ? '1' : '0';
		$existing = $db->table('settings')->where('key_word', '=', $key)->get();
		
		if (($existing['total_count'] ?? 0) > 0) {
			return (bool) $db->table('settings')->where('key_word', '=', $key)->update(['value' => $val, 'updated_at' => $date]);
		}
		return (bool) $db->table('settings')->insert(['key_word' => $key, 'value' => $val, 'updated_at' => $date]);
	}
}

if (!function_exists('list_admin_modules')) {
	function list_admin_modules(){
		$root = ROOT_FOLDER . '/admin/model';
		$modules = [];
		if (!is_dir($root)) { return $modules; }
		$entries = scandir($root);
		foreach ($entries as $entry) {
			if ($entry === '.' || $entry === '..') { continue; }
			$full = $root . '/' . $entry;
			// Sadece klasör olanları modül kabul et
			if (is_dir($full)) {
				// Sistemsel klasörleri hariç tut
				if (in_array($entry, ['modules'], true)) { continue; }
				$modules[] = $entry;
			}
		}
		sort($modules);
		return $modules;
	}
}

// Modül adı için kullanıcıya dönük etiket
if (!function_exists('module_label')) {
	function module_label($module){
		$mod = (string)$module;
		// Özel eşleştirmeler
		$special = [
			'menu' => 'page_title_menus',
			'theme_options' => 'page_title_theme_options',
			'languages' => 'page_title_languages',
			'themes' => 'page_title_themes',
			'admins' => 'admins.title',
			'roles' => 'roles.title',
			'settings' => 'settings.general',
			'pages' => 'page_title_pages',
			'posts' => 'page_title_posts',
			'post_categories' => 'page_title_post_categories',
			'services' => 'page_title_services',
			'service_categories' => 'page_title_service_categories',
			'projects' => 'page_title_projects',
			'project_categories' => 'page_title_project_categories',
			'teams' => 'page_title_teams',
			'team_categories' => 'page_title_teams_categories',
			'sliders' => 'menu_sliders',
			'feedback' => 'page_title_feedback',
			'request_demo' => 'page_title_request_demo',
			'modules' => 'modules.title',
		];
		if (isset($special[$mod])){
			$key = $special[$mod];
			return lang($key, [], ucfirst(str_replace('_',' ',$mod)));
		}
		// Genel: page_title_<module>
		$label = lang('page_title_' . $mod, [], null);
		if ($label !== null && $label !== 'page_title_' . $mod){ return $label; }
		// Genel: <module>.title
		$label2 = lang($mod . '.title', [], null);
		if ($label2 !== null && $label2 !== $mod . '.title'){ return $label2; }
		// Varsayılan fallback
		return ucfirst(str_replace('_',' ',$mod));
	}
}
