Files
CodePress/cms/core/config.php
T
E.Noorlander 06785e9922 CodePress CMS v1.9.0: visitor statistics with SVG world map and GeoIP
- Add GeoIP class with provider chain: local DB-IP Lite, MaxMind .mmdb, external API
- Add built-in pure-PHP MMDBReader so .mmdb works without Composer
- Add cli/geoip-update.php to download DB-IP Lite and build a compact binary index
- Add cli/generate-world-map.php to generate the world map SVG from Natural Earth TopoJSON
- Add Analytics class aggregating stats in admin/storage/stats.json with LOCK_EX
- Add admin statistics page with choropleth world map, country list, top pages,
  daily chart, referrers and a period filter
- Add GeoIP and privacy settings with database update and stats reset buttons
- Add optional IP anonymization and configurable retention period
- Add country field to requests.log (parser accepts 7, 8 or 9 fields)
- Add country column to request log and KPI cards to the dashboard
- Ignore GeoIP binaries and stats.json in Git
- Update TODO.md, guides and version to 1.9.0
2026-07-29 15:40:02 +02:00

126 lines
4.6 KiB
PHP

<?php
// Simple configuration loader
$configJsonPath = __DIR__ . '/../../config.json';
$configExamplePath = __DIR__ . '/../../config.json.example';
// Auto-create config.json if it does not exist
if (!file_exists($configJsonPath)) {
if (file_exists($configExamplePath)) {
@copy($configExamplePath, $configJsonPath);
} else {
$defaultConfig = [
'site_title' => 'CodePress',
'content_dir' => 'content',
'templates_dir' => 'cms/templates',
'active_theme' => 'default',
'default_page' => 'auto',
'language' => [
'default' => 'nl',
'available' => ['nl', 'en']
],
'seo' => [
'description' => 'CodePress CMS - Lightweight file-based content management system',
'keywords' => 'cms, php, content management, file-based'
],
'author' => [
'name' => 'E. Noorlander',
'website' => 'https://noorlander.info'
],
'show_version' => true,
'enabled_plugins' => ['MQTTTracker', 'HTMLBlock'],
'features' => [
'auto_link_pages' => true,
'search_enabled' => true,
'breadcrumbs_enabled' => true
],
'security' => [
'block_ai_bots' => true,
'block_scrapers' => true,
'block_search_engines' => false,
'block_empty_user_agent' => true,
'rate_limit_enabled' => true,
'rate_limit_max' => 60,
'rate_limit_window' => 60,
'custom_blocked_agents' => [],
'blocked_ips' => [],
'allowed_ips' => []
],
'analytics' => [
'enabled' => true,
'anonymize_ip' => false,
'geoip_provider' => 'local',
'geoip_mmdb_path' => '',
'geoip_api_url' => '',
'geoip_api_key' => '',
'retention_days' => 400
]
];
@file_put_contents($configJsonPath, json_encode($defaultConfig, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
}
}
if (file_exists($configJsonPath)) {
$jsonContent = file_get_contents($configJsonPath);
$config = json_decode($jsonContent, true);
if (json_last_error() === JSON_ERROR_NONE && is_array($config)) {
// Merge defaults for sections that may be missing in existing installs
$sectionDefaults = [
'security' => [
'block_ai_bots' => true,
'block_scrapers' => true,
'block_search_engines' => false,
'block_empty_user_agent' => true,
'rate_limit_enabled' => true,
'rate_limit_max' => 60,
'rate_limit_window' => 60,
'custom_blocked_agents' => [],
'blocked_ips' => [],
'allowed_ips' => [],
],
'analytics' => [
'enabled' => true,
'anonymize_ip' => false,
'geoip_provider' => 'local',
'geoip_mmdb_path' => '',
'geoip_api_url' => '',
'geoip_api_key' => '',
'retention_days' => 400,
],
];
foreach ($sectionDefaults as $section => $defaults) {
$config[$section] = array_merge($defaults, is_array($config[$section] ?? null) ? $config[$section] : []);
}
// Convert relative paths to absolute
$projectRoot = __DIR__ . '/../../';
if (isset($config['content_dir']) && strpos($config['content_dir'], '/') !== 0) {
$config['content_dir'] = $projectRoot . $config['content_dir'];
}
if (isset($config['templates_dir']) && strpos($config['templates_dir'], '/') !== 0) {
$config['templates_dir'] = $projectRoot . $config['templates_dir'];
}
// Load active theme
$activeTheme = $config['active_theme'] ?? 'default';
$themeDir = __DIR__ . '/../../themes/' . $activeTheme;
$themeFile = $themeDir . '/theme.json';
if (file_exists($themeFile)) {
$themeConfig = json_decode(file_get_contents($themeFile), true);
$config['theme'] = $themeConfig;
} else {
$config['theme'] = [];
}
return $config;
}
}
// Fallback to minimal config
return [
'site_title' => 'CodePress',
'content_dir' => __DIR__ . '/../../content',
'templates_dir' => __DIR__ . '/../templates',
'default_page' => 'auto'
];