<?php
/*
* @package LabCMS
* @copyright (c) 2006 Alexander Levin aka Loki (loki_angel@mail.ru)
* @support http://labcms.ru
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*/
class LabCMS
{
	protected static $instance;
	public $no_errors=true;
	public $errors=array();
	public $cache=array();
	public $skins=array();
	public $cached=false;
	public $modules=null;
	public $show=false;
	
	private $title=null;
	private $description=null;
	private $keywords=null;
	private $template=null;
	private $_cache_id=1;
	private $cacher=null;
	private $default_skin='default';

	private function __clone()
	{
	}

	public static function i()
	{
		return self::instance();
	}
	
	public static function instance()
	{
		if (!is_object(self::$instance)) {
			//self::$instance = new self;
			self::$instance = Factory::create('LabCMS');
		}
		return self::$instance;
	}

	public static function init($url=null)
	{
		if (!$url) $url=$_SERVER['PHP_SELF'];
		
		if (!config::get('core.domain')) {
			config::set('core.domain', preg_replace('/^www\./i', '', $_SERVER["SERVER_NAME"]));
		}
		$port=(!in_array($_SERVER['SERVER_PORT'], array(80, 443)))?':'.$_SERVER['SERVER_PORT']:'';
		config::set(
			'core.siteUrl',
			($_SERVER['SERVER_PORT']==443)?'https':'http'
			.'://'.config::get('core.domain').$port
		);

		self::i()->_LoadNodeByURL($url);
		
		if (!self::i()->show || !self::i()->id) {
			if (!self::i()->error301()) self::i()->error404();
		}
		
		if (isset(self::i()->params['location'])) self::i()->redirectByLocation(self::i()->params['location']);

		if (self::i()->title) config::set('core.title', self::i()->title);
		if (self::i()->description) config::set('core.description', self::i()->description);
		if (self::i()->keywords) config::set('core.keywords', self::i()->keywords);
		Tpl::i()->assignByRef('_lc', self::$instance);
	}
	
	private function _LoadNodeByURL($url)
	{
		if (self::_getCache($url)) {
			self::i()->setSkin(config::get('core.skin'));
			return;
		}

		//пытаемся получить данные для указанной ноды
		$data=$this->_getNodeDataByUrl($url);
		//если получили какие-то данные, то 
		if ($data) {
			$this->_setNodeParams($data);
		}
		$this->setSkin(config::get('core.skin'));
		$this->_setCache($url);
	}

	private function _getNodeDataByUrl($url)
	{
		return Db::i()->selectRow(
			"SELECT t.tree_id, t.parent_id, t.symlink, t.params, t.template, t.name,
			l.lang_id, lang_name, `key`, t.path, t.`show`
			FROM ?_tree t
			LEFT JOIN ?_langs l ON t.lang_id=l.lang_id
			WHERE t.path=? AND symlink=0 LIMIT 1", $url
		);
	}
	
	private function _setNodeParams($data)
	{
		$this->id=$data['tree_id'];
		$this->title=$data['name'];
		$this->show=$data['show'];
		$this->url=$data['path'];
		$this->symlink=$data['symlink'];
		$this->parent_id=$data['parent_id'];
		
		$this->lang=array(
			'id'=>$data['lang_id'],
			'key'=>$data['key'],
			'name'=>$data['lang_name']
		);
		
		if ($data['params']) {
			$var_arr=explode("&", $data['params']);
			$this->params=array();
			foreach ($var_arr as $val) {
				$vars=explode("=", $val);
				if (trim($vars[0])) $this->params[trim($vars[0])]=trim($vars[1]);
			}
		}
		
		$this->parents=$this->GetAllParents($this->id);
		
		if (!$this->lang['id'] || !$this->template) $this->_GetDataFromParents();

		$this->_GetModules();
	}
	
	private function _GetDataFromParents()
	{
		if ($this->template && $this->lang['id']) return;
		
		$parent_nodes=Db::i()->select(
			"SELECT template, l.lang_id, lang_name, `key`
			FROM ?_tree t
			LEFT JOIN ?_langs l ON t.lang_id=l.lang_id
			WHERE tree_id IN (?a) ORDER BY FIELD(tree_id, ?a)",
			$this->parents, array_reverse($this->parents)
		);
		if ($parent_nodes) {
			foreach ($parent_nodes as $node) {
				if ($this->template && $this->lang['id']) break;
				if (!$this->template && $node['template']) $this->template=$node['template'];
				if (!$this->lang['id'] && $node['lang_id']) {
					$this->lang=array(
						'id'=>$node['lang_id'],
						'key'=>$node['key'],
						'name'=>$node['lang_name']
					);
				}
			}
		}
		//если язык не установлен, то задаем язык по умолчанию
		if (!$this->lang['id']) {
			$lang=Db::i()->selectRow(
				"SELECT lang_id, lang_name, `key`
				FROM ?_langs WHERE `key`=?", config::get('core.default_lang')
			);
			$this->lang=array(
						'id'=>$lang['lang_id'],
						'key'=>$lang['key'],
						'name'=>$lang['lang_name']
			);
		}
		
	}
	
	private function _GetModules()
	{
		$static=$component=$system=$common=array();
		$modules=Db::i()->select(
			'SELECT m.module_id, module, component, tree_id, static, runlevel
			FROM ?_includes i JOIN ?_modules m ON i.module_id=m.module_id
			WHERE tree_id IN (?a) AND m.disable=0
			ORDER BY FIELD(tree_id, ?a), runlevel, component DESC',
			$this->parents, array_reverse($this->parents)
		);
		if ($modules)
		foreach ($modules as $module) {
			if (!count($static)
				&& !count($system)
				&& !count($component)
				&& !count($common)
			) {
				$current_node=$module['tree_id'];
			}
			
			if ($module['tree_id']==$current_node || $module['static']) {
				if ($module['runlevel']>1000) {
					$common[$module['module_id']]=$module;
				} elseif ($module['runlevel']<1000) {
					$system[$module['module_id']]=$module;
				} elseif ($module['component']) {
					$component[$module['module_id']]=$module;
				}
			}
		}
		
		//порядок подключения модулей: системные, компоненты, остальные
		$this->modules=$system+$component+$common;
	}
	
	public function setAdminSkin()
	{
		if (config::get('core.admin_skin')) $this->setSkin(config::get('core.admin_skin'));
		else $this->setSkin($this->default_skin);
	}
	
	public function setSkin($skin)
	{
		if ($this->getSkin()==$skin) return;
		$this->_setSkin($skin);

		$this->_setTemplateData();

		if (array_key_exists($this->getSkin(), $this->skins)
			&& is_array($this->skins[$this->getSkin()])
			&& isset($this->skins[$this->getSkin()]['css'])
			&& is_array($this->skins[$this->getSkin()]['css'])
			&& isset($this->skins[$this->getSkin()]['js'])
			&& is_array($this->skins[$this->getSkin()]['js'])) return;

		$this->skins[$this->getSkin()]['css']=$this->skins[$this->getSkin()]['js']=array();
		$this->_setGlobalSkinData();
		$this->_setModulesSkinData();
		$this->cached=false;

	}
	
	private function _setSkin ($skin)
	{
		LabVars::$current_skin=$skin;
	}
	
	private function _setTemplateData()
	{
		Tpl::i()->setTemplateDir($this->getSkinsTree());
		Tpl::i()->compile_id=$this->getSkin();
	}
	
	private function _setGlobalSkinData()
	{
		$this->_setBase($this->getSkin());

		//подключаем общие для дизайна css и js
		foreach ($this->getSkinsTree() as $skin) {
			if (is_dir($skin.'/css')) {
				$this->_SetSkinCss($skin.'/css');
				break;
			}
		}
		
		foreach ($this->getSkinsTree() as $skin) {
			if (is_dir($skin.'/js')) {
				$this->_SetSkinJs($skin.'/js');
				break;
			}
		}
	}
	
	private function _setModulesSkinData()
	{
		if ($this->modules) {
			foreach ($this->modules as $module) {
				foreach ($this->getSkinsTree() as $skin) {
					if (is_dir($skin.'/'.$module['module'].'/css')) {
						$this->_SetSkinCss($skin.'/'.$module['module'].'/css');
						break;
					}
				}
				
				foreach ($this->getSkinsTree() as $skin) {
					if (is_dir($skin.'/'.$module['module'].'/js')) {
						$this->_SetSkinJs($skin.'/'.$module['module'].'/js');
						break;
					}
				}
			}
		}
	}
	
	public function getSkinsTree($skin=null)
	{
		if (!$skin) $skin=$this->getSkin();
		if (isset($this->skins[$skin]['tree']) && $this->skins[$skin]['tree']) return $this->skins[$skin]['tree'];
		$skins=array();
		$current=$skin;
		while (true) {
			if ($skin!=$this->default_skin) {
				$skins[]=LAB_PATH_TEMPLATE.'/'.$skin;
				if (file_exists(LAB_PATH_TEMPLATE.'/'.$skin.'/theme.xml')) {
					$xml=file_get_contents(LAB_PATH_TEMPLATE.'/'.$skin.'/theme.xml');
					if (preg_match('/<parent>(.+?)<\/parent>/i', $xml, $parent)) {
						if (in_array(LAB_PATH_TEMPLATE.'/'.$parent[1], $skins)) {
							$this->error(_m('Циклическая зависимость в шаблонах'));
							break;
						}
						$skin=$parent[1];
						continue;
					}
				}
			}
			break;
		}
		$skins[]=LAB_PATH_TEMPLATE.'/'.$this->default_skin;
		$this->skins[$current]['tree']=$skins;
		$this->cached=false;
		return $skins;
	}
	
	private function _setBase($skin)
	{
		Tpl::i()->assign(
			'base',
			config::get('core.siteUrl').str_replace(LAB_PATH_ROOT, '', LAB_PATH_TEMPLATE).'/'.$skin
		);
	}
	
	private function _SetSkinCss($path)
	{
		if ($files=glob($path.'/*.css')) {
			sort($files);
			foreach ($files as $file) {
				$media=basename($file, ".css");
				$media=(
					in_array(
						$media,
						array('braille', 'embossed', 'handheld', 'print', 'projection', 'screen', 'speech', 'tty', 'tv')
					)
				)?$media:'all';
				$this->skins[$this->getSkin()]['css'][]=array(
					"path"=>str_replace(LAB_PATH_ROOT, '', $file),
					"media"=>$media
				);
			}
		}
	}

	private function _SetSkinJs($path)
	{
		if ($js=glob($path.'/*.js')) {
			sort($js);
			foreach ($js as $js_item) {
				$this->skins[$this->getSkin()]['js'][]=str_replace(LAB_PATH_ROOT, '', $js_item);
			}
		}
	}
	
	/*
	* метод определяет всех родителей текущего узла
	* @param integer	id узла
		* @return array	массив родителей отсортированный по подчиненности
		* @author Loki
	*/
	public function GetAllParents($id)
	{
		$tree=Db::i()->selectCol("SELECT tree_id AS ARRAY_KEY, parent_id FROM ?_tree");
		$parents=array($id);
		while (!empty($tree[$id])) {
			$parents[]=$tree[$id];
			$id=$tree[$id];
		}
		return array_reverse($parents);
	}
	
	public function redirectByLocation($url)
	{
		// Если ссылка на tree_id, если нет, то просто переходим как по url
		if (is_numeric($url)) {
			// Получаем путь
			$url = Db::i()->selectCell(
				"SELECT path  FROM ?_tree WHERE `tree_id` = ?d",
				$url
			);
		}
		
		if (!empty($url)) {
			header("Location: ".$url);
			exit();
		}
	}
	
	/*
	* пытается найти редирект и выводит ошибку 301 в случае успеха
		* @author Loki
	*/
	public function error301($url=null)
	{
		if (!$url) $url=$this->cut_sessid($_SERVER['REQUEST_URI']);
		$redirects=Db::i()->select(
			"SELECT pattern, link FROM ?_redirects
			WHERE `active`=1 ORDER BY pos"
		);
		if ($redirects)
		foreach ($redirects as $redirect) {
			$pattern=str_replace('/', '\/', $redirect['pattern']);
			if ($url!=$link=preg_replace('/^'.$pattern.'$/i', $redirect['link'], $url)) {
				header("HTTP/1.0 301 Moved Permanently");
				header("Location: ".$link);
				exit;
			}
		}
		return false;
	}
	
	/*
	* выводит ошибку 404 из шаблона
		* @author Loki
	*/
	public function error404()
	{
		Header("HTTP/1.0 404 Not Found");
		Header("Date: " . gmdate("D, d M Y H:i:s") . " GMT");
		Header("Content-Type: text/html; charset=utf-8");
		Tpl::i()->assign('css', LabCMS::i()->getSkinCSS());
		Tpl::i()->assign('js', LabCMS::i()->getSkinJS());
		Tpl::i()->assign('sitemap', $this->getModuleNodePath('sitemap'));
		Tpl::i()->display('errors/404.tpl');
		exit;
	}
	
	/*
	* выводит ошибку 403 из шаблона
		* @author Loki
	*/
	public function error403()
	{
		//если пользователь не авторизован
		if (User::i()->isGuest()) {
			if (empty($this->params['error403'])) {
				$module=config::get('core.auth_module')?config::get('core.auth_module'):'login';
				$this->params['error403']=$this->getModuleNodePath($module);
			}
			if ($this->params['error403']) {
				refresh(
					'',
					$this->url(
						false, false, false,
						$this->params['error403'], $_SERVER['REQUEST_URI']
					)
				);
			}
			Tpl::i()->assign('auth_path', $this->params['error403']);
		}
		Header("HTTP/1.0 403 Forbidden");
		Header("Date: " . gmdate("D, d M Y H:i:s") . " GMT");
		Header("Content-Type: text/html; charset=utf-8");
		Tpl::i()->display('errors/403.tpl');
		exit;
	}
	
	/*
	* добавляет в шаблон сообщение об ошибке
	* добавляет значение true параметру класса is_error
	* @param string	текст сообщения
		* @return boolean	true
		* @author Loki
	*/
	//TODO временно включаем второй параметр в true. Потом его надо будет совсем убрать
	public function error($msg, $lang=true)
	{
		if ($msg) {
			if ($lang) $msg=$msg;
			else $msg=_m($msg);
		} else $msg=_m("Произошла неизвестная ошибка!");
		Tpl::i()->append('errors', $msg);
		$this->errors[]=$msg;
		$this->no_errors=false;
	}
	
	public function setMessage($mess, $html=false, $lang=false)
	{
		if ($mess) {
			if (!$lang) $mess=_m($mess);
			if (!$html) $type='text';
			else $type='html';
			return Tpl::i()->assign('system_message', array($type=>$mess));
		}
		return false;
	}
	
	public function getModuleNodePath($module)
	{
		if (isset($this->path_to_module[$module])) return $this->path_to_module[$module];
		$this->path_to_module[$module]=Db::i()->selectCell(
			"SELECT path
			FROM ?_tree t
			JOIN ?_includes i ON t.tree_id=i.tree_id
			JOIN ?_modules m ON i.module_id=m.module_id
			WHERE module = ? AND `show`=1 LIMIT 1", $module
		);
		$this->cached=false;
		return $this->path_to_module[$module];
	}
	
	public function getModuleIdByName($module)
	{
		if (isset($this->cache['modules'][$module])) return $this->cache['modules'][$module];
		$this->cache['modules'][$module]=Db::i()->selectCell(
			"SELECT module_id
			FROM ?_modules
			WHERE module = ? LIMIT 1", $module
		);
		$this->cached=false;
		return $this->cache['modules'][$module];
	}
	
	public function url($params=array(), $action='', $type='', $href='', $redirect='', $token=false)
	{
		return _url($params, $action, $type, $href, $redirect, $token);
	}
	
	public function isAjax($ext=null)
	{
		if (!$ext && isset($_GET['data_type'])) $ext=$_GET['data_type'];
		return in_array($ext, array('js', 'xml', 'json', 'ajax'));
	}
	
	public function disableForDemo()
	{
		if (DEMO_MODE) {
			if (!LabVars::$current_module['component']) return false;
			if (LabVars::$current_module['module']=='login'
				&& (!$_GET['action']
				|| $_GET['action']=='logout')
			) return false;
			if (!$_REQUEST['token']) return false;
			$this->error(_m("Данная функция недоступна в демо версии"));
			return true;
		}
	}
	
	/**
		* метод закидывает отработавший модуль в шаблон, в зависимости от его типа
		* если модуль является компонентом, то добавляем его данные в переменную $_component, 
		* в противном случае в переменную $_имя_модуля
		* @param text
		* @author Loki
		*/
	public function assignModule($mod_template)
	{
		//проверяем существует ли шаблон для данного модуля
		if (!$template=$this->_checkTempalte($mod_template)) return false;

		//если модуль является компонентом, то добавляем его данные в переменную $_component,
		//в противном случае в переменную $_имя_модуля
		if (LabVars::$forceDisplay) {
			Tpl::i()->display($template, $this->_getCacheId());
		} elseif ($this->isModuleComponent()) {
			$_component=Tpl::i()->fetch($template,	$this->_getCacheId());
			$_component=Hook::call('filter_component', $_component);
			Tpl::i()->assign('_component', $_component);
		} else {
			Tpl::i()->assign(
				'_module_'.$this->getModuleName(),
				Tpl::i()->fetch(
					$template,
					$this->_getCacheId()
				)
			);
		}
		$this->_cache_id=1;
	}
	
	private function _getCacheId()
	{
		//return $this->getModuleId()."|".User::i()->group_id."|".$this->_cache_id;
		return User::i()->group_id."|".$this->_cache_id;
		//return $this->_cache_id;
	}
	
	/**
		* проверяет кэширован ли запрошенный шаблон
		* @param text	$template	имя шаблона
		* @param int	$time	период кэширования
		* @param text	$id	идентификатор кэша
		* @author Loki
		*/
	public function is_cached($template, $time, $id=1)
	{
		if (config::get('core.cache')) {
			//включаем кэширование smarty
			Tpl::i()->caching = true;
			$this->_cache_id=$id;

			Tpl::i()->setCacheLifetime($time);

			//если модуль имеет шаблон для вывода, то проверяем кэширован ли шаблон 
			if ($template) {
				if (!$template=$this->_checkTempalte($template)) return;
				if ((config::get('core.debug_mode')
					|| LabVars::$allow_debug)
					&& isset($_GET["debug"])
				) return;
				//если есть кэшированная версия, то возвращаем true
				return Tpl::i()->isCached(
					$template, $this->_getCacheId()
				);
			} else {
				//в противном случае проверяем кэширован ли объект.
				return $this->cached;
			}
		}
		return false;
	}
	
	/*
		* вывод на экран главного шаблона
		* @author Loki
		*/
	public function display()
	{
		//$this->cache - это массив, куда добавлены переменные, которые невозможно кэшировать 
		//из-за отстутсвия у модуля собствнного шаблона
		Tpl::i()->assign($this->cache);
		$this->_setBase($this->getSkin());
		Tpl::i()->caching = false;
		
		//если задан некэшируемый в объекте шаблон, то пытаемся отрисовать его
		if (LabVars::$template) {
			$template=$this->_checkMainTemplate(LabVars::$template);
		} else {
			$template=$this->_checkMainTemplate($this->template);
		}
		
		if (!$template) die('Сборочный шаблон не найден!');
		
		$this->cache_id=$this->cut_sessid($_SERVER['REQUEST_URI']);
		
		Tpl::i()->display(
			$template,
			$this->_getCacheId()
		);
	}
	
	private function _checkMainTemplate($tpl)
	{
		if (!$tpl) $tpl='default.tpl';
		
		if (Tpl::i()->templateExists($tpl)) {
			return $tpl;
		} elseif (Tpl::i()->templateExists('default.tpl')) {
			return 'default.tpl';
		}
		
		return $this->error(sprintf(_m("Шаблон '%s' не найден"), $tpl));
	}
	
	private function _checkTempalte($tpl)
	{
		if (substr($tpl, 0, 7)=='string:') {
			return $tpl;
		}
		
		$module=$this->getModuleName();
		if (Tpl::i()->templateExists($module.'/'.$tpl)) {
			return $module.'/'.$tpl;
		}
		
		return $this->error(
			sprintf(_m("Шаблон '%s' не найден"), $module.'/'.$tpl)
		);
	}
	
	public function cut_sessid($url)
	{
		$sessid=preg_quote(ini_get('session.name'), "/");
		return preg_replace('/[\?|&]'.$sessid.'=[^&]+/', '', $url);
	}
	
	public function isError()
	{
		return count($this->errors)?true:false;
	}

	public function isNoError()
	{
		return !$this->isError();
	}

	public function getError()
	{
		return $this->errors[0];
	}
	
	public function getModuleId()
	{
		return (empty(LabVars::$current_module['module_id']))?null:LabVars::$current_module['module_id'];
	}
	
	public function getModuleName()
	{
		return (empty(LabVars::$current_module['module']))?null:LabVars::$current_module['module'];
	}
	
	public function getModuleAccess()
	{
		return (empty(LabVars::$current_module[User::i()->group_id]['access']))
		?array()
		:LabVars::$current_module[User::i()->group_id]['access'];
	}
	
	public function isModuleComponent()
	{
		return (!empty(LabVars::$current_module['component']));
	}
	
	public function isModuleSystem()
	{
		return (!empty(LabVars::$current_module['system']));
	}
	
	public function isModuleStatic()
	{
		return (!empty(LabVars::$current_module['static']));
	}
	
	public function setModuleTemplate($tpl)
	{
		LabVars::$current_module['template']=$tpl;
	}
	
	public function getModuleTemplate()
	{
		return empty(LabVars::$current_module['template'])?false:LabVars::$current_module['template'];
	}
	
	public function getSkinCSS()
	{
		return $this->skins[$this->getSkin()]['css'];
	}
	
	public function getSkinJS()
	{
		return $this->skins[$this->getSkin()]['js'];
	}
	
	public function getSkin()
	{
		//if (empty(LabVars::$current_skin)) LabVars::$current_skin=config::get('core.skin');
		return LabVars::$current_skin;
	}
	
	public function setTitle($string)
	{
		if ($this->title!=$string) $this->cached=false;
		$this->title=$string;
		config::set('core.title', $string);
	}
	
	public function setDescription($string)
	{
		if ($this->description!=$string) $this->cached=false;
		$this->description=$string;
		config::set('core.description', $string);
	}
	public function setKeywords($string)
	{
		if ($this->keywords!=$string) $this->cached=false;
		$this->keywords=$string;
		config::set('core.keywords', $string);
	}
	
	private static function _getCache($key)
	{
		if (!config::get('core.cache')) return;
		if ($data=Cache_Generic::init()->get(self::_getCacheKey($key))) {
			return self::$instance=$data;
		}
		
	}
	
	private function _setCache($key)
	{
		if (config::get('core.cache') && $this->no_errors && empty($this->cached)) {
			$this->cached=true;
			return Cache_Generic::init()->set(self::_getCacheKey($key), $this, -1);
		}
	}
	
	public function setCache()
	{
		return $this->_setCache($this->url);
	}
	
	private static function _getCacheKey($key=null)
	{
		if (is_numeric($key)) return 'node_id_'.$key;
		else return 'node_url_'.urlencode($key);
	}
	
	/*
		* сбрасывает кэш
		* если не установлен ключ, то сбрасываются только шаблоны текущего модуля,
		* если установлен - то все шаблоны или/и объекты
		* @param boolean	ключ для полного сброса кэша
		* @author Loki
		*/
	public static function reset_cache($mode=false)
	{
		switch($mode)
		{
			case('parsed'):
				Tpl::i()->clearCompiledTemplate();
				break;			
			case('auth'):
				$store =  new Auth_OpenID_FileStore(LAB_PATH_DATA.'/cache/openid');
				$store->cleanupNonces();
				break;
			default:
				self::reset_files();
				Cache_Generic::init()->clean();
				self::reset_external();
				$store =  new Auth_OpenID_FileStore(LAB_PATH_DATA.'/cache/openid');
				$store->cleanupNonces();
				Tpl::i()->clearCompiledTemplate();
		}
	}
	
	public function clearCache($template)
	{
		Tpl::i()->clearCache($this->_checkTempalte($template));
	}
	
	private static function reset_files()
	{
		$files=glob(LAB_PATH_DATA.'/cache/*');
		if ($files) foreach ($files as $file) {
			if (is_file($file)) unlink($file);
		}
		$files=glob(LAB_PATH_DATA.'/cache/smarty/*');
		if ($files) foreach ($files as $file) {
			if (is_file($file)) unlink($file);
		}
	}

	static function reset_external()
	{
		$files=glob(LAB_PATH_DATA.'/external/*');
		if ($files) array_map("unlink", $files);
	}
	
	public static function getCookieDomain()
	{
		if (config::get('core.subdomain_auth')) {
			return '.'.config::get('core.domain');
		} else {
			return null;
		}
	}
	
	public static function setAllowFileUpload()
	{
		if (!DEMO_MODE) return $_SESSION['access_files']=1;
		return $_SESSION['access_files']=0;
	}
	
	public static function checkForUpdates()
	{
		include LAB_PATH_KERNEL.'/install/version.php';

		if (version_compare($version, config::get('core.version'), '>')) {
			$update=glob(LAB_PATH_ROOT."/updates/".config::get('core.version')."-*.php");
			if (count($update)==1 && $update) {
				include $update[0];
				if ($success) {
					if (file_exists(LAB_PATH_MODULES.'/lc_guide/uninstall.sql')) {
						if (!Db::parse_mysql_dump(LAB_PATH_MODULES.'/lc_guide/uninstall.sql', false)) {
							die("При обновлении руководства произошла ошибка!");
						}
					}
					if (file_exists(LAB_PATH_MODULES.'/lc_guide/install.sql')) {
						if (!Db::parse_mysql_dump(LAB_PATH_MODULES.'/lc_guide/install.sql', false)) {
							die("При обновлении руководства произошла ошибка!");
						}
					}
						
					$ini=array();
					$ini['dblocation']=config::get('core.dblocation');
					$ini['dbname']=config::get('core.dbname');
					$ini['dbuser']=config::get('core.dbuser');
					$ini['dbpasswd']=config::get('core.dbpasswd');
					$ini['prefix']=config::get('core.prefix');
					$ini['secure_code']=config::get('core.secure_code');
			
					preg_match('/-([\d\.]+)\.php$/i', $update[0], $ver);
					$ini['version']=$ver[1];
					
					
					if (version_compare($ini['version'], '5.4', '>=')) {
						config::save('core.version', $ini['version']);
						unset($ini['version']);
					}	
									
					if (write_ini_file(LAB_PATH_DATA.'/cms.ini', $ini)) {
						self::reset_cache('all');
						Header("Location:/");
						exit();
					}
				} else die("При обновлении версии произошла ошибка!");
			} else {
				die("Ошибка структуры обновлений!");
			}
		}
	}
}