<?php

##################################################
##												##
## Author:       Andrey Brykin (Drunya)         ##
## Version:      1.3.1                          ##
## Project:      CMS                            ##
## package       CMS Fapos                      ##
## subpackege    Document parser library        ##
## copyright     ©Andrey Brykin 2010-2011       ##
##################################################


##################################################
##												##
## any partial or not partial extension         ##
## CMS Fapos,without the consent of the         ##
## author, is illegal                           ##
##################################################
## Любое распространение                        ##
## CMS Fapos или ее частей,                     ##
## без согласия автора, является не законным    ##
##################################################

/**
* Document parser
*
* Parse pages and data. Replaced chanks, snippets.
* Quote/unquote global tags.
*
* @author        Andrey Brykin
* @package       CMS Fapos
* @subpackage    Document parser
* @link          http://cms.develdo.com
*/

include(R . 'sys/inc/mobile_device_detect.php');

class Document_Parser {

	/**
	 * @var object
	 */
	private $Cache;
	
	/**
	 * @var string 
	 */
	public $templateDir;
	
	private static $levels = false;
	
	

	/**
	 *
	 */
	public function __construct() {
		$this->Cache = new Cache;
		$this->Cache->prefix = 'block';
		$this->Cache->cacheDir = R . 'sys/cache/blocks/';
		$this->Cache->lifeTime = 3600;
	}
	
	
	
	/**
	* quote global tags
	* @data      (str)||(array) data
	* @return     quoted data
	*/
	public function quoteTags($data) {
		
		if (is_array($data)) {
			foreach ($data as $key => $value) {
				$data[$key] = $this->quoteTags($value);
			}
			return $data;
		} else {
			$symbols = array(
				'}' => '&#125;',
				'{' => '&#123;',
			);
			$data = str_replace(array_keys($symbols), $symbols , $data);
			return $data;
			//return str_replace('}', '\}', $data);
		}
		

	}
	
	/**
	* unquote global tags
	* @data      (str)||(array) data
	* @return     unquoted data
	*/
	public function unquoteTags($data) {
		if (is_array($data)) {
			foreach ($data as $key => $value) {
				$data[$key] = $this->unquoteTags($value);
			}
			return $data;
		} else {
			$symbols = array(
				'}' => '&#125;',
				'{' => '&#123;',
			);
			$data = str_replace($symbols,  array_keys($symbols), $data);
			return $data;
			//return str_replace('\}', '}', $data);
		}
	}


	/**
	* @param string file       path to file
	* @return string           parsed file
	*/
	public function getAndParseFile($file) {
		$data = file_get_contents($file);
		$data = $this->parseSnippet($data); 
		$data = $this->parseAddOperators($data);
		$data = $this->ParseTemplate($data);
		return $data;
	}
	
	
	/**
	* @file       path to file
	* @return     parsed file
	*/
public function getAndParse($file) { 


if (!empty($_GET['version']) && $_GET['version'] === 'full') { 
     $_SESSION['version'] = 'full'; 
} else if (mobile_device_detect(true, true, true, true, true, true, true, false, false) && empty($_SESSION['version']) 
|| (!empty($_GET['version']) && $_GET['version'] === 'pda')) { 
          $_SESSION['version'] = 'pda'; 
} 


if (!empty($_SESSION['version']) && $_SESSION['version'] === 'pda') { 
    $file = 'pda_' . $file;  
}
     
     
		$file = R . 'template/' . Config::read('template') . '/html/%s/' . trim($file);
		$file = (file_exists(sprintf($file, $this->templateDir))) 
		? sprintf($file, $this->templateDir) : sprintf($file, 'default');
	
	
	
		if (!file_exists($file)) {
			if (Config::read('debug_mode') == 1)
				throw new Exception("Can't find '" . h($file) . "' template file");
			die("Can't find '" . h($file) . "' template file");
		}
		
		$data = file_get_contents($file);
		$data = $this->parseSnippet($data); 
		$data = $this->parseAddOperators($data);
		$data = $this->ParseTemplate($data);
		return $data;
	}
	
	
	/**
	* @file       path to file
	* @return     parsed file
	*/
	public function parseString($str) {
		$str = $this->parseSnippet($str); 
		$str = $this->parseChanck($str);
		$str = $this->ParseTemplate($str);
		return $str;
	}
	
	
	
	/**
	* @page       (str) data
	* @return      data with parsed snippets
	*/
	public function parseSnippet($page) {
		global $FpsDB;
		
        $tpl = preg_match_all('#\{\[([!]*)(\w+)\]\}#U', $page, $mas);
        for ($i= 0; $i < count($mas[2]); $i++) {
			$cached = true;
			$block_name = $mas[2][$i];
			if ($mas[1][$i] === '!') $cached = false;

			
			// Check cache
			if ($cached === true) {
				$cache_key = 'snippet_' . strtolower($block_name);
				$cache_key .= (!empty($_SESSION['user']['status'])) ? '_' . $_SESSION['user']['status'] : '_guest';
				
				if ($this->Cache->check($cache_key)) {
					$res = $this->Cache->read($cache_key);
					$page = str_replace($mas[0][$i], $res, $page);
					continue;
				}
			}
			
			
			// If no cache
			$sql = $FpsDB->select('snippets', DB_FIRST, array('cond' => array('name' => strtolower($block_name))));
			if (empty($sql[0])) continue;
            $limit = $sql[0];
			
			if (strtolower($block_name) == strtolower($limit['name'])) {
				ob_start();
				$str = eval($limit['body']);
				$res = ob_get_contents();
				ob_end_clean();
				$page = str_replace($mas[0][$i], $res, $page); 

				if ($cached === true) 
					$this->Cache->write($res, $cache_key, array());
			}
	    }
		return $page;
	}
	
	
	
	/**
	* @page       (str) data
	* @return      data with parsed additional operators
	*/
	public function parseAddOperators($data) {
		if (!empty($_SESSION['user']['status'])) {
			$userGroup = ACL::get_user_group($_SESSION['user']['status']); 
		} else {
			$userGroup = ACL::get_user_group(0);
		}
		$online = getWhoOnline();
		$params = array(
			'IS_USER_REGISTERED' => (bool)(!empty($_SESSION['user']['id'])),
			'FPS_USER_NAME' => (!empty($_SESSION['user']['name'])) ? h($_SESSION['user']['name']) : 'Гость',
			'FPS_USER_GROUP' => (!empty($userGroup['title'])) ? $userGroup['title'] : 'Гости',
			'PERSONAL_PAGE_LINK' => (!empty($_SESSION['user']['id'])) ? get_url('/users/edit_form') : get_url('/users/add_form/'),
			'FPS_WDAY' => date("D"),
			'FPS_DATE' => date("d-m-Y"),
			'FPS_TIME' => date("H:i"),
			'FPS_YEAR' => date("Y"),
			'POWERED_BY' => 'Fapos',
			'SITE_TITLE' => Config::read('site_title'),
			'ALL_ONLINE' => ($online['users'] + $online['guests']),
			'USERS_ONLINE' => $online['users'],
			'COUNTER' => get_url('/sys/img/counter.png'),
			'WWW_ROOT' => WWW_ROOT,
			'FPS_RSS' => $this->getRss(),
		);
		extract($params);
		
		
		if (self::$levels === false) {
			self::$levels += 1;
		} else {
			self::$levels = 1;
		}
		
		if (self::$levels > 3) return $data;
		
		
		
		if (preg_match_all('#^(.*?)\{if\(([\w\s_\-="\']+)\)\}(.*)(\{else\}(.*))?\{endif\}(.*?)$#isU', $data, $matches)) {
			if (count($matches[1]) > 0) {
				foreach ($matches[2] as $key => $row) {

					$comstr = preg_replace('#[\(=\s]*([A-Z_]+?)[\)=\s]*#uU', '$\\1', $row);
					$comstr = '$b = (boolean)(' . $comstr . ');';
					eval($comstr);
					
					if ($b === true) {
						$data = str_replace(
							$matches[0][$key], 
							$matches[1][$key].$matches[3][$key].$matches[6][$key], 
							$data
						);
						$data = $this->parseAddOperators($data);
					} else {
						$data = str_replace(
							$matches[0][$key], 
							$matches[1][$key].$matches[5][$key].$matches[6][$key], 
							$data
						);
						$data = $this->parseAddOperators($data);
					}
				}
			}
		}
		self::$levels = false;
		return $data;
	}
		
		
	/**
	* @page       (str) data
	* @return      data with parsed global tags
	*/
	public function ParseTemplate($page) {
		$markets = array();
		
		$markets['{FPS_WDAY}'] = date("D");
		$markets['{FPS_DATE}'] = date("d-m-Y");
		$markets['{FPS_TIME}'] = date("H:i");
		$markets['{FPS_YEAR}'] = date("Y");
		
		$markets['{POWERED_BY}'] = 'Fapos';
		$markets['{SITE_TITLE}'] = Config::read('site_title');
		
		if (isset($_SESSION['user']) && isset($_SESSION['user']['name'])) {
			$markets['{PERSONAL_PAGE_LINK}'] = get_url('/users/edit_form');
			$markets['{FPS_USER_NAME}'] = $_SESSION['user']['name'];
			$userGroup = ACL::get_user_group($_SESSION['user']['status']); 
			$markets['{FPS_USER_GROUP}'] = $userGroup['title'];
		} else {
			$markets['{PERSONAL_PAGE_LINK}'] = get_url('/users/add_form/');
			$markets['{FPS_USER_NAME}'] = 'Гость';
			$markets['{FPS_USER_GROUP}'] = 'Гости';
		}
		
		$online = getWhoOnline();
		$markets['{ALL_ONLINE}'] = ($online['users'] + $online['guests']);
		$markets['{USERS_ONLINE}'] = $online['users'];
		$markets['{GUESTS_ONLINE}'] = $online['guests'];
		
	
		if (strstr($page, '{FPS_CHAT}')) {
			include_once R . 'modules/chat/index.php';
			$chat_link = get_url('/chat/view_messages/');
			$markets['{FPS_CHAT}'] = '<iframe id="fpsChat" src="' . $chat_link 
			. '" width="100%" height="400" style="overflow:auto; margin:0px; padding:0px; border:none;"></iframe>';
			$markets['{FPS_CHAT}'] .= ChatModule::add_form();
		}
		
		$markets['{COUNTER}'] = get_url('/sys/img/counter.png');
		$markets['{WWW_ROOT}'] = WWW_ROOT;
		
		$markets['{FPS_RSS}'] = $this->getRss();
		
		$page = str_replace(array_keys($markets), $markets, $page);
		

		return $page;	
	}
	
	
	/**
	* @return     list with RSS links
	*/
	public function getRss() {
		$rss = '';
		if (Config::read('rss_news', 'common')) {
			$rss .= get_img('/sys/img/rss_icon_mini.png') . get_link(__('News RSS'), '/news/rss/') . '<br />';
		}
		if (Config::read('rss_stat', 'common')) {
			$rss .= get_img('/sys/img/rss_icon_mini.png') . get_link(__('Stat RSS'), '/stat/rss/') . '<br />';
		}
		if (Config::read('rss_loads', 'common')) {
			$rss .= get_img('/sys/img/rss_icon_mini.png') . get_link(__('Loads RSS'), '/loads/rss/') . '<br />';
		}
		
		return $rss;
	}
	
	
	/**
	* @page       (str) data
	* @modul      (str) current module 
	* @return     data with head menu
	*/
	public function headMenu($page, $modul=NULL) {
		$this->ACL = new ACL;
		
		$menu = get_link('Главная', '/');
		if(isset($_SESSION['user']['name'])) {
			$menu = $menu . get_link('Мой профиль', '/users/edit_form/') . get_link('Выход', '/users/logout/');
			$menu = $menu . get_link('Пользователи', '/users/index/');
			if ($modul == 'forum') {
			    $menu = $menu . get_link('Поиск', '/search/');
			}
			
			// Есть ли непрочитанные сообщения в папке "Входящие"?
			$cntNewMsg = countNewMessages();
			if ( $cntNewMsg < 1 ) {
				$menu = $menu . get_link('Личные&nbsp;сообщения', '/users/in_msg_box/');
			} else {
				$menu = $menu . get_link('Новые&nbsp;сообщения', '/users/in_msg_box/', array('class' => 'newMessages'));
			}
		} else {
			$menu = $menu . get_link('Регистрация', '/users/add_form/') . get_link('Вход', '/users/login_form/');
		}		
		
		if ( isset( $_SESSION['user']['name'] ) and $this->ACL->turn(array('panel', 'entry'), false)) {
		$menu = $menu . get_link('Админка', '/admin/');
	    }
		
		$menu .= '<a onClick="add_favorite(this);" title="Добавить в закладки" href="javascript://" >В закладки</a>';
		
		$html = str_replace('{HEADMENU}', $menu, $page);
	
		return $html;
	}
	
}

?>
