<?php

use Mpdf\Tag\P;

include_once('i_general.php') ;
include_once('i_adds_class.php') ;
 include_once('i_db2.php') ;
 include_once('i_func.php') ;
 include_once('i_debug.php') ;
 include_once('c_objects.php');
 include_once('c_system.php');
 include_once('i_fast_food.php');
 include_once(_DIR_TO_MODULES.'/accounts/i_account.php');

 define('_REQUEST_UID',md5(uniqid(rand(),true))) ; // UID текущего запроса на выдачу страницы, под этим UID будет сохранен лог страницы
 set_error_handler("userErrorHandler");
 register_shutdown_function('myShutdownHandler');


// временно для совместимости с path.php
// оставлено тут так как i_base подключается перед объявлением модулей в patch.php
if (!isset($GLOBALS['_SETTING']['modules']) and _sizeof($GLOBALS['use_modules'])) foreach($GLOBALS['use_modules'] as $name) $GLOBALS['_SETTING']['modules'][$name]=1 ;

 set_time_point('start') ;

//*************************************************************************************************************************************/
//
// фукции вывода страниц сайта
//
//*************************************************************************************************************************************/

  function cashe_show_page(&$options=array()){ show_page($options); }
  function fast_show_page(&$options=array()){ $options['engine_upload_mode']='fast' ; show_page($options); }

  function engine_start($options=array())
  { connect_database() ;   // законектиться к базе

    session_boot($options) ; // грузим сессию, возвращается код, который был прописан в модулях вне функций

    reboot_setting_from_DB() ; // загружаем настройки с базы в GLOBALS. В сессию они больше не грузятся

    setting_setup($options) ; // настройка переменных после первой загрузки сесиии

    _exit() ; // !!! обязательная операция 1.защита от дописывания вирусов в конец страницы  2.Предотвращение повторного определения класса для страниц ALL-IN_VAN
  }

  function show_page($options=array())
  { if (defined('no_show_page')) return ; // предотвращение зацикливания кода для ALL-IN-VAN страниц
    if (!defined('_CUR_ID')) define('_CUR_ID',0) ;
    if (!defined('_CUR_FILTER')) define('_CUR_FILTER','') ;
    if (!defined('ESMO_STATUS')) define('ESMO_STATUS','work') ;
    if (!defined('_CUR_CAB_DIR')) define('_CUR_CAB_DIR','') ;

    if ($options['ext']=='setting') $options['ext']='aspmo_setting' ;

    connect_database() ;   // законектиться к базе

    $boot_HTML=session_boot($options) ; // грузим сессию, возвращается код, который был прописан в модулях вне функций

    reboot_setting_from_DB() ; // загружаем настройки с базы в GLOBALS. В сессию они больше не грузятся

    if ($GLOBALS['LS_debug_mode']) { $GLOBALS['time_line_mode']=2; }

    if (_CUR_SHEME!=_MAIN_PROTOCOL and $GLOBALS['LS_redirect_to_main_sheme'])
    {  LOGS()->reg_log('redirect_301_to', 'Текущий протокол ['._CUR_SHEME.'] не соответсвует заданной в настроках схеме ['._MAIN_PROTOCOL.']') ;

       header("HTTP/1.1 301 Moved Permanently");
         header("Location: "._MAIN_PROTOCOL._MAIN_DOMAIN.'/cab/');
        _exit() ;

      }

    if ($options['engine_upload_mode']=='fast') reboot_engine_fast() ;
    else                                        setting_setup($options) ; // настройка переменных после первой загрузки сесиии

    // проверяем авторизацию, через внешние модули, к примеру AD

   // if ($options['class_file']!='c_ajax.php')
    //    ENGINE()->on_event('check_autorize') ;

    list($script_page,$class_page,$debug_info)=include_script_page($options) ; // подключаем скрипт с классом страницы, возвращаем путь скрипта и название класса в этом скрипте
    $page_obj=null ;
    if (class_exists($class_page))
    {   // все дальшейшие обращения к экземпляру текущей страницы через _CUR_PAGE()
        $options['in']['_CUR_ID']=_CUR_ID ;
        $options['in']['_CUR_ROOT_DIR_NAME']=_CUR_ROOT_DIR_NAME ;
        $options['in']['_CUR_PAGE_DIR']=_CUR_PAGE_DIR ;
        $page_obj = new $class_page($options) ; // создание экземпляра страницы
        if (method_exists($page_obj,'init')) $page_obj->init($options) ;
        $page_obj->class_name=$class_page ;
        $page_obj->script_file=$script_page ;
        $page_obj->script_dir=dirname($page_obj->script_file).'/' ;

        $GLOBALS['_CUR_PAGE']=$page_obj ;
        $GLOBALS['cur_page']=$page_obj ;

    set_time_point('Создание объекта <strong>_CUR_PAGE</strong>') ;

        $page_obj->show($options) ;  // выводим страницу
        echo $boot_HTML ;

    set_time_point('Вывод объекта <strong>_CUR_PAGE</strong>') ;

    set_time_point('end') ;
    // при включенном режим отладки сохраняем временную трассировку страницы в файл
        if ($GLOBALS['LS_debug_mode'] and is_object($page_obj)/* and _sizeof($page_obj->HEAD)*/)
    { $options['page_trace_fname']=LOGS()->save_time_trace() ;
      LOGS()->logging_pages_info($options) ;
    }

    }
    else
    { echo 'Не удалось найти класс '.$class_page.' для создания страницы:<br>' ;
      echo $debug_info ;
    }

    _exit() ; // !!! обязательная операция 1.защита от дописывания вирусов в конец страницы  2.Предотвращение повторного определения класса для страниц ALL-IN_VAN
  }

  function _exit()
  {   mysqli_close($GLOBALS['DB_LINK']) ; // закрывает коннект с базой
      session_write_close() ; // закрываем сессию
      exit ; // !!! обязательная операция 1.защита от дописывания вирусов в конец страницы  2.Предотвращение повторного определения класса для страниц ALL-IN_VAN
  }

 // до старта сессии необходимо подключить все скрипты и объявить все классы, объекты которых хранятся в памяти сесии
 function session_boot(&$options=array())
  { global 	$debug_boot,$debug_modul,$use_script ;
    if ($options['debug_modul']) $debug_modul=1 ;
    //if (!$debug_modul)
        ob_start() ;  $html='' ;
     // подключаем модули ------------------------------------------------------------------------------------------------------------------
     // ВНИМАНИЕ! Необходимо подключить все скрипты с классами объектов, котороые хранятся в сессии до session_start,
     // иначе будет ошибка, что для объектов в сессии не существует объявление класса
     $t_before_include_script=fixed_time() ;
     if ($options['engine_upload_mode']!='fast')
     {   global $__functions ;  // !!! не удалять, так как это объявление позволяет формировать массив $__functions при подклбчении модулей

     // подключаем обязательные модули
         //if (_sizeof($use_script)) foreach($use_script as $script_name)  include_once(_DIR_TO_ROOT.'/'.$script_name);

     //damp_array(get_included_files()) ;

     // подключем модуль админки или сайта
         include_once(_DIR_TO_ENGINE.'/m_site.php');      // описание классов объектов
     if ($debug_modul) echo 'Подключаем модуль <strong>"m_site.php"</strong><br>' ;
     //    if (_ENGINE_MODE=='admin' or _SITE_CREATE_FULL_MODEL) { include_once(_DIR_TO_ENGINE.'/m_admin.php');  if ($debug_modul) echo 'Подключаем модуль <strong>"m_admin.php"</strong><br>' ; }

     // подключаем все дополнительные модули, идущие в составе движка (находятся в /engine/moduls/)
     // внимаение!!! модули, которые переопеделены в modules_local не должны подключаться в modules, так как будет конфликт по имени класса
     //damp_array($GLOBALS['_SETTING'],1,-1) ;
     if (_sizeof($GLOBALS['_SETTING']['modules'])) foreach($GLOBALS['_SETTING']['modules'] as $modul_name=>$enabled)
     { if ($enabled)
       { if (!$GLOBALS['_SETTING']['modules_local'][$modul_name]) include_modul(_DIR_TO_MODULES,$modul_name) ;
         else if ($debug_modul) echo 'Подключаем модуль <strong>"'.$modul_name.'"</strong> - ОТМЕНА, модуль <strong>'.$modul_name.'</strong> переопределен в локальном классе<br>' ;
       }
     }
         if (_sizeof($GLOBALS['_SETTING']['modules_local'])) foreach($GLOBALS['_SETTING']['modules_local'] as $modul_name=>$enabled) if ($enabled) include_modul(_DIR_TO_MODULES_LOCAL,$modul_name) ;

     if ($debug_modul) echo 'Подключаем <strong>плагины</strong><br>' ;
     if (_sizeof($GLOBALS['_SETTING']['plugins'])) foreach($GLOBALS['_SETTING']['plugins'] as $plugin=>$enabled)
     { if ($enabled)
       { if (!$GLOBALS['_SETTING']['plugins_local'][$plugin]) include_plugin(_DIR_TO_MODULES.'/plugins/',$plugin) ;
         else if ($debug_modul) echo 'Подключаем плагин <strong>"'.$plugin.'"</strong> - ОТМЕНА, плагин <strong>'.$plugin.'</strong> переопределен в локальном классе<br>' ;
       }
     }
         if (_sizeof($GLOBALS['_SETTING']['plugins_local'])) foreach($GLOBALS['_SETTING']['plugins_local'] as $plugin=>$enabled) if ($enabled) include_plugin(_DIR_TO_MODULES_LOCAL.'/plugins/',$plugin) ;

         //подсключаем все статичные шаблоны
         // в дальнейшем заменить все static_modul и $use_tempates_static на upload_template
         //if (_sizeof($GLOBALS['__functions']['static_modul'])) foreach($GLOBALS['__functions']['static_modul'] as $modul_patch) if (file_exists(_DIR_TO_ROOT.'/'.$modul_patch)) include_once(_DIR_TO_ROOT.'/'.$modul_patch); //else if (_IS_SYSTEM_IP) echo 'Не найден скрипт "'.$modul_patch.'"' ;
         //if (_sizeof($GLOBALS['__functions']['upload_template'])) foreach($GLOBALS['__functions']['upload_template'] as $script_name) if (file_exists(_DIR_TO_TEMPLATES.'/'.$script_name)) include_once(_DIR_TO_TEMPLATES.'/'.$script_name); //else if (_IS_SYSTEM_IP) echo 'Не найден скрипт "'.$script_name.'"' ;
         //if (_sizeof($GLOBALS['use_tempates_static'])) foreach($GLOBALS['use_tempates_static'] as $template_name) include_once(_DIR_TO_CLASS.'/'.$template_name);


         if (!$options['no_use_modules'])
         {  if ($debug_modul) echo 'Подключаем EXT-модуль сайта <strong>"mc_ext_moduls.php"</strong><br>' ;
            include_once(_DIR_TO_CLASS.'/mc_ext_moduls.php');      // описание классов объектов
         }

         if ($debug_boot) { echo '<div class="green bold">Список подключенных файлов:</div>'; damp_array(get_included_files(),1,0) ;    }
     }
     else
     {  if ($options['load_modul']) foreach($options['load_modul'] as $modul_name)  include_once(_DIR_TO_MODULES.'/'.$modul_name.'/m_'.$modul_name.'.php');
     }

     $GLOBALS['t_include_script']=fixed_time($t_before_include_script) ;
     set_time_point('Подключение скриптов ('._sizeof(get_included_files()).' files)') ;

        // открываем сесиию ----------------------------------------------------------------------------------------------------------------------------
      // отдельное название для сессии в браузере, чтобы данные админки не смешивались с данными сайта в пределах одного браузера и домена
     if (!$GLOBALS['session_name']) $GLOBALS['session_name']=str_replace('.','',_ENGINE_MODE._MAIN_DOMAIN) ;  // разводим сессию сайта и админки
     session_name($GLOBALS['session_name']) ;
    set_time_point('Задано session_name') ;

        // формируем session_id для роботов - чтобы роботы каждый раз не создавали новую сессию, а использовали уже открытую, которая будет жить не более суток
      if ($GLOBALS['flags']['is_robot']) $session_uid=str_replace(array('.','_',':'),'',IP.'_'._BASE_DOMAIN.'_'.date('d_m_y',time())) ;
      if ($options['use_session_id'])    $session_uid=$options['use_session_id'] ;

      if ($debug_boot and $session_uid) echo 'session_id set to '.$session_uid.'<br>' ;
      if ($session_uid)  session_id($session_uid) ;
    set_time_point('Задано session_id') ;

    $temp_flags=$GLOBALS['flags'];
    $t_before_open_session=fixed_time() ;

    session_start() ;
    set_time_point('session_start') ;
    $GLOBALS['t_open_session']=fixed_time($t_before_open_session) ;

      if (isset($_COOKIE['session_end']) and $_COOKIE['session_end']>0 and $_COOKIE['session_end']<time() and MEMBER()->id)
      {
          if (is_numeric(MEMBER()->autologout) and MEMBER()->autologout>0) {
              ACCOUNTS()->member_logout('Автоматический выход через '.MEMBER()->autologout.' сек простоя ЭСМО') ;
          } else {
              ACCOUNTS()->member_logout('Автоматический выход через '._SESSION_LIFE_TIME.' сек простоя ЭСМО') ;
      }
      }
      if (is_numeric(MEMBER()->autologout) and MEMBER()->autologout>0) {
          setcookie('session_end',time()+MEMBER()->autologout,time()+100000,'/') ;
      } else {
      setcookie('session_end',time()+_SESSION_LIFE_TIME,time()+100000,'/') ;
      }

      set_time_point('check_account_logout') ;



    if ($options['clear_session']) $_SESSION=array() ;
    if ($_SESSION['SES_trace_SQL']) { $GLOBALS['debug_db']=1 ; $GLOBALS['time_line_mode']=2; }
    //if ($_SESSION['SES_trace_page']) { $GLOBALS['time_line_mode']=2; }
    //if ($_SESSION['SES_trace_script']) { $GLOBALS['time_line_mode']=2; }

    // все глабальные переменные сохраняются в сессии - приходитмя их принудительно обнулять
    $GLOBALS['flags']=$temp_flags ;

    if ($_SESSION['cur_engine_versions']!=_ENGINE_VERS._CLASS_VERS) $options['reboot_all']=1 ;
    $_SESSION['cur_engine_versions']=_ENGINE_VERS._CLASS_VERS ;
    set_time_point('Открыли сессию') ;
    //if (!$debug_modul)
    $html=ob_get_clean() ; // echo $html ;
    if ($debug_modul) echo $html ;
    // обновляем данные текущего пользователя
    if (MEMBER()->id and function_exists('ACCOUNTS') and $options['use_session_id']!='setup') ACCOUNTS()->update_member_info(MEMBER()) ;
    set_time_point('update_member_info') ;


    return($html) ;
  }

  function include_modul($dir,$modul_name)
  { global $debug_modul ;
      //$debug_modul=1 ;
    global $__functions ;  // !!! не удалять, так как это объявление позволяет формировать массив $__functions при подклбчении модулей
     if ($debug_modul) echo 'Подключаем модуль <strong>"'.$modul_name.'"</strong><br>' ;
     if (file_exists($dir.'/'.$modul_name.'/m_'.$modul_name.'.php'))  include_once($dir.'/'.$modul_name.'/m_'.$modul_name.'.php');
     if (file_exists($dir.'/'.$modul_name.'/m_'.$modul_name.'_admin.php')) include_once($dir.'/'.$modul_name.'/m_'.$modul_name.'_admin.php');

     if ($debug_modul)
     { echo (file_exists($dir.'/'.$modul_name.'/m_'.$modul_name.'.php'))? '<div class=green>Скрипт /m_'.$modul_name.'.php  найден в '.hide_server_dir($dir).'</div>':'<div class=red>Скрипт /m_'.$modul_name.'.php  не найден в '.hide_server_dir($dir).'</div>' ;
       echo (file_exists($dir.'/'.$modul_name.'/m_'.$modul_name.'_admin.php'))? '<div class=green>Скрипт /m_'.$modul_name.'_admin.php  найден в '.hide_server_dir($dir).'</div>':'<div class=red>Скрипт /m_'.$modul_name.'_admin.php  не найден в '.hide_server_dir($dir).'</div>' ;
     }
  }

  function include_plugin($dir,$plugin_name)
  {   global $debug_modul ;
      global $__functions ;  // !!! не удалять, так как это объявление позволяет формировать массив $__functions при подклбчении модулей
      if (file_exists($dir.'i_'.$plugin_name.'.php'))
      {   include_once($dir.'i_'.$plugin_name.'.php') ;
          if ($debug_modul) echo '<div class=green>Скрипт plugins/i_'.$plugin_name.'.php  найден</div>' ;
          GENERAL()->arr_plugins[$plugin_name]=array('fname'=>$dir.'i_'.$plugin_name.'.php','class_name'=>'i_'.$plugin_name) ;
      }
      elseif ($debug_modul) echo '<div class=red>Скрипт ext/i_'.$plugin_name.'.php  не найден</div>'  ;

  }

  function setting_setup(&$options=array())
  { global $debug_modul,$reboot_all,$debug_boot ;
    //echo 'session_name='.session_name().'<br>' ;
    if (!_sizeof($_SESSION['descr_obj_tables'])) { $reboot_all=1 ; if ($debug_boot) echo 'Назначена перезагрузка - нет модели объектных таблиц<br>' ;
        set_time_point('азначена перезагрузка - нет модели объектных таблиц, session_name='.session_name()) ;

    }// когда роботы при доллом обходе используют один id сессии - она имеет лимит жизни. Перегружаем заново данные для восстановления

    //15.08.12 - удалено, теперь значения формы сохранябтся в $_SESSION['form_values'] через вызов system->save_form_values_to_session
    // вызов необходимо прописывать вручную там, где есть необходиомость сохранения значения форм
    //save_form_params() ; // сохраняем значения форм в глобальном массиве
    // проверяем условия для автоматического назначения флага перезагрузки движка
    if ($options['reboot_all']) 	{	$reboot_all=1 ; if ($debug_boot) echo 'Назначена перезагрузка - опция $options[reboot_all]<br>' ; }
    if (isset($_POST['reboot'])) 	{	$reboot_all=1 ; if ($debug_boot) echo 'Назначена перезагрузка - передано $_POST[reboot]<br>' ; }
    if ($_SESSION['__fast_edit_mode']=='enabled')  {	$reboot_all=1 ; if ($debug_boot) echo 'Назначена перезагрузка - режим быстрого редактирования<br>' ; }
    if (_IS_SYSTEM_IP and _REBOOT_ALL_FOR_SYSTEM_IP) { $reboot_all=1 ; echo 'Назначена перезагрузка - _REBOOT_ALL_FOR_SYSTEM_IP<br>' ; }	// клиент в списке своих  - перегружать всегда
    if ($options['reboot_by_refresh_page'] and $_SESSION['last_view_page']==$_SERVER['REQUEST_URI']){ $reboot_all=1 ; echo 'Назначена перезагрузка - $options[reboot_by_refresh_page]<br>' ; }
    if (!$_SESSION['_flags']['objects_boot_'._ENGINE_MODE] and $debug_boot) { echo 'Назначена перезагрузка - $objects_boot_'._ENGINE_MODE.'=0<br>' ; }
    if (!$_SESSION['_flags']['objects_boot_'._ENGINE_MODE] or $reboot_all)  reboot_engine($options) ; // если настройки сайта и админки еще не загружены, загружаем их
    else if ($debug_boot) echo 'Перезагрузка не производиться - нет оснований<br>' ;
	// подключаем объявленные в init.php модули php - отмена, устарело
	//global $arr_file_php ; if (_sizeof($arr_file_php)) foreach($arr_file_php as $script_name)  include_once(_DIR_TO_ROOT.'/'.$script_name);

    global $cur_val,$val ; if (isset($val)  or !isset($cur_val))    $cur_val=(isset($val))? $val:0 ; // установка текущей валюты

    global $reboot_all ; if ($debug_modul) echo '<span class=red>Команда перезагрузки ядра $reboot_all='.$reboot_all.', $objects_boot_'._ENGINE_MODE.'='.$_SESSION['_flags']['objects_boot_'._ENGINE_MODE].'</span><br>' ;
    //global $ggs ; echo '$ggs='.$ggs.'<br>' ;

    // если режим инсталяции движка создаем систему классов и на этом закругляемся
    /*  временно отклбчено до разработки нового инсталятора
    if ($options['install_mode'])
    {   create_class_model() ;    //echo 'Классы' ;
        $_SESSION['list_db_tables']=get_db_info() ;
        if (!$_SESSION['list_db_tables']['obj_descr_obj_tables']) return ;
        create_model_obj_tables() ;
        return ;
    } */


    //damp_array($_SESSION['list_created_sybsystems']) ;
    if (_sizeof($_SESSION['list_created_sybsystems'])) foreach($_SESSION['list_created_sybsystems'] as $system_tkey=>$system_name) define(strtoupper($system_name),$system_name) ;

    // 4.02.12 - вынести этот блок в отдельную функцию модуля partners
    /*
    global $partners_system,$partner_uid ;
    if (isset($partners_system) and $partner_uid and !$_SESSION['member']->info['sales']) $partners_system->set_member_sales($partner_uid) ;
    //$_SESSION['member']->read_cookies() ;
    */

    compatible_options_names($options) ; // преобразование старых имен опций в новые


    set_time_point('setting_setup - OK') ;
  }

  // минимальная загрузка движка
  // - без модулей
  // - без описания классов
  //
  function reboot_engine_fast()
  { init_system_vars() ;
    create_model_obj_tables(array('no_describe_tables'=>1)) ;
    reboot_setting_from_DB() ;
    $_SESSION['events_system']=new c_events_system(array('table_name'=>'log_'.SITE_CODE.'_events')) ;
    compatible_options_names() ;
  }

  // перезагрузка движка - обновление всех данных сесссии
  // выполняется после загрузки сессии если сессия пуста
  // важна последовательность загрузки данных
  function reboot_engine($options=array())
  { global $debug_boot,$debug_modul ;
    //ENGINE()->event_lister=array() ;
    //trace() ;
    if ($debug_boot) echo '<strong>Вызвана функция перезагрузки</strong><br>' ;
    if ($debug_boot) echo 'Размер сессии:'._sizeof($_SESSION).'<br>' ;
    // загружаем системные переменные значениями по умолчанию при полной перезагрузке
    // обяъвление всех системных массивов - существующие будут обнулены и переопределены заново
    // ВНИМАНИЕ!!! после вызова init_system_vars необходимо переглобавлить все переменные, вызываемые таким образом
    init_system_vars() ;

    // Создаем модель объектных таблиц. Внимание! init.php еще не подключен, описание descr_tables не будет использовано
    if (_ENGINE_MODE=='admin') create_model_obj_tables() ;
    else                       create_model_obj_tables(array('no_describe_tables'=>1)) ; // Создаем модель объектных таблиц

    // тут необходимо бы создать можель классов, но описание сайтовских классов еще не загружено
    // надо бы выделить их в отдельную функицю и подгружать тут

    // грузим в сессию переменные сайта из базы  - переменные загрузаются при каждом обращении из базы
    //reboot_setting_from_DB() ;

    // грузим в сесию роли
    boot_roles() ;

    // грузим в сесию значения индексных таблиц
    // 26.09.16 - будет подтягиваться из вьюверов по ходу обращения к спискам
    boot_index_list() ;

    // загружаем почтовые аккаунты
    //boot_email_account() ;  - больше не требуется, параметры подключения хранятися в настройках


    include_once(_DIR_TO_ENGINE.'/i_descr_clss.php') ;   // описания всех классов (без модулей)
    declare_class() ;

    // иницилизируем настройки модулей -----------------------------------------------------------------------------------------------------------------------
    // это аналоги функций  init_system_vars - но для каждого модуля отдельно
    if ($debug_modul) { echo '<div class="green bold">Загружаем настройки модулей</div>' ; /*Список заданных функций насттройки' ; damp_array($GLOBALS['__functions']['init'],1,-1) ; */ }
    foreach($GLOBALS['__functions']['init'] as $init_func_name) { $init_func_name($options) ; if ($debug_modul) echo 'Выполнена функция инициализации переменных <strong>'.$init_func_name.'()</strong><br>' ; }

    // грузим в сессию переменные сайта
    //include_once(_DIR_TO_ROOT.'/ini/'._INIT_) ;
    //init_local_setting() ;
    //if (function_exists('init_admin_setting'))  init_admin_setting() ;  // грузим переменные адмики

    // новая схема хранения описаний классов в ini. Пока вносим классы в сесию для обеспечания совместимости, как только все классы будут описаны по новой схеме
    // описания классов будут удалены из сесиии
    // удаляем  добавляение в сесиию классов, описанных в clss.yaml
    // вместо этого будем создавать модель классов на основе данных из сессии и из clss.yaml
    // !!! в сессию описания классов больше не ложим, нет необходимости
    //$arr_ini_clss=SETUP()->load_ini_setting('/ini/clss.yaml') ;
    //if (_sizeof($arr_ini_clss)) foreach($arr_ini_clss as $clss=>$descr_clss) $_SESSION['descr_clss'][$clss]=$descr_clss ;

    // Создаем модель классов
    create_class_model() ;



    //damp_array($_SESSION['img_pattern']) ;

    // глобалим переменые сессии, так как после сразу объявления переменной в сессии, до первой перезагурзки страницы, переменные автоматически в GLOBAL не попадают
    // в идеале ко всем переменным сессии обращается не через  global, а через SESSION
    // 22.05.12 - проблема решена через новый session_declare
    //if (_sizeof($_SESSION)) foreach($_SESSION as $name=>$value) $GLOBALS[$name]=$value ;

    // создаем объекты модулей ----------------------------------------------------------------------------------------------------------------------
    // выполняются функции function _xxx_site_boot($options) всех подключенных модулей
    // в этих функциях, как правило идет команда create_system_modul_obj('xxx') ;
    //echo '$reboot_all='.$reboot_all.'<br>' ;
    //echo '$objects_boot_'._ENGINE_MODE.'='.$_SESSION['_flags']['objects_boot_'._ENGINE_MODE].'<br>' ;
    create_static_subsystems($options) ;  // выполняются функции из массива $__functions['boot_admin'][] или $__functions['boot_site'][]
    //create_dynamic_subsystems() ; // 2.04.2011 - вынесена из m_site.php т.к. должны выполняться после создания всех статических подсистем сайта // 10.12.12 - заменена опцией  "no_root_dir" в подсистеме
    //damp_array($_SESSION['list_created_sybsystems']) ;
    if (function_exists('after_init_system')) { after_init_system() ; set_time_point('after_init_system - OK') ; }
    $_SESSION['_flags']['objects_boot_'._ENGINE_MODE]=1 ; // сохраняем в сессии флаг успешной загрузки движка
    $GLOBALS['flags']['is_reboot']=1 ; // данный флаг будет сохранен в журнал - признак полной загрузки движка
    //damp_array($GLOBALS['flags']) ;
    //damp_array($_SESSION['_flags']) ;


    if (is_object($_SESSION['member']) and $_SESSION['member']->id)
    {  $system=($_SESSION['member']->use_system)? $_SESSION[$_SESSION['member']->use_system]:$_SESSION['account_system'] ;
       if (is_object($system) and method_exists($system,'update_member_info')) $system->update_member_info($_SESSION['member']) ;
    }

    // переходная функция после начала хранения информации по отчетам в базе и до тех пор, пока системы храняться в виде объектов сессии
    // загрущаем в объект массивы reports_list reports_sections docs_list
    // которые создавались при старой функции reg_reports
    // после перехода на создание объектов по вызову данные массивы будут загружаться из базы только при обращении к ним
    if (function_exists('ENGINE') and method_exists(ENGINE(),'upload_reports_docs')) ENGINE()->upload_reports_docs() ;

  }

  // автоматическая подгрузка классов страниц и фреймов для админки
  /*function __autoload($class_name)
  { if (_ENGINE_MODE=='admin')
    {   $script_name=_DIR_TO_ENGINE.'/admin/'.$class_name.'.php' ;
        if (file_exists($script_name)) include_once($script_name) ;
    }
  } */

  // определяем текущий скрипт страницы и название используемого класса
  // в переменной сервера $_SERVER['SCRIPT_FILENAME'] имеет имя входного скрипта, который апач вызвал для отработки текущего запроса
  // на выбор этого скрипта вляют настройки араche и содержимое .htaccess
  // в .htaccess может выбираться входной скрипт в зависимоти от содержания текущего запроса
  // необходимо на основании имени скрипта, пути скрипта и текущего домена/поддомена подключить правильный скрипт из /class/ для вызова класса страницы

  function include_script_page(&$options=array())
  { global $debug_page ;
    $debug_arr=array() ;

    $php_source=basename($_SERVER['SCRIPT_FILENAME']) ;        //echo 'php_source='.$_SERVER['SCRIPT_FILENAME'].'<br>';
    $in_script_name=str_replace(array('.php','.html'),'',$php_source) ; // имя входного скрипта без .html и .php
    $in_script_dir=dirname(hide_server_dir($_SERVER['SCRIPT_FILENAME'])) ; // пусть входного скрипта без пути до сайта
    //$in_script_dir=str_replace("\\","/",$in_script_dir) ;
    $in_script_dir=str_replace("\\","",$in_script_dir) ;
    $in_script_domain=_CUR_SUBDOMAIN ;

    global $dir_to_engine ; // !!! внимание - переменую не удалять, в противном случае перестанет работать include ($dir_to_engine."c_page_HTML.php") ; в скриптах сайта
    ob_start() ;

    //$options['debug']=1 ;

    if ($debug_page)
      {  ?><div style='background:white;'><strong>Информация по странице:</strong><br><?
         $arr=array() ;
         $arr['Входной скрипт']=array('<strong>$_SERVER[SCRIPT_FILENAME]</strong>',$_SERVER['SCRIPT_FILENAME']) ;
         $arr['Поддомен']=array('<strong>in_script_domain</strong>',$in_script_domain) ;
         $arr['Путь к скрипту страницы']=array('<strong>in_script_dir</strong>',$in_script_dir) ;
         $arr['Имя страницы']=array('<strong>in_script_name</strong>',$in_script_name) ;
         print_2x_arr($arr) ;
         echo '<strong>Переданные $options для создания страницы:</strong><br>' ;
         damp_array($options,2,0) ;
         ?></div><?
      }

     if ($in_script_name!='ajax')
     { $base_page_file=_DIR_TO_CLASS."/c_page.php" ;
     $base_class_name=($options['class_file']!='this')? 'c_page':'c_page_'.$in_script_name ;
     }
     else
     { $base_page_file=_DIR_TO_CLASS."/c_ajax.php" ;
       $base_class_name='c_page_ajax' ;
     }

     // получаем имя файла с классом текущей страницы
     $use_script_file=get_name_class_file($in_script_dir,$in_script_name,$options) ;
     $use_script_file_local=get_name_class_file_local($in_script_dir,$in_script_name,$options) ;
     $GLOBALS['cur_page_script_name']=$use_script_file ;
     $debug_arr['Файл класса текущей страницы']=array('<strong>class_file</strong>',hide_server_dir($use_script_file),(file_exists($use_script_file)? '<span class=green>+++</span>':'<span class=red>-</span>')) ;

     // получаем имя класса страницы
     $class_name=get_name_class($in_script_dir,$in_script_name,$options) ;
     $GLOBALS['cur_page_class_name']=$class_name ;

     // делаем проверку на существование файлов скриптов класса и шаблона класса
     // должен существовать либо файл класса либо файл шаблона либо базовый файл страницы.
     // если ни один из файлов не существует - выдаем ошибку
     if (file_exists($use_script_file_local))
     { define('no_show_page',1) ; // предотвращение повторного выполнения цикла по show_page
       if ($options['class_file']!='this') include($use_script_file_local) ;
       // в локальном скрипте страницы класс страницы может называться с_page_SCRIPT
       if (class_exists($class_name))                   $use_class_name=$class_name ;       // в первую очередь пытаемся использовать именной класс страницы, например c_page_account_create_shop
       else                                             $use_class_name=$base_class_name ;  // иначе используем стандарное
     }
     elseif (file_exists($use_script_file))
     { define('no_show_page',1) ; // предотвращение повторного выполнения цикла по show_page
       if ($options['class_file']!='this') include($use_script_file) ;
       // в локальном скрипте страницы класс страницы может называться с_page_SCRIPT
       if (class_exists($class_name))                   $use_class_name=$class_name ;       // в первую очередь пытаемся использовать именной класс страницы, например c_page_account_create_shop
       else                                             $use_class_name=$base_class_name ;  // иначе используем стандарное
     }
     else
     { $use_script_file=$base_page_file ; // если ни одного класса не было найдено - использует класс базовой страницы сайта
       include_once($use_script_file) ;
       // в скрипте базовой страницы класс страницы может называться только с_page
       $use_class_name=$base_class_name ;
     }

     ?><div style='background:white;'><strong>Информация по скрипту и классу страницы:</strong><br><?
        $debug_arr['Класс текущей страницы']=array('<strong>class_name</strong>',$class_name,(class_exists($class_name)? '<span class=green>+++</span>':'<span class=red>-</span>')) ;
        print_2x_arr($debug_arr) ;
     ?></div><div style='background:white;'><strong>Итоговая информация:</strong><br><?
             $arr=array() ;
             $arr['Используемый скрипт страницы']=array('<strong>use_script_file</strong>',hide_server_dir($use_script_file),(file_exists($use_script_file)? '<span class=green>+++</span>':'<span class=red>-</span>')) ;
             $arr['Используемый класс страницы']=array('<strong>use_class_name</strong>',$use_class_name,(class_exists($use_class_name)? '<span class=green>+++</span>':'<span class=red>-</span>')) ;
             print_2x_arr($arr) ;
             ?></div><?

    set_time_point('include_script_page - OK') ;

    $text=ob_get_clean()  ;
    $GLOBALS['_debug_page_trace'].=$text ;

    // вывод _debug_page_trace надо делаить после вывода контента страницы
    if ($GLOBALS['debug_page']) echo $text ;

    return(array($use_script_file,$use_class_name,$text)) ;
  }

 function type_page(&$options=array()) {}

//*************************************************************************************************************************************/
//
// ОПРЕДЕЛЕНИЕ ПОДКЛЮЧЯЕМОГО  class_script
//
//*************************************************************************************************************************************/

// возвращает имя файла класса для скритра сайта
// предусмотреть возможность получения имени скрипта не по пути in_script а по _CUR_PAGE_DIR
// необходио для работы личных кабинетов, когда необходимо иметь множетство class_script чкерез один in_script в запсисмости от _CUR_PAGE_DIR
// уже сделано в квазаре
// $arr=explode('/',_CUR_PAGE_DIR) ;
// if ($arr[3])     { $options['class_file']='c_'.$arr[2].'_'.$arr[3].'.php' ; $options['class_name']='c_page_'.$arr[1].'_'.$arr[2].'_'.$arr[3] ; }
// elseif ($arr[2]) { $options['class_file']='c_'.$arr[2].'.php' ;             $options['class_name']='c_page_'.$arr[1].'_'.$arr[2] ; }
// else             { $options['class_file']='c_index.php' ;                   $options['class_name']='c_page_'.$arr[1] ; }

function get_name_class_file($in_script_dir,$in_script_name,&$options=array())
{   if ($options['debug']) echo 'in_script_dir='.$in_script_dir.'<br>' ;
    if ($options['debug']) echo 'in_script_name='.$in_script_name.'<br>' ;
    if ($options['debug']) echo 'options='.print_r($options).'<br>' ;
    if ($in_script_dir=='') $in_script_dir='/' ;

    $dir_name=ltrim($in_script_dir,'/') ; // удалеям / из начала строки
    $dir_name=str_replace(array('/','-'),'_',$dir_name) ; // заменяем остальные слеши на _
    // получаем имя файла локального скпипта страницы
    if (isset($options['class_file']))     $use_class_file=$options['class_file'] ;
    else if ($in_script_dir=='/')          $use_class_file='c_'.$in_script_name.'.php' ;
    else if ($in_script_name=='index')     $use_class_file='c_'.$dir_name.'.php' ;
    else                                   $use_class_file='c_'.$dir_name.'_'.$in_script_name.'.php' ;
    if ($options['script_dir']) $options['use_include_patch']=$options['script_dir'] ;
    if ($options['ext']) $options['use_include_patch']=_DIR_EXT.'/'.basename($options['ext']).'/' ;
    if ($options['ext_local']) $options['use_include_patch']=_DIR_EXT_LOCAL.'/'.basename($options['ext_local']).'/' ;
    $class_file=((isset($options['use_include_patch']))? $options['use_include_patch']:_DIR_TO_CLASS.'/').$use_class_file ;
    // спациальная вставка для страниц, код которых находится в одной файле со стартовым кодом
    if ($options['class_file']=='this') $class_file=$_SERVER['SCRIPT_FILENAME'] ;
    if ($options['debug']) echo 'class_file='.$class_file.'<br>' ;
    return($class_file) ;
}

function get_name_class_file_local($in_script_dir,$in_script_name,&$options=array())
{   if ($options['debug']) echo 'in_script_dir='.$in_script_dir.'<br>' ;
    if ($options['debug']) echo 'in_script_name='.$in_script_name.'<br>' ;
    if ($options['debug']) echo 'options='.print_r($options).'<br>' ;
    if ($in_script_dir=='') $in_script_dir='/' ;

    $dir_name=ltrim($in_script_dir,'/') ; // удалеям / из начала строки
    $dir_name=str_replace(array('/','-'),'_',$dir_name) ; // заменяем остальные слеши на _
    // получаем имя файла локального скпипта страницы
    if (isset($options['class_file']))     $use_class_file=$options['class_file'] ;
    else if ($in_script_dir=='/')          $use_class_file='c_'.$in_script_name.'.php' ;
    else if ($in_script_name=='index')     $use_class_file='c_'.$dir_name.'.php' ;
    else                                   $use_class_file='c_'.$dir_name.'_'.$in_script_name.'.php' ;
    if ($options['script_dir']) $options['use_include_patch']=$options['script_dir'] ;
    if ($options['ext']) $options['use_include_patch']=_DIR_EXT_LOCAL.'/'.basename($options['ext']).'/' ;
    $class_file=((isset($options['use_include_patch']))? $options['use_include_patch']:_DIR_TO_CLASS.'/').$use_class_file ;
    // спациальная вставка для страниц, код которых находится в одной файле со стартовым кодом
    if ($options['class_file']=='this') $class_file=$_SERVER['SCRIPT_FILENAME'] ;
    if ($options['debug']) echo 'class_file='.$class_file.'<br>' ;
    return($class_file) ;
}

// возвращает имя файла класса для скритра сайта
function get_name_class_file_admin($in_script_name,&$options=array())
{   if ($options['debug']) echo 'in_script_name='.$in_script_name.'<br>' ;
    if ($options['debug']) echo 'options='.print_r($options,1).'<br>' ;

    // получаем имя файла локального скпипта страницы
    if (isset($options['class_file']))     $use_class_file=$options['class_file'] ;
    else                                   $use_class_file='c_'.$in_script_name.'.php' ;

    if ($options['script_dir']) $options['use_include_patch']=$options['script_dir'] ;
    if ($options['ext']) $options['use_include_patch']=_DIR_EXT.'/'.basename($options['ext']).'/' ;
    $class_file=((isset($options['use_include_patch']))? $options['use_include_patch']:_DIR_TO_ENGINE.'/admin/').$use_class_file ;
    if ($options['debug']) echo 'class_file='.$class_file.'<br>' ;
    return($class_file) ;
}

// получаем имя класса для страницы
function get_name_class($in_script_dir,$in_script_name,&$options=array())
{   $dir_name=ltrim($in_script_dir,'/') ; // удалеям / из начала строки
    $dir_name=str_replace(array('/','-'),'_',$dir_name) ; // заменяем остальные слеши на _
    if ($options['class_file'])
      if ($options['class_file']!='this')   { $name=str_replace('c_','',basename($options['class_file'])) ;
                                              $name=str_replace('.php','',$name) ;
                                              $options['page_class_name']='c_page_'.$name ;
                                            }
      else                                  // собираем имя класса для страницы ALL-IN-VAN
                                            { $str=hide_server_dir($_SERVER['SCRIPT_FILENAME']) ;
                                              $str=str_replace('/','_',$str) ;
                                              $str=str_replace('.php','',$str) ;
                                              $str=str_replace('.html','',$str) ;
                                              $str=str_replace('.htm','',$str) ;
                                              $options['page_class_name']='c_page'.$str ;
                                            }
    if ($options['page_class_name'])           $class_name=$options['page_class_name'] ;
    if ($options['class_name'])                $class_name=$options['class_name'] ;
    else if ($in_script_dir=='/')              $class_name='c_page_'.$in_script_name ;
    else if ($in_script_name=='index')         $class_name='c_page_'.$dir_name ;
    else                                       $class_name='c_page_'.$dir_name.'_'.$in_script_name ;
    return($class_name);

}

function check_robot($user_agent='',$debug=0)
{ global $robots,$robots_IP,$br_vers ;
  if ($debug)
  { ?><h2>Подписи роботов:</h2><?
    damp_array($robots,1,-1) ;
    ?><h2>IP роботов:</h2><?
    damp_array($robots_IP,1,-1) ;
  }
  if (!$user_agent) $user_agent=$_SERVER['HTTP_USER_AGENT'] ;
  if (_sizeof($robots)) foreach($robots as $robot_key) if (stripos($user_agent,$robot_key)!==FALSE) return(1) ;
 if (_sizeof($robots_IP)) foreach($robots_IP as $robot_IP)  if ($robot_IP==IP) return(1) ;
 if ($br_vers=='OTHER') return(2) ;
 return(0) ;
}


 // загрузка переменных из базы в сессию
 function reboot_setting_from_DB()
	{ global $debug_boot ;
	  //if (!isset($_SESSION['list_db_tables'][TM_SETTING])) return ;

      $vars=execSQL('SELECT * from '.TM_SETTING.' where clss=99 order by pkey ',array('no_fs_info'=>1,'debug'=>0)) ;

	  if (_sizeof($vars)) foreach ($vars as $rec) if ($rec['comment'])
      { $var_name=(mb_substr($rec['comment'],0,3)!='LS_')? 'LS_'.$rec["comment"]:$rec["comment"] ;
        if ($rec["enabled"]) { $source_value=(isset($GLOBALS['_SETTING']['LocalSettings'][$var_name]))? $GLOBALS['_SETTING']['LocalSettings'][$var_name]:$rec['value'] ;
                               $value=($rec['crypt'] or $var_name=='LS_AD_password')? decrypt_string($source_value):$source_value ;
                               //if ($rec['crypt']) LOGS()->reg_log('decrypt_string',$var_name.'<br>'.$source_value.'<br>'.$value.'<br>(_APP_KEY='._APP_KEY.')<br>') ;

                               $GLOBALS[$var_name]=$value ;
                               if ($GLOBALS['debug_site_setting']) echo  $var_name.'='.$rec["value"].'<br>' ;
                             }
        //else                 unset($_SESSION[$var_name])	 ;
        // 22.05.12 - в session_declare уже есть внесение в $GLOBALS значения из SESSION
        //global ${$rec["comment"]} ; ${$rec["comment"]}=$_SESSION[$rec["comment"]] ;
      }

      if ($debug_boot) echo 'загружены переменные из базы данных<br>' ;
	  set_time_point('Загрузка <strong>DB</strong> переменных ' .TM_SETTING) ;
	}

 function get_setting_from_DB_value($name)
 {   $rec=execSQL_van('SELECT * from '.TM_SETTING.' where clss=99 and comment="'.$name.'" and enabled=1') ;
     $value=($rec['crypt'])? decrypt_string($rec['value']):$rec['value'] ;
     return($value) ;
 }

 //  $mail_options - задается в /init/patch.php
 /*function boot_email_account()
 {  global $mail_options,$debug_mail_setting ;
    //echo 'Загружаем почтовые аккаунты' ;
    $_SESSION['email_accounts']=array() ;
    $_SESSION['default_email_method']=($mail_options['use_smtp'])? 'smtp':'sendmail' ;
    $_SESSION['default_email_from']=$GLOBALS['LS_email_site_noreply'] ;  // задаем имя отправителя в настройках сайта
    $_SESSION['default_email_from']=(isset($mail_options['default_account']))? $mail_options['default_account']:$GLOBALS['LS_email_site_noreply'] ; // имя отправителя - по почтовому аккаунту по умолчанию
    if (_sizeof($mail_options['accounts'])) $_SESSION['email_accounts']=$mail_options['accounts'] ; // если описаны почтовые аккаунты - сохраняем их в сесиии
    else if (isset($mail_options['from']))
    {   $email=$mail_options['from'] ;
        $_SESSION['default_email_from']=$email ;
        $_SESSION['email_accounts'][$email]['from_name']=$mail_options['from_name'] ;
        $_SESSION['email_accounts'][$email]['smtp_server']=$mail_options['smtp_server'] ;
        $_SESSION['email_accounts'][$email]['smtp_server_port']=$mail_options['smtp_server_port'] ;
        $_SESSION['email_accounts'][$email]['smtp_login']=$mail_options['smtp_login'] ;
        $_SESSION['email_accounts'][$email]['smtp_password']=$mail_options['smtp_password'] ;
    }
    if ($debug_mail_setting)
    {   ?>
         <h2>Информация по настройке почты</h2>
            <table class=debug>
                <tr><td>Отправитель, заданный через настройки сайта</td><td>$GLOBALS['LS_email_site_noreply']</td><td><?echo $GLOBALS['LS_email_site_noreply']?></td></tr>
                <tr><td>Описание почтовых аккаунтов в patch.php</td><td>$mail_options</td><td><?damp_array($GLOBALS['mail_options'],1,-1)?></td></tr>
                <tr><td>Отправитель по умолчанию в сессии</td><td>$_SESSION['default_email_from']</td><td><?echo $_SESSION['default_email_from']?></td></tr>
                <tr><td>Метод отправки по умолчанию в сессии</td><td>$_SESSION['default_email_method']</td><td><?echo $_SESSION['default_email_method']?></td></tr>
                <tr><td>Почтовые аккаунты в сессии</td><td>$_SESSION['email_accounts']</td><td><?damp_array($_SESSION['email_accounts'],1,-1)?></td></tr>
            </table>
       <?
    }
 } */


function boot_index_list()
{ global $debug_boot ;
  if (!isset($_SESSION['list_db_tables'][TM_LIST])) return ;
  $recs=execSQL('select * from obj_site_list where clss=21 and enabled=1') ;
  $_SESSION['index_list_names']=array() ;
  if (_sizeof($recs)) foreach($recs as $rec) $_SESSION['index_list_names'][$rec['pkey']]=get_IL_array_name($rec);
  if ($debug_boot) echo 'Загружено оглавление списков<br>' ;
}

function boot_roles()
{ global $debug_boot ;
  if (!isset($_SESSION['list_db_tables']['roles'])) return ;
  $recs=execSQL('select * from roles order by id',['debug'=>0,'indx'=>'id']) ;
  $_SESSION['ARR_roll']=array() ;
  if (_sizeof($recs)) foreach($recs as $rec) $_SESSION['ARR_roll'][$rec['id']]=$rec;
  if ($debug_boot) echo 'Загружены роли<br>' ;
}


function get_IL_array_name($rec)
{  if ($rec['arr_name'])       $key=safe_file_names($rec['arr_name']) ;
   //else if ($rec['obj_name'])  $key=safe_file_names($rec['obj_name']) ;
   else                        $key=$rec['pkey'] ;
   $key='IL_'.$key ;
   return($key) ;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// создания подсистем сайта
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


function create_static_subsystems($options=array())
{ global $__functions,$debug_modul,$debug_boot ;
  $_SESSION['list_created_sybsystems']=array() ;  //echo 'Массив очищен<br>' ;
  if ($debug_modul) echo '<strong>'.create_static_subsystems.'</strong><br>' ;
  //damp_array($__functions,1,-1);

  if ($debug_modul or $debug_boot) echo 'Создаем <div class="blau bold">СТАТИЧЕСКИЕ ПОДСИСТЕМЫ</div><br>' ;

    // подключаем все дополнительные модули, идущие в составе движка (находятся в /engine/moduls/)
    //damp_array($GLOBALS['_SETTING'],1,-1) ;
    if (_sizeof($GLOBALS['_SETTING']['modules'])) foreach($GLOBALS['_SETTING']['modules'] as $modul_name=>$enabled) if ($enabled) create_system_modul_obj($modul_name) ;
    if (_sizeof($GLOBALS['_SETTING']['modules_local'])) foreach($GLOBALS['_SETTING']['modules_local'] as $modul_name=>$enabled) if ($enabled) create_system_modul_obj($modul_name) ;


}
// функция создания статитческих подсистем
// как правило вызывается из модуля function _xxx_site_boot($options)
// при создании статической подсистемы по умолчанию используются следующий правила:
// - имя подсистемы = $system_kod.'_system'
// - название класса объекта подсистемы = c_'.$system_kod.'_system' ;
// - корневая директория подсистемы = $system_kod

function create_system_modul_obj($system_kod,$options=array())
{  global $debug_modul,$debug_boot ;
   // определяем режим отладки
   if ($debug_boot or $debug_modul or $options['debug'] or $_SESSION['init_options'][$system_kod]['debug'])  $debug=1 ;

   $system_name=$system_kod.'_system' ;
   if ($debug) echo '<br><div class="blue bold">Создание подсистемы <strong>'.$system_name.'</strong> через create_system_modul_obj</div>' ;
   if (in_array($system_name,$_SESSION['list_created_sybsystems'])) { if ($debug) echo '<div class=red>Подсистема <strong>'.$system_name.'</strong> уже создана</div>' ; return ; }
   // создаем подсистему
   create_system_site($system_kod,$options) ;
}


// создание подсистемы сайта
// передаем:
// $system_kod			-	имя подсистемы, goods
// $class_name			-	класс, на основе котого будет создаваться подсистема, c_goods_system
//							если имя класса не указано, будет использован класс c_system
// $options				- 	дополнительные параметры для создания подсистемы

function create_system_site($system_kod,$options=array())
{ global $debug_modul,$debug_boot ;
  $system_name=$system_kod.'_system' ;
  // определяемся с классом подсистемы
  //if ($options['class_name'])
  //{ // для динамической подисистемы класс должен задан в БД и передан переда через options
  //  $class_name=(class_exists($options['class_name']))? $options['class_name']:'c_system' ;  // проверяем наличие локального класса
  //}
  //else
  { // для статических подсистем класс опередаляется по коду подсистемы
    $system_class_name=(class_exists('c_'.$system_kod.'_system'))? 'c_'.$system_kod.'_system':'c_system' ; // если класс подсистемы не определен, берем базовый класс подсистемы
    $class_name=(class_exists($system_class_name.'_site'))? $system_class_name.'_site':$system_class_name ;  // проверяем наличие локального класса
  }

  if (!is_array($_SESSION['init_options'][$system_kod])) $_SESSION['init_options'][$system_kod]=array() ; // если опций нет, создаем пустой массив опций

  // определяем режим отладки
  $debug=0 ;
  if ($debug_boot or $debug_modul or $options['debug'] or $_SESSION['init_options'][$system_kod]['debug'])  $debug=max($debug_boot,$debug_modul,$options['debug'],$_SESSION['init_options'][$system_kod]['debug']) ;
  //echo 'debug='.$debug.'<br>';

  if ($debug)
  { echo '<h2>'.$system_kod.'</h2>' ;
  	echo 'Название подсистемы: <span class=green>'.$system_name.'</span><br>';
  	echo 'Класс подсистемы: <span class=green>'.$class_name.'</span><br>' ;
	echo 'Переданные параметры через options (из _'.$system_kod.'_site_boot() / БД):' ; print_r($options) ; echo '<br>';
    echo '<strong>init_options['.$system_kod.']</strong> - всего '._sizeof($_SESSION['init_options'][$system_kod]).' параметров<br>' ;
    if ($debug==2 and _sizeof($_SESSION['init_options'][$system_kod])) {  damp_array($_SESSION['init_options'][$system_kod],1,0) ; }
    $options['debug']=$debug  ;
  }

  // проверка на существование класса подсистемы -  в принципе, невожная ситуация, т.к.ранее проверятеся существование указанного класса
  if (!class_exists($class_name)) {echo '<div class=alert>Указан несуществующий класс: :'.$class_name.'</div>' ; return ;}

  // суммируем option и $_SESSION['init_options']
  $res_options=array_merge($options,$_SESSION['init_options'][$system_kod]) ;
  $res_options['system_kod']=$system_kod ;
  $res_options['system_name']=$system_name ;
  //if ($debug==2) {	echo '<strong>res_options['.$system_kod.']</strong>=' ; damp_array($res_options,1,0) ; echo '<br>' ; }

  if ($res_options['no_create_new_on_reboot'] and is_object($_SESSION[$system_name])) { if ($debug) echo '<div class=info>Пересоздание данного гласса при reboot не труебуется.</div>' ; return ;}

  // создаем объект подсистемы, при этом будет отработан констуктов класса, которому переданы все  опции подсистемы
  $_SESSION[$system_name]=new $class_name($res_options) ;
  $GLOBALS[$system_name]=&$_SESSION[$system_name] ;

  // сохраняем имя созданной подсистемы в глобальном списке
  if ($_SESSION[$system_name]->tkey) $_SESSION['list_created_sybsystems'][$_SESSION[$system_name]->tkey]=$system_name ; //damp_array($list_created_sybsystems) ;
  else                               $_SESSION['list_created_sybsystems'][$system_name]=$system_name ; //damp_array($list_created_sybsystems) ;

  if ($debug) { echo '<strong>'.$system_name.'</strong> - система успешно создана и проиницилизирована<br>' ;
  				//damp_array($_SESSION[$system_name]) ;
  			  }

}


 // ---------------------------------------------------------------------------------------------------------------------------------
 // модель классов
 // ---------------------------------------------------------------------------------------------------------------------------------

 function create_class_model($debug_mode=0)
  { global $debug_boot ;
   // $debug_mode=0 ;
   //   $debug_boot=0 ;
    $debug_mode2=($debug_mode==2)? 1:0;
    if ($debug_boot) echo '<strong>Создаем модель классов</strong><br>' ;

    unset($_SESSION['class_system']) ;
    $_SESSION['class_system'] = new c_system() ;

    if (_sizeof($_SESSION['class_system']->tree)) foreach ($_SESSION['class_system']->tree as $i=>$rec) if (isset($_SESSION['class_system']->tree[$i])) unset($_SESSION['class_system']->tree[$i]) ;
    $_SESSION['class_system']->tree=array() ;

   // создаем дерево классов
   if (_sizeof($_SESSION['descr_clss'])) foreach($_SESSION['descr_clss'] as $clss=>$clss_info) $_SESSION['class_system']->tree[$clss] = new c_obj_clss($clss,$clss_info['parent'],$clss_info['name'],$_SESSION['class_system'],$debug_mode2) ;
   $arr_ini_clss=SETUP()->load_ini_setting('/ini/clss.yaml') ;
   if (_sizeof($arr_ini_clss)) foreach($arr_ini_clss as $clss=>$clss_info)
   {   // временно пока оставляем так, так как в дереве храниться только структура классов, а все описание (поля, индексы) - в сесиии $_SESSION['descr_clss']
       $_SESSION['descr_clss'][$clss]=$clss_info ;
       $_SESSION['class_system']->tree[$clss] = new c_obj_clss($clss,$clss_info['parent'],$clss_info['name'],$_SESSION['class_system'],$debug_mode2) ;
   }

   if ($debug_mode) echo 'Созданы объекты классов на основе описаний в сессии, count='._sizeof($_SESSION['descr_clss']).' - <span class="green">OK</span><br>' ;
   if ($debug_mode) echo 'Созданы объекты классов на основе описаний в clss.yaml, count='._sizeof($arr_ini_clss).' - <span class="green">OK</span><br>' ;

   $_SESSION['class_system']->tree['root']=&$_SESSION['class_system']->tree[0] ;

    if (_sizeof($_SESSION['class_system']->tree)) foreach ($_SESSION['class_system']->tree as $obj)
    { if (isset($_SESSION['class_system']->tree[$obj->parent]))
        {  if ($obj->clss)
           { if ($debug_mode2) echo "Добавляем (".$obj->clss.")".$obj->name." к (".$obj->parent.")".$_SESSION['class_system']->tree[$obj->parent]->name."<br>" ;
             $_SESSION['class_system']->tree[$obj->parent]->add_child($obj->clss) ;
           }
        } else if ($obj->parent>0) {  if ($obj->clss>0) $_SESSION['class_system']->tree['root']->add_child($obj->clss) ; // если parent не существует, цепляем к вершине
        							  $obj->parent=0 ;
        				              if ($debug_mode2) echo 'Используем '.$_SESSION['class_system']->tree['root']->name." для (".$obj->clss.")".$obj->name." (Не найдкн clss=".$obj->parent.")<br>" ;
        						   }
    }

   //damp_array($_SESSION['class_system']) ;
    $_SESSION['class_system']->tree['root']->update_child_level() ;
    //if ($debug_mode) echo '<strong>Копируем поля потомкам</strong><br>' ;
    //$_SESSION['class_system']->tree['root']->copy_fields_to_child() ;  // теперь добавляем к потомкам родительские списки полей
    if ($debug_mode) echo 'Создана модель классов - <span class="green">OK</span><br>' ;
    set_time_point('Создана модель <strong>классов</strong>') ;
    //damp_array($_SESSION['class_system']) ;
  }

/* МОДЕЛЬ ОБЪЕКТНЫХ ТАБЛ�?Ц ----------------------------------------------------------------------------------------------------------------------------------------------*/

 // создаем модель объектных таблиц на основе всех таблиц или определенной группы
 // no_check - не производить DOT проверку таблиц
 // no_connect - не загружать связи между таблицами
 // no_use_clss - не загружать информацию по поддерживаемым классам
 // no_clone_img - не загружать информацию по клонам изображений
 // no_edit_inf - не загружать информацию по настройкам редактирования полей
 // use_tkey_table	- модель создаетсяя/обновляется только для указанной таблицы
 // no_describe_tables - не загружать структуру таблиц

 function create_model_obj_tables($options=array())
  { global $debug_boot;
    //if (!isset($_SESSION['list_db_tables']['obj_descr_obj_tables'])) return ;
    if ($debug_boot or $options['debug']) echo "<div class='green bold'>Создаем модель объектных таблиц</div>" ;
    // очищаем массив от старых объектов
    // заремировано, т.к. при указании кода конктетной таблицы не происходит выборка непрямых дочерних объектов
    //if (!$options['use_tkey_table'])
      { if (is_array($_SESSION['descr_obj_tables']) and _sizeof($_SESSION['descr_obj_tables'])) foreach ($_SESSION['descr_obj_tables'] as $i=>$rec) if (isset($_SESSION['descr_obj_tables'][$i])) unset($_SESSION['descr_obj_tables'][$i]) ;
        $add_usl='' ;
      }


    $mas_obj=execSQL('select * from obj_descr_obj_tables'.$add_usl.' order by pkey') ;
    if (!_sizeof($mas_obj)) { echo 'Не найдено ни одной таблицы для создания модели' ; damp_array($options) ; _exit() ; }
    $mas_obj_clss=group_by_field('clss',$mas_obj) ;
    //damp_array($mas_obj_clss) ;

    $_SESSION['list_db_tables']=array() ;    // эти массивы пока дублируют друг друга в дальнейшем надо оставить тока один
    $_SESSION['pkey_by_table']=array() ;
    $_SESSION['tables']=array() ;           // этот массив дублирует _DOT(...)->table_name

    // пока просто создаем объекты но без создания у каждого списка потомков
    if (_sizeof($mas_obj_clss[101])) foreach ($mas_obj_clss[101] as $rec)
    {  $_SESSION['descr_obj_tables'][$rec['pkey']] = new c_obj_table($rec,'descr_obj_tables') ;
       $_SESSION['list_db_tables'][$rec['table_name']]=$rec['pkey'] ;
       $_SESSION['pkey_by_table'][$rec['table_name']]=$rec['pkey'] ;
       $_SESSION['tables'][$rec['pkey']]=$rec['table_name'] ;
    }

    if (_sizeof($mas_obj_clss[108])) foreach ($mas_obj_clss[108] as $rec)
    {  $_SESSION['descr_obj_tables'][$rec['pkey']] = new c_obj_table($rec,'descr_obj_tables') ;
       $_SESSION['list_db_tables'][$rec['table_name']]=$rec['pkey'] ;
       $_SESSION['pkey_by_table'][$rec['table_name']]=$rec['pkey'] ;
       $_SESSION['tables'][$rec['pkey']]=$rec['table_name'] ;
    }

    // 05.09.2010 заполняем свойство list_OUT. В приниципе, этот список означает только список дочерних таблиц.
    // он по сути, дублирует свойтсво list_clss_ext.
   if (_sizeof($_SESSION['descr_obj_tables'])) foreach ($_SESSION['descr_obj_tables'] as $rec)
    { if (isset($_SESSION['descr_obj_tables'][$rec->parent]))
       { // ДОРАБОТАТЬ: свойства list_obj и list_OUT дублируют друг друга, оставить только одно
         $_SESSION['descr_obj_tables'][$rec->parent]->list_OUT[$rec->pkey]=$rec->table_name ;
         $_SESSION['descr_obj_tables'][$rec->parent]->list_obj[]=$rec->pkey ;
         $_SESSION['descr_obj_tables'][$rec->pkey]->mode='out' ;
       }
    }

   if (!$options['no_use_clss'])  upload_use_clss_info_from_arr($options['use_tkey_table'],$mas_obj_clss[104],$mas_obj_clss[105]) ;		// загружаем инфу по классам таблицы

   $list_procedures=-1 ; $list_triggers=-1 ;
   //if (_DB_ALLOW_PROCEDURE)$list_procedures=execSQL('SHOW PROCEDURE status',array('indx'=>'Name','debug'=>0)) ;
   //if (!_sizeof($list_procedures)) $list_procedures=-1 ; // если далее передать пустой массив, то будет сделан повторный запрос к базе на наличие процедур

   //if (_DB_ALLOW_TRIGGERS) $list_triggers=execSQL('SHOW TRIGGERS',array('indx'=>'Trigger','debug'=>0)) ;
   //if (!_sizeof($list_triggers)) $list_triggers=-1 ; // если далее передать пустой массив, то будет сделан повторный запрос к базе на наличие процедур


   //$table_info=execSQL('SHOW CREATE DATABASE',2) ;

   //$table_info=execSQL('DESCRIBE obj_site_banners',2) ;

   //damp_array($options) ;
   if (!$options['no_describe_tables'])
   { if (!$options['use_tkey_table'])
     { if ($debug_boot or $options['debug']) echo "<div class='green bold'>- получаем описания таблиц БД</div>" ;
       //if(_sizeof($_SESSION['descr_obj_tables'])) foreach ($_SESSION['descr_obj_tables'] as $rec) if ($rec->table_name) upload_descr_table($rec->pkey,$list_procedures,$list_triggers) ;
	 }
	 //else upload_descr_table($options['use_tkey_table'],$list_procedures,$list_triggers) ;
   }

   if ($debug_boot or $options['debug']) echo "<div class='black'>создание модели объектных таблиц закончено</div>" ;
   set_time_point('Создана модель <strong>объектных таблиц</strong>') ;
  }



 // загружает описание таблицы в модель
 function upload_descr_table($tkey,$list_proc=array(),$list_trig=array())
 { global $no_upload_table_by_code ;
   $rec=$_SESSION['descr_obj_tables'][$tkey] ;
   if (!isset($no_upload_table_by_code) or strpos($rec->table_name,$no_upload_table_by_code)===false) $fields_info=execSQL("DESCRIBE ".$rec->table_name);
   if (_sizeof($fields_info)) foreach($fields_info as $fname=>$finfo) $_SESSION['descr_obj_tables'][$rec->pkey]->field_info[$fname]=$finfo['Type'];
   if (_DB_ALLOW_PROCEDURE)
   { if (is_array($list_proc) and !_sizeof($list_proc)) $list_proc=execSQL('SHOW PROCEDURE status like "'.$rec->table_name.'__%"',array('indx'=>'Name','debug'=>0)) ;
   if (is_array($list_proc)) foreach($list_proc as $name=>$info) if (strpos($name,$rec->table_name.'__')!==false) $_SESSION['descr_obj_tables'][$rec->pkey]->proc_info[str_replace($rec->table_name.'__','',$name)]=$info ;
   }
   if (_DB_ALLOW_TRIGGERS)
   { if (is_array($list_trig) and !_sizeof($list_trig)) $list_trig=execSQL('SHOW TRIGGERS like "'.$rec->table_name.'__%"',array('indx'=>'Trigger','debug'=>0)) ;
   if (is_array($list_trig)) foreach($list_trig as $name=>$info) if (strpos($name,$rec->table_name.'__')!==false) $_SESSION['descr_obj_tables'][$rec->pkey]->triggers[str_replace($rec->table_name.'__','',$name)]=$info ;
   }

 }

  // обновляем информацию в модели таблиц по поддерживаемым объектах объектных таблиц по реальным данным в таблицах
  // классы прописываются только для таблиц, в которых они будут храниться
  // уже дожны быть:
  // - определены в модели режимы MODE таблиц 05/09/2010 - отмена
  // 05.09.2010 в связи с изменениями в параметре МОDE упрощен алгоритм заполения массиво list_clss и list_clss_ext
  // ДОРАБОТАТЬ: т.к. эта функция используется только в двух вызовах m_setup_admin то необходимо переделать те вызовы на
  // upload_use_clss_info_from_arr, а саму эту функцию списать

  function upload_use_clss_info($use_tkey=0)
  { global $debug_boot ;
    if ($debug_boot) echo "upload_use_clss_info <br>" ;

    if ($use_tkey)
    { // получить надо не только свои поддерживаемые классы но и дочерних OUT таблиц
      if (_sizeof($_SESSION['descr_obj_tables'][$use_tkey]->list_OUT)) $arr_OUT=array_keys($_SESSION['descr_obj_tables'][$use_tkey]->list_OUT) ;
      $str=$use_tkey ;
      if (_sizeof($arr_OUT)) $str.=','.implode(',',$arr_OUT) ;
      $usl_tkey=' and t.parent in ('.$str.') ' ;

    } else $usl_tkey='' ;

    // чистим старый данные
    if (!$use_tkey and _sizeof($_SESSION['descr_obj_tables'])) foreach ($_SESSION['descr_obj_tables'] as $tkey=>$tinfo)
       {  unset($_SESSION['descr_obj_tables'][$tkey]->list_clss) ;
          unset($_SESSION['descr_obj_tables'][$tkey]->list_clss_ext) ;
       }
       else { unset($_SESSION['descr_obj_tables'][$use_tkey]->list_clss) ;
       		  unset($_SESSION['descr_obj_tables'][$use_tkey]->list_clss_ext) ;
       		}

    $list_used_class=execSQL('select t.pkey,t.parent,t.indx,t.obj_name,t.enabled,table_name from obj_descr_obj_tables t where t.clss=104  '.$usl_tkey.' order by t.parent,t.indx',0,1) ;
    $_list_multilang_fields=execSQL('select pkey,parent,obj_name,indx from obj_descr_obj_tables where clss=105 and enabled=1 order by parent') ;
    $list_multilang_fields=group_by_field('parent',$_list_multilang_fields) ;
    //damp_array($list_multilang_fields) ;

    // $list - список всеъ поддерживаемых классов у всех таблиц
    if (_sizeof($list_used_class)) foreach($list_used_class as $rec)
    { $clss=$rec['indx'] ;    // код класса
      $tkey=$rec['parent'] ;  // код таблицы
      $parent_tkey=$_SESSION['descr_obj_tables'][$tkey]->parent ;// для EXT и OUT код родителькой таблицы

      //$mode=($rec['obj_name'])? $rec['obj_name']:'main';
      //$tkey_ext=$rec['enabled'] ;

      if (isset($_SESSION['descr_obj_tables'][$tkey]))
       { $_SESSION['descr_obj_tables'][$tkey]->list_clss[$clss]=$tkey ;
         $_SESSION['descr_obj_tables'][$tkey]->list_clss_ext[$clss]['main']=$tkey ;
         if ($_SESSION['descr_obj_tables'][$tkey]->mode=='out')
         { $_SESSION['descr_obj_tables'][$parent_tkey]->list_clss[$clss]=$tkey ;
           $_SESSION['descr_obj_tables'][$parent_tkey]->list_clss_ext[$clss]['out']=$tkey ;
         }

         if ($_SESSION['descr_obj_tables'][$tkey]->clss==106) $_SESSION['descr_obj_tables'][$tkey]->indx_clss=$clss ;
         if ($_SESSION['descr_obj_tables'][$tkey]->clss==108) $_SESSION['descr_obj_tables'][$tkey]->jur_clss=$clss ;

         if ($rec['table_name']) $_SESSION['descr_obj_tables'][$tkey]->list_clss_ext[$clss]['file']=$rec['table_name'] ;

         // сохраняем информацию по мультиязчности
         if (_sizeof($list_multilang_fields[$rec['pkey']])) foreach($list_multilang_fields[$rec['pkey']] as $rec_ml)
           { $_SESSION['descr_obj_tables'][$tkey]->list_clss_ext[$clss]['multilang'][$rec_ml['obj_name']]=$rec_ml['indx'] ;
             //echo 'list_clss_ext['.$clss.'][multilang]['.$rec_ml['obj_name'].']='.$rec_ml['indx'].'<br>' ;
           }
         //echo '123' ;

       }  //else echo 'Не найден parent '.$tkey.'<br>' ;

    }
   //set_time_point('upload_use_clss_info - OK') ;
  }

  // специальная версия для быстрой загрузки классов из массивов без дополнительных запросов к БД
  function upload_use_clss_info_from_arr($use_tkey,$list_used_class,$_list_multilang_fields)
  { global $debug_boot ;
    if ($debug_boot) echo "<div class='green bold'>- загружаем список поддерживаемых классов в экземпляры таблиц</div>" ;


    // чистим старый данные
    if ($use_tkey)
    { unset($_SESSION['descr_obj_tables'][$use_tkey]->list_clss) ;
      unset($_SESSION['descr_obj_tables'][$use_tkey]->list_clss_ext) ;
    }
    else if (_sizeof($_SESSION['descr_obj_tables'])) foreach ($_SESSION['descr_obj_tables'] as $tkey=>$tinfo)
       {  unset($_SESSION['descr_obj_tables'][$tkey]->list_clss) ;
          unset($_SESSION['descr_obj_tables'][$tkey]->list_clss_ext) ;
       }

    $list_multilang_fields=group_by_field('parent',$_list_multilang_fields) ;
    //damp_array($list_multilang_fields) ;

    // $list - список всеъ поддерживаемых классов у всех таблиц
    if (_sizeof($list_used_class)) foreach($list_used_class as $rec)
    { $clss=$rec['indx'] ;    // код класса
      $tkey=$rec['parent'] ;  // код таблицы
      $parent_tkey=$_SESSION['descr_obj_tables'][$tkey]->parent ;// для EXT и OUT код родителькой таблицы

      //$mode=($rec['obj_name'])? $rec['obj_name']:'main';
      //$tkey_ext=$rec['enabled'] ;

      if (isset($_SESSION['descr_obj_tables'][$tkey]))
       { $_SESSION['descr_obj_tables'][$tkey]->list_clss[$clss]=$tkey ;
         $_SESSION['descr_obj_tables'][$tkey]->list_clss_ext[$clss]['main']=$tkey ;
         if ($_SESSION['descr_obj_tables'][$tkey]->mode=='out')
         { $_SESSION['descr_obj_tables'][$parent_tkey]->list_clss[$clss]=$tkey ;
           $_SESSION['descr_obj_tables'][$parent_tkey]->list_clss_ext[$clss]['out']=$tkey ;
         }

         if ($_SESSION['descr_obj_tables'][$tkey]->clss==106) $_SESSION['descr_obj_tables'][$tkey]->indx_clss=$clss ;
         if ($_SESSION['descr_obj_tables'][$tkey]->clss==108) $_SESSION['descr_obj_tables'][$tkey]->jur_clss=$clss ;

         if ($rec['table_name']) $_SESSION['descr_obj_tables'][$tkey]->list_clss_ext[$clss]['file']=$rec['table_name'] ;

         // сохраняем информацию по мультиязчности
         //if (_sizeof($list_multilang_fields[$rec['pkey']])) foreach($list_multilang_fields[$rec['pkey']] as $rec_ml)
         //  { $_SESSION['descr_obj_tables'][$tkey]->list_clss_ext[$clss]['multilang'][$rec_ml['obj_name']]=$rec_ml['indx'] ;
         //    //echo 'list_clss_ext['.$clss.'][multilang]['.$rec_ml['obj_name'].']='.$rec_ml['indx'].'<br>' ;
         //  }

       }  //else echo 'Не найден parent '.$tkey.'<br>' ;

    }
   //set_time_point('upload_use_clss_info - OK') ;
  }

//*************************************************************************************************************************************/
//
// фукции-утилиты
//
//*************************************************************************************************************************************/

 //
 function _exit_404()
 { header("HTTP/1.1 404 Not found");
   ?><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD><BODY><H1>Not Found</H1>
   The requested URL <?echo $_SERVER['REQUEST_URI']?> was not found on this server.<P>
   <HR>
   <ADDRESS><?echo $_SERVER['SCRIPT_NAME']?> Server at <?echo $_SERVER['HTTP_HOST']?> Port 80</ADDRESS>
   </BODY></HTML><?
   _exit();
 }

 function redirect_JS_to($to_url)
 {
    ?><script type="text/javascript">document.location="<?echo $to_url?>"</script><?
 }

 function redirect_301_to($to_url,$no_used_cur_domain=0)
 {   global $debug_page_relocation ;
     $arr=parse_url($to_url) ;
     if (!$no_used_cur_domain and !$arr['host']) $arr['host']=_CUR_DOMAIN ;
     //damp_array($arr) ;
     $arr['path']=str_replace('//','/',$arr['path']) ;
     if ($arr['scheme']) $arr['scheme'].='://' ;
     else                $arr['scheme']=_CUR_SHEME ;
     $to_url=$arr['scheme'].$arr['host'].$arr['path'] ;


     $from_url=_MAIN_PROTOCOL._CUR_DOMAIN._CUR_PAGE_DIR._CUR_PAGE_NAME;
     if ($to_url==$from_url) return ;


     //$SEO_info=execSQL_van('select pkey,url,title,description,keywords from '.TM_SITEMAP.' where enabled=1 and url="'.addslashes(_CUR_PAGE()->SEO_url).'"') ;

     if ($debug_page_relocation)
     {  trace() ;
        global $SF_REQUEST_URI ;
        echo 'base_domain='._BASE_DOMAIN.'<br>_MAIN_DOMAIN='._MAIN_DOMAIN.'<br>_CUR_DOMAIN='._CUR_DOMAIN.'<br>SF_REQUEST_URI='.$SF_REQUEST_URI.'<br>_CUR_PAGE_PATH='._CUR_PAGE_PATH.'<br>' ;
        echo 'seo_info:' ;
        //damp_array($SEO_info,1,-1) ;
        if ($to_url)
        { echo 'Relocation from   page: '.$from_url.'<br>' ;
          echo 'Relocation to cur page: '.$to_url.'<br>header("HTTP/1.1 301 Moved Permanently")<br>header("Location: '.$to_url.'")'; _exit() ;
        }
        else echo 'No relocation for this page<br>' ;
     }

     //sif ($SEO_info['pkey']) execSQL_update('update '.TM_SITEMAP.' set status=301 where pkey='.$SEO_info['pkey']) ;

     header("HTTP/1.1 301 Moved Permanently");
     header("Location: ".$to_url);
     _exit() ;
 }


 function capcha_code_checkit($_check_code='')
  {  if ($_SESSION['member']->id) return(true) ;
     if (!$_check_code and $_POST['_check_code']) $_check_code=$_POST['_check_code'] ;
     if (!$_check_code and $_GET['_check_code'])  $_check_code=$_GET['_check_code'] ;
     if (!$_check_code and $_POST['captcha'])     $_check_code=$_POST['captcha'] ;     // mootools form submit
     if (!$_check_code and $_GET['captcha'])      $_check_code=$_GET['captcha'] ;     // mootools form submit
     //echo '$_check_code='.$_check_code.'<br>$check_code_number='.$_SESSION['check_code_number'].'<br>' ;
     if ($_SESSION['check_code_number']!='' and $_SESSION['check_code_number']==$_check_code)
     { $_SESSION['check_code_number']='' ; // сбрасываем проверочный код
       return (true) ;
     }
     return(false) ;
  }

 function unset_check_code()
 { global $check_code_number,$_check_code ;
   $check_code_number=rand() ;
   $_check_code=$check_code_number ;
 }

 // ставим для системых переменных СЕССИИ значения по умолчнаю - вызывается только при перезагрузке сесиии
 function init_system_vars()
 {  $_SESSION['list_mon_names']                 =array('1'=>'Январь','2'=>'Февраль','3'=>'Март','4'=>'Апрель','5'=>'Май','6'=>'Июнь','7'=>'Июль','8'=>'Август','9'=>'Сентябрь','10'=>'Октябрь','11'=>'Ноябрь','12'=>'Декабрь') ;
    $_SESSION['list_mon_short_names']           =array('1'=>'января','2'=>'февраля','3'=>'марта','4'=>'апреля','5'=>'мая','6'=>'июня','7'=>'июля','8'=>'августа','9'=>'сентября','10'=>'октября','11'=>'ноября','12'=>'декабря') ;
    $_SESSION['list_wday_names']                =array('0'=>'Воскресенье','1'=>'Понедельник','2'=>'Вторник','3'=>'Среда','4'=>'Четверг','5'=>'Пятница','6'=>'Суббота','7'=>'Воскресение') ;
    $_SESSION['list_wday_short_names']          =array('0'=>'Вc.','1'=>'Пн.','2'=>'Вт.','3'=>'Ср.','4'=>'Чт.','5'=>'Пт.','6'=>'Сб.','7'=>'Вc.') ;

    $_SESSION['descr_obj_tables']               =array() ;
    $_SESSION['descr_tables']                   =array() ;
    $_SESSION['pkey_by_table']                  =array() ;
    $_SESSION['tables']                         =array() ;
    $_SESSION['list_db_tables']                 =array() ;
    $_SESSION['descr_clss']                     =array() ;

    $_SESSION['_flags']=array() ; // сбрасываем все флаги

    // сдедующие массивы используются только в админке, но перегружаются всегда так как их объявление может совмещено с объявлением переменных сайта
    $_SESSION['menu_admin']=array() ;
    $_SESSION['menu_admin_site']=array() ;
    $_SESSION['menu_admin_top']=array() ;
    $_SESSION['arr_filter']=array() ;
    $_SESSION['arr_find_on_field']=array() ;  // перенести в модель
    $_SESSION['table_order']=array() ; // сортировка в таблицам по классам - перенести в модель
 }

function session_declare($name,$value) { $_SESSION[$name]=$value ; $GLOBALS[$name]=&$_SESSION[$name] ; }


// преобразование имен параметров для поддержки старых версий
function compatible_options_names(&$options=array())
{ // сделано в целях унификации и упрощения параметров создания страницы
  if ($options['use_class_file'] and !$options['class_file']) $options['class_file']=$options['use_class_file'] ;
  if ($options['script_file'] and !$options['class_file']) $options['class_file']=$options['script_file'] ;
  if ($options['used_system'] and !$options['system']) $options['system']=$options['used_system'] ;
  if ($options['used_modul'] and !$options['modul']) $options['modul']=$options['used_modul'] ;
  if ($options['use_class'] and !$options['page_class_name']) $options['page_class_name']=$options['use_class'] ;
  // далее исползуется для AJAX - если название команды передано совместо с именем расширения - вписываем расшмирение как параметр POST
  if ($_POST['cmd']) {$arr=explode('/',$_POST['cmd']) ; if (_sizeof($arr)==2) {$_POST['ext']=$arr[0] ; $_POST['cmd']=$arr[1] ; } }
  if ($_POST['ext']) $options['ext']=$_POST['ext'] ;
  if ($_POST['script'])
  {  $arr=explode('/',$_POST['script']) ;
     if ($arr[0]=='mod') { $options['modul_ext']=$arr[1] ; }
     if ($arr[0]=='ext' and !$arr[2]) { $options['admin_ext']=$arr[1] ; }
  }

  $GLOBALS['member']=&$_SESSION['member'] ;
  $GLOBALS['menu_admin_site']=&$_SESSION['menu_admin_site'] ;
  $GLOBALS['descr_clss']=&$_SESSION['descr_clss'] ;
  $GLOBALS['descr_tables']=&$_SESSION['descr_tables'] ;
  $GLOBALS['menu_admin_site']=&$_SESSION['menu_admin_site'] ;
  // временная компенсация отмены regsiter_globals в 5.4
  if (_sizeof($_SESSION)) foreach($_SESSION as $name=>$value) if (!isset($GLOBALS[$name])) $GLOBALS[$name]=&$_SESSION[$name] ;
}



 // ---------------------------------------------------------------------------------------------------------------------------------
 // функция подключения скриптом для создания объекта класса
 // ---------------------------------------------------------------------------------------------------------------------------------

 // функция создания обекта clss
 // объект будет создан на основе класса clss_xxx
 // если класс clss_xxx не опроеделен, будет использован первый определенный класс предков
 function CLSS($clss,$finfo=array()) {return(_CLSS($clss,$finfo));}

 function _CLSS($clss)
 { if (!isset($_SESSION['class_system']->tree[$clss])) { $clss=0 ; /*echo $clss.' not found, use сlss 0<br>' ; */}
   if (!isset($_SESSION['class_system']->tree[$clss])) return(null);

   if (is_object($GLOBALS['obj_clss_'.$clss])) return($GLOBALS['obj_clss_'.$clss]) ;
   include_class($clss,['debug'=>0]) ;
   $mas_parent=$_SESSION['class_system']->tree[$clss]->get_list_parent_clss() ;
   $mas_parent=array_reverse($mas_parent) ;
   foreach($mas_parent as $parent_clss)
   { $clss_class_name='clss_'.$parent_clss ; // название класса, на основе которого будет создаваться наш класс
     // ищем первый объявленный родительский класс
     if (class_exists($clss_class_name,false)) { $GLOBALS['obj_clss_'.$clss]=new $clss_class_name($clss) ; break ; }
   }
   return($GLOBALS['obj_clss_'.$clss]) ;
 }

 // внимание!!! в каждом файле /class/clss_xxx.php должен быть include_once('clss_YYY.php') ; - на родительский класс
 function include_class($clss,$options=array())
 {  //trace() ;
    if ($options['debug']) echo 'include class '.$clss.'<br>' ;
    if (isset($_SESSION['class_system']->tree[$clss])) $arr_clss=$_SESSION['class_system']->tree[$clss]->get_list_parent_clss() ;
    else                                   $arr_clss[]=$clss ;
    $arr_clss=array_reverse($arr_clss) ;
    if ($options['debug']) damp_array($arr_clss,1,-1);

    if (_sizeof($arr_clss)) foreach($arr_clss as $use_clss)  if (file_exists(_DIR_TO_CLSS.'/clss_'.$use_clss.'.php'))
    { include_once(_DIR_TO_CLSS.'/clss_'.$use_clss.'.php') ;
      if ($options['debug']) echo 'Подключен /clss_'.$use_clss.'.php<br>' ;
      //trace() ;
      return (1) ;
    }
    return('') ;
 }

 // ---------------------------------------------------------------------------------------------------------------------------------
 // функция подключения скриптов для для выполнения функций
 // ---------------------------------------------------------------------------------------------------------------------------------

 function include_extension($name,$options=array())
 {  $GLOBALS['debug_frame_viewer']=1 ;
    if ($GLOBALS['debug_frame_viewer']) echo 'Подключаем расширение "'.$name.'"' ;
    //$name=basename($name) ;
    if (strpos($name,'.php')===false) $name.='.php' ;
    if (file_exists(_DIR_TO_EXTENSIONS.'/'.$name))
    { include_once(_DIR_TO_EXTENSIONS.'/'.$name) ;
      if (!$options['no_hidden_var']) {?><input type=hidden name="include_extension[<?echo $name?>]" value="1"><?} // используем имя расширения как ключ, чтобы расширения не дублировались
      if ($GLOBALS['debug_frame_viewer']) echo ' - <span class=green>OK</span><br>' ;
      return(1) ;
    }
    else
    {   list($ext_name,$script_name)=explode('/',$name) ;
        $script_name=str_replace('.php','',$script_name) ;
        if (file_exists(_DIR_ENGINE_EXT.'/'.$ext_name.'/'.$script_name.'.php'))
        { include_once(_DIR_ENGINE_EXT.'/'.$ext_name.'/'.$script_name.'.php') ;
          if (!$options['no_hidden_var']) {?><input type=hidden name="include_extension[<?echo $name?>]" value="1"><?} // используем имя расширения как ключ, чтобы расширения не дублировались
          if ($GLOBALS['debug_frame_viewer']) echo ' - <span class=green>OK</span><br>' ;
          return($script_name) ;
        }
        else
        { if ($GLOBALS['debug_frame_viewer']) echo ' - <span class=red>Расширение не найдено в '._DIR_TO_EXTENSIONS.'</span><br>' ;
          return(0) ;
        }
    }
 }


 function ext_panel_register($options)
 {
   $_SESSION['ext_panel_func'][]=$options ;

 }

  // пытаемся выполнить команду
  // 1. если передан код класса в options['clss'], пытаемся найти функцию в CLSS_xxx, если находим - выполняем
  // 2. если передан указатель на тукущую страницу/фрейм, ищем в нем метод, если находим - выполняем
  // 3. пытаемся подклбчить ext/mod/ext скрипт, на основании cmd+$from, если  находим функцию - выполняем
  function exec_script_cmd($cmd,$from='',$options=array())
  { $result=0 ; $cmd_exec=0 ;
    $debug=_DEBUG_CMD_INCLUDE || $options['debug'] ;
    // если передан код класса, ищем метод в объекте класса
    if (isset($options['clss']))
    { $obj_clss=_CLSS($options['clss']) ; //damp_array($obj_clss) ;
      if (method_exists($obj_clss,$cmd))
      { if ($debug) echo 'Функция <strong>'.$cmd.'</strong> найдена в классе <span class=green>clss_'.$options['clss'].'</span><br><br>' ;
        $result=$obj_clss->$cmd($options) ;
        return(array($result,1)) ;
      }
    }

    // проверяем наличие метода в соответствующем классе страницы (фрейма)
    if (is_object(_CUR_PAGE()) and method_exists(_CUR_PAGE(),$cmd))
    { if ($debug) echo 'Функция <strong>'.$cmd.'</strong> найдена в классе страницы <span class=black>'.hide_server_dir(__FILE__).'</span>::<span class=green>'.__CLASS__.'</span><br><br>' ;
      $result=_CUR_PAGE()->$cmd($options) ;
      $cmd_exec=1 ;
    }
    elseif (function_exists($cmd))
    { if ($debug) echo 'Функция <strong>'.$cmd.'</strong> <span class=green>найдена</span><br>';
      $result=$cmd($options) ;
      $cmd_exec=1 ;
    }
    else
    { $func_name=include_script_cmd($cmd,$from,$options) ;   // вернет имя функции, если она найдена
      if ($func_name) { $result=$func_name($options) ; $cmd_exec=1 ; }
    }
    return(array($result,$cmd_exec)) ;
  }

// ключевая функция для подключения скрипта с функицией-командой
 //
 // V1:
 // cmd=test_panel                              - текущий класс страницы
 // cmd=demo/test_panel                         - /class/ext/demo/test_panel.php
 // cmd=test_panel from=ext/demo                - /engine/ext/demo/test_panel.php
 // cmd=test_panel from=ext/demo/i_demo.php     - /engine/ext/demo/i_demo.php
 // cmd=test_panel from=mod/demo                - /class/engine_modules/demo/test_panel.php
 // cmd=test_panel from=mod/demo/i_demo.php     - /class/engine_modules/demo/i_demo.php
 //
 // V2:
 // cmd=test_panel                              - /class/c_ajax.php для сайта и /engine/admin/c_ajax.php для админки
 // cmd=demo/test_panel                         - /class/ext/demo/c_ajax.php
 // cmd=test_panel from=ext/demo                - /engine/ext/demo/c_ajax.php
 // cmd=test_panel from=mod/demo                - /class/engine_modules/demo/c_ajax.php

 function include_script_cmd($cmd,$from='',$options=array())
 {  $debug=0 ;  $engine_ext='' ;  $site_ext='' ; $site_module='' ; $script_name='' ; $func_exec='' ;
    $debug=$GLOBALS['debug_frame_viewer'] || $GLOBALS['debug_search_panel_function']|| _DEBUG_CMD_INCLUDE || $options['debug'] ;
    /// !!! предусмотреть передачу через $options параметра file
    /// !!! предусмотреть поиск метода cmd в тукущем классе
    $arr_cmd=explode('/',$cmd) ; //damp_array($arr_dir) ;
    if (_sizeof($arr_cmd)==2) { $site_ext=$arr_cmd[0] ; $func_name=$arr_cmd[1]; $script_name=($from)? $from:$func_name.'.php' ; } else $func_name=$cmd ;
    $arr_from=explode('/',$from) ; //damp_array($arr_dir) ;
    if ($arr_from[0]=='ext') { $engine_ext=$arr_from[1] ; $func_name=$cmd ; $script_name=$cmd.'.php' ;}
    if ($arr_from[0]=='mod') { $site_module=$arr_from[1] ; $func_name=$cmd ; $script_name=$cmd.'.php' ;}
    if ($arr_from[2])        { $script_name=$arr_from[2] ;  }
    $script='' ;
    if ($site_ext)    $script=include_script(_DIR_TO_CLASS.'/ext/'.$site_ext,$script_name,array('comment'=>'Подключили расширение сайта','debug'=>$debug)) ;
    if ($engine_ext)  $script=include_script(_DIR_TO_ENGINE.'/ext/'.$engine_ext,$script_name,array('comment'=>'Подключили расширение движка','debug'=>$debug)) ;
    if ($site_module) $script=include_script(_DIR_TO_MODULES.'/'.$site_module,$script_name,array('comment'=>'Подключили модуль сайта сайта','debug'=>$debug)) ;
    if ($script)
    { if(function_exists($func_name)) { $func_exec=$func_name ; if ($debug) echo 'Функция "<strong>'.$func_name.'</strong>" - <span class=green>OK</span><br>' ; }
      else { echo '<span class=red>Функция <strong>'.$func_name.'</strong> не найдена  в скрипте "<strong>'.hide_server_dir($script).'</strong>"</span><br>' ;}
    }

    // необходопо показать причины, по которым не был найдена функция, независимо от debug
    if ((!$func_exec or $debug) and _IS_SYSTEM_IP )
    {  $arr['cmd']=$cmd ; $arr['from']=$from ; $arr['site_ext']=$site_ext ; $arr['engine_ext']=$engine_ext ; $arr['site_module']=$site_module ; $arr['script_name']=$script_name ; $arr['func_name']=$func_name ;
       damp_array($arr,1,-1) ;
    }
    return($func_exec) ;
 }

  function include_script($dir,$script_name,$options=array())
   { $script=$dir.'/'.$script_name ;
     $debug=_DEBUG_CMD_INCLUDE || $options['debug'] ;
     if (is_dir($dir) and is_file($script))
      { include_once($script) ;
        if ($debug) echo $options['comment'].': <strong>'.hide_server_dir($script).'</strong>  - <span class=green>OK</span><br>' ;
      }
     else
     { echo '<span class=red>Не найден скрипт <strong>'.hide_server_dir($script).'</strong></span><br>' ;
       $script='' ;
     }
     return($script) ;
   }

   function encrypt_string($string,$key=_APP_KEY) {
     $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
       //echo 'encrypt_string "'.$string.'"'.'<br>' ; echo '_APP_KEY='._APP_KEY.'<br>' ;
     $encrypted_data = openssl_encrypt($string, 'aes-256-cbc', $key, 0, $iv);
     return base64_encode($encrypted_data.'::'.$iv);
   }

   function decrypt_string($string,$key=_APP_KEY) {
     list($encrypted_data, $iv) = explode('::', base64_decode($string), 2);
     //echo 'decrypt_string "'.$string.'"'.'<br>' ; echo '_APP_KEY='._APP_KEY.'<br>' ;
         return openssl_decrypt($encrypted_data, 'aes-256-cbc', $key, 0, $iv);
   }

// Определяем новую функцию-обработчик fatal error.
function myShutdownHandler()
{
  if (@is_array($e = @error_get_last())) {
    $code = isset($e['type']) ? $e['type'] : 0;
    $msg = isset($e['message']) ? $e['message'] : '';
    $file = isset($e['file']) ? $e['file'] : '';
    $line = isset($e['line']) ? $e['line'] : '';
    if($code>0)userErrorHandler($code,$msg,$file,$line,'');
    $GLOBALS['is_fatal_error']=1 ;


  }
}

?>
