<?php
/**
 * Файл содержит два класса:
 * *
 * mr_core
 * uses
 * *
 * а также декларирует функцию __autoload и определяет интерфейсы:
 * *
 * i_mr_ini
 * i_mr_xmod
 * *
 * Параметры mr.ini:
 * *
 * [mr_core]
 * error_reporting -- режим вывода ошибок. Допускается константа php типа E_ALL или E_NONE
 * locale -- параметры локали. Используются в режиме LC_ALL
 * gzip -- yes|no -- включить/выключить gzip-сжатие вывода.
 * *
 * (c) Дмитрий Куринский, 2006.
 * Пространство имён: xmlns:mr=http://www.mirari.ru
 */
    
class mr_core{
 static private 
$sec$micro;
 static private 
$log=array(), $ini=array(), $rewrite=array();

 const 
version "1.8.1";

/**
 * Вход в пространство класса. Эта функция запускается автоматически при включении класса.
 */
 
static public function start()
 {
  list(
self::$secself::$micro)=explode(" "microtime(), 2);

  
self::$ini = @parse_ini_file(getcwd()."/mr.ini"true) or die("Фатальная ошибка: не найден файл конфигурации (".getcwd().", ".is_readable("mr.ini").")");

  
error_reporting(isset(self::$ini["mr_core"]["error_reporting"])?self::$ini["mr_core"]["error_reporting"]:E_NONE);
  
setlocale(LC_ALLself::$ini["mr_core"]["locale"]);


  if(@
self::$ini["mr_core"]["gzip"])
  {
   function 
mr_core_ob_set_cookie_before($s)
   {
    
setcookie("mr_core_size_before"strlen($s));
    return 
$s;
   }
   function 
mr_core_ob_set_cookie_after($s)
   {
    
setcookie("mr_core_size_after"strlen($s));
    return 
$s;
   }
   
ob_start("mr_core_ob_set_cookie_after");
   
ob_start("ob_gzhandler"9);
   
ob_start("mr_core_ob_set_cookie_before");
  }
 }

/**
 * Время с момента начала генерации странички с заданной точностью
 */
 
static public function timedef($afterpoint=12)
 {
  list(
$sec$micro)=explode(" "microtime(), 2);
  
$timedef $sec-self::$sec $micro-self::$micro;
  
$afterpoint = (int)$afterpoint;
  return 
sprintf("%01.{$afterpoint}f"round($timedef$afterpoint));
 }

/**
 * Сохраняет сообщение в массив логов, который после можно просмотреть
 */
 
static public function log($message)
 {
  
self::$log[ (string)self::timedef() ] = $message;
 }

/**
 * Возвращает текст логов в формате время => событие
 */
 
static public function log_content()
 {
  
$string="Логи выполнения программы:\n";
  foreach(
self::$log as $time=>$message)
   
$string.="  $time => $message\n";
   if(
class_exists("mr_db"false)) $string.="  ".self::timedef()." => Запросов к БД: ".mr_db::queries().", время: ".mr_db::time()." сек\n";
   
$string.="  ".self::timedef()." => Формирование и вывод логов\n";
  return 
$string;
 }

/**
 * Возвращает секцию параметров конфигурации
 */
 
static public function get_ini_array($section)
 {
  return @
self::$ini[$section];
 }

/**
 * Сохраняет переменную в массив рерайтеров. Это полезно для сохранения авторизации
 * при переходе по заголовку Location
 */
 
static public function addtorewriter($name$value)
 {
  
output_add_rewrite_var($name$value);
  
self::$rewrite[$name]=$value;
 }

/**
 * Мгновенное перенаправление пользователя
 */
 
static public function location($where="/")
 {
  
$query="";
  if(
count(self::$rewrite)>0)
   foreach(
self::$rewrite as $n=>$v)
    
$query.=($query?"&":"").$n.($v?"=$v":"");
  if(
$query$query=(strpos($where"?")!==false?"&":"?").$query;
  
header("Location: http://{$_SERVER['HTTP_HOST']}".($where{0}=="/"?"":"/").$where.$query);
 }

/**
 * Возвращает массив рерайтера
 */
 
static public function rewriter_get_array()
 {
  return 
self::$rewrite;
 }
    }

/**
 * * * * * *
 * Интерфейс передачи модулям их ini-параметров
 * * * * * *
 */
 
interface i_mr_ini{
  static public function 
set_ini_array($ini);
 }

/**
 * * * * * *
 * Интерфейс автозапуска запрошенного модуля
 * * * * * *
 */
 
interface i_mr_xmod{
  static public function 
action($action);
 }

/**
 * * * * * *
 * Класс организации модульности в программе
 * * * * * *
 */
    
class uses{
 static private 
$classes=array("uses"=>true"mr_core"=>true);

/**
 * Подключает модуль, имя которого передано в параметре.
 * Если этот модуль определяет класс, то проверяем, не нужны ли ему ini-параметры.
 * Если нужны, передаём их. Всё пишем в логи.
 * Модули имеют расширение .phps и ищутся в директориях include
 */
 
static public function module($class)
 {
  if(isset(
self::$classes[$class])) return self::$classes[$class];
  else {
   
$path self::name_to_path($class);
   if(
$f = @fopen($path"r"true))
   {
    
fclose($f);
    
self::$classes[$class] = include_once $path;
    if(
class_exists($classfalse))
    {
     
$Reflection = new ReflectionClass($class);
     if(
$Reflection->implementsInterface("i_mr_ini")) eval($class."::set_ini_array(mr_core::get_ini_array(\"$class\"));");
     
mr_core::log("Подключен класс $class");
     return 
self::$classes[$class];
    } else {
     
mr_core::log("Подключен модуль $class");
     return;
    }
   } else {
    
mr_core::log("Ошибка: не найден модуль $class");
    return 
self::$classes[$class] = false;
   }
  }
 }

/**
 * Функция преобразует имя модуля в путь к нему.
 */
 
static protected function name_to_path($name)
 {
  return 
$name.".phps";
 }
    }

 function 
__autoload($class)
 {
  return 
uses::module($class);
 }

 return 
mr_core::start();
?>