<?php

$chrono_start = microtime(true);

if (version_compare(PHP_VERSION, '5.0.0', '<')) {
    trigger_error('Version de php non supportee', E_USER_ERROR);
}

define('ONYX_VERSION', '2.1');

define('FILE', $_SERVER["SCRIPT_FILENAME"]);

define('ONYX', dirname(__FILE__).'/');

if (!is_readable(ONYX."ban.list")) {
    trigger_error('Fichier de ban introuvable', E_USER_ERROR);
}
if (in_array($_SERVER['REMOTE_ADDR'], file(ONYX."ban.list", FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES))) {
    die('banni');
}

require_once('require/parse.php');
require_once('require/cache.php');
require_once('require/str.php');
require_once('require/env.php');

#   *** Chargement de la configuration ***

$cached = Cache::read('_configuration_'.FILE);
if ($cached['check'] == md5_file(ONYX.'config/root.xml').md5_file(ONYX.'modules/modules.xml')) {
    $VAR = $cached['var'];
    $ENV = $cached['env'];
    define('ROOT', $cached['root']);

    foreach ($cached['modules'] as $name) {
        //if(isset($all_modules[$name]))
        {
                        $OPT = $cached['opt'][$name];

                        include_once(ONYX.'modules/'.$name.'/main.php');
                    }
    }

    define('CACHED', true);
} else {
    $xml = new DOMDocument();

    $xml->load(ONYX.'config/root.xml') or trigger_error('Erreur du fichier de configuration', E_USER_ERROR);
    $xml->normalizeDocument();
    //$xml->validate();

    if ($root = $xml->documentElement->getAttribute('root')) {
        if ($root == substr(FILE, 0, strlen($root))) {
            define('ROOT', $root);

            $search = substr(FILE, strlen($root));

            $paths = explode('/', $search);
            $paths2 = $paths;
            foreach ($paths as $key => $path) {
                for ($i = $key - 1; $i >= 0; $i--) {
                    $paths2[$key] = $paths[$i] . '/' . $paths2[$key];
                }
                if ($key != count($paths) - 1) {
                    $paths2[$key] .= '/';
                }
            }

            foreach ($xml->getElementsByTagName('config') as $value) {
                $config[$value->getAttribute('match')] = $value;
            }

            $VAR = $ENV = $modules = array();
            array_unshift($paths2, '*');

            foreach ($paths2 as $path) {
                if ($config[$path]) {
                    $VAR = array_merge($VAR, parse_config($config[$path]));

                    $ENV = array_merge($ENV, parse_config($config[$path], 'env', 'option'));

                    foreach ($config[$path]->getElementsByTagName('module') as $module) {
                        $modules[$module->getAttribute('name')] = $module;
                    }
                }
            }

            $xml_modules = new DOMDocument();
            $xml_modules->load(ONYX.'modules/modules.xml') or trigger_error('Erreur du fichier de modules', E_USER_ERROR);
            $xml_modules->normalizeDocument();
            foreach ($xml_modules->getElementsByTagName('module') as $module) {
                if (!ctype_alnum($module->getAttribute('name'))) {
                    trigger_error('Le nom du module contient des caracteres illegaux', E_USER_ERROR);
                }

                $all_modules[$module->getAttribute('name')] = $module;
            }

            $all_opt = $load_modules = array();

            foreach ($modules as $name => $module) {
                if (isset($all_modules[$name]) && !in_array($name, $load_modules)) {
                    if ($require = $all_modules[$name]->getAttribute('require')) {
                        if (!in_array($require, $load_modules)) {
                            trigger_error("Module '$name' requiert '$require'", E_USER_WARNING);
                            continue;
                        }
                    }

                    $OPT = parse_config($module, 'option');
                    $OPT = array_merge(parse_config($all_modules[$name]->getElementsByTagName('default')->item(0), 'option'), $OPT);

                    include_once(ONYX.'modules/'.$name.'/main.php');

                    $all_opt[$name] = $OPT;

                    $load_modules[] = $name;
                }
            }

            if ($xml->documentElement->getAttribute('cache')) {
                Cache::set('_configuration_'.FILE, array('var' => $VAR,'env' => $ENV, 'root' => $root,'modules' => $load_modules, 'opt' => $all_opt, 'check' => md5_file(ONYX.'config/root.xml').md5_file(ONYX.'modules/modules.xml')));
            } else {
                Cache::del('_configuration_'.FILE);
            }
        } else {
            trigger_error('Fichier hors de la racine', E_USER_ERROR);
        }
    } else {
        trigger_error('Configuration erronnee', E_USER_ERROR);
    }

    define('CACHED', false);
}

error_reporting($ENV['error_level']);

set_include_path(get_include_path() . PATH_SEPARATOR . ONYX.'include/');

ignore_user_abort($ENV['ignore_user_abort']);

setLocale(LC_TIME, $ENV['locale']);
setLocale(LC_NUMERIC, 'en_EN');

if ($VAR['chrono']) {
    function view_chrono()
    {
        global $chrono_start,$VAR;
        echo str_replace('$', round(microtime(true) - $chrono_start, 4), $VAR['chrono']);
    }
    register_shutdown_function('view_chrono');
}

if ($ENV['log_php']) {
    ini_set('error_log', ONYX.'log/php.log');
}

foreach ($ENV['ini'] as $name => $value) {
    ini_set($name, $value);
}

foreach ($ENV['header'] as $name => $value) {
    header($name.': '.$value);
}

unset($xml,$root,$search,$paths,$paths2,$path,$key,$i,$value,$config,$modules,$module,$load_modules,$xml_modules,$all_modules,$name,$require,$OPT,$all_opt,$dir,$file,$ENV,$cached);
