Location: PHPKode > projects > pkZoos Website > includes/template.php
<?php
	if(!defined('PK_MAGIC'))
		die('hack or what?');





	/* */

	class TPL
	{
		var $lang_dir;
		var $filename;
		var $cachename;
		var $mail;
		var $src;
		var $dst;
		var $data;
		var $block_names;
		var $block_level;
		var $tag_stack;

		var $regex_sqstring = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
		var $regex_blockvarname = '[_a-z][_a-z0-9]*\.[_a-z][_a-z0-9]*';
		var $regex_varname = '[_a-z][_a-z0-9]*';
		var $regex_hexint = '0x[a-f0-9]+';
		var $regex_float = '(?:[0-9]*\.)?[0-9]+(?:e[-+]?[0-9]+)?';





		/* */

		function TPL()
		{
			$this->reset();
		}





		/* */

		function language($lang_id)
		{
			global $db;

			$q = "
				SELECT lang_dir
				FROM " . LANGS_TABLE . "
				WHERE lang_id = " . $lang_id . "
			";

			$lang_res = $db->query($q);
			$lang_row = $db->fetch_row($lang_res);
			$this->lang_dir = $lang_row['lang_dir'];
		}





		/* */

		function filename($filename, $mail = false)
		{
			global $config;
			global $style;

			if($mail)
			{
				$this->filename = $config['script_path'] . 'langs/' . $this->lang_dir . '/mails/' . $filename;
				$this->cachename = $config['cache_path'] . 'mails.' . $this->lang_dir . '.' . $filename . '.php';
			}
			else
			{
				$this->filename = $config['style_path'] . $filename;
				$this->cachename = $config['cache_path'] . 'styles.' . $style['dir'] . '.' . $filename . '.php';
			}

			$this->mail = $mail;
		}





		/* */

		function reset()
		{
			global $lang;

			$this->lang_dir = $lang['dir'];
			$this->filename = '';
			$this->cachename = '';
			$this->mail = false;
			$this->src = '';
			$this->dst = '';
			$this->data = array
			(
				'.' => array
				(
                    'LD' => '{',
                    'RD' => '}'
				)
			);
			$this->block_names = array();
			$this->tag_stack = array();
		}





		/* */

		function display($buffer = false)
		{
			$compile = false;

            if(!@file_exists($this->cachename))
            {
                $compile = true;
            }
            else if(@filemtime($this->cachename) < @filemtime($this->filename))
            {
                $compile = true;
            }

            if($compile)
            {
                $this->_load_file($this->filename);
                $this->_compile();
				$this->_save_file($this->cachename);

				if($buffer)
				{
					$this->src = $this->dst;
					$this->dst = '';
				}
            }
            else
            {
				$this->_load_file($this->cachename);

				if(!$buffer)
				{
					$this->dst = $this->src;
					$this->src = '';
				}
			}

            if($buffer)
            {
				ob_start();
            	eval(' ?>' . $this->src . '<?php ');
            	$this->dst = ob_get_contents();
				ob_end_clean();

				return $this->dst;
            }
            else
            {
				eval(' ?>' . $this->dst . '<?php ');
            }
		}





		/* */

		function add_var($key, $val)
		{
            $this->data['.'][$key] = $val;
		}





		/* */

		function add_vars($vars)
		{
            foreach($vars as $key => $val)
            {
                $this->data['.'][$key] = $val;
            }
		}





		/* */

        function add_block_vars($blockname, $vars)
        {
            $blocks = explode('.', $blockname);
            $block_count = count($blocks) - 1;

            $v = &$this->data;

            for($i = 0; $i < $block_count; $i++)
            {
                $v = &$v[$blocks[$i]];
                $v = &$v[count($v) - 1];
            }

			if(isset($v[$blocks[$block_count]]))
			{
				$count = count($v[$blocks[$block_count]]);
			}
			else
			{
				$count = 0;
			}

            $vars['INDEX'] = $count;

            if($count == 0)
            {
                $vars['FIRST'] = true;
            }
            else
            {
                $vars['FIRST'] = false;
                $v[$blocks[$block_count]][$count - 1]['LAST'] = false;
            }

            $vars['LAST'] = true;

            foreach($vars as $key => $val)
            {
                $vars[$key] = $val;
            }

            $v[$blocks[$block_count]][] = &$vars;

            for($i = 0; $i < $count; $i++)
            {
            	$v[$blocks[$block_count]][$count - 1]['COUNT'] = $count;
            }
        }





		/* */

		function _load_file($filename)
		{
            $handle = @fopen($filename, 'rb');
            $this->src = @fread($handle, filesize($filename));
            @fclose($handle);
		}





		/* */

		function _save_file($filename)
		{
            $handle = @fopen($filename, 'wb');
            @fwrite($handle, $this->dst);
            @fclose($handle);
		}





		/* */

		function _compile()
		{
			$this->src = str_replace(array("\r\n", "\r"), "\n", $this->src);

			$this->src = preg_replace(array('#\<\?.*?(?:\?\>|$)#s', '#\<%.*?(?:%\>|$)#s', '#\<script\s+language\s*=\s*("?)php\1\s*\>.*?(?:\<\/\s*script\s*\>|$)#is'), '', $this->src);
            $this->dst = '<?php if(!defined(\'PK_MAGIC\')) die(\'hack or what?\'); ?>';

            $list = preg_split('#({.*?})#', $this->src, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

            for($i = 0; $i < count($list); $i++)
            {
            	if(preg_match('#^{.*}$#', $list[$i]))
            	{
                    $t = trim(substr($list[$i], 1, strlen($list[$i]) - 2));

            		if(($p = strpos($t, '//')) !== false)
            		{
						$t = substr($t, 0, $p);
					}

                    if(isset($t[0]) && $t[0] == '#')
                    {
                        $t = preg_split('#([_a-z][_a-z0-9]*)#i', $t, 2, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

                        $cmd = '';
                        $args = '';

                        if(isset($t[1]))
                        {
                            $cmd = trim($t[1]);

                            if(isset($t[2]))
                            {
                                $args = trim($t[2]);
                            }
                        }

                        switch($cmd)
                        {
                            case 'include':
                            	$this->dst .= '<?php ' . $this->_compile_include($args) . ' ?>';
                                break;

                            case 'if':
                            	$this->dst .= '<?php ' . $this->_compile_if($args) . ' ?>';
                                break;

                            case 'elseif':
                            	$this->dst .= '<?php ' . $this->_compile_elseif($args) . ' ?>';
                                break;

                            case 'else':
                                $this->dst .= '<?php ' . $this->_compile_else($args) . ' ?>';
                                break;

                            case 'endif':
                            	$this->dst .= '<?php ' . $this->_compile_endif($args) . ' ?>';
                                break;

                            case 'loop':
								$this->dst .= '<?php ' . $this->_compile_loop($args) . ' ?>';
                                break;

                            case 'endloop':
                            	$this->dst .= '<?php ' . $this->_compile_endloop($args) . ' ?>';
                                break;

                            case '':
                                die('tpl: missing command after #.');
                                break;

                            default:
                                die('tpl: unknown command #'.$cmd.'.');
                                break;
                        }
                    }
                    else if($t != '')
                    {
                        $this->dst .= '<?php echo ' . $this->_expression($t) . '; ?>';
                    }
				}
				else
				{
					$this->dst .= $list[$i];
				}
            }

            $this->dst = preg_replace("#\\?>([\n]+)#", 'echo "\\1"; ?>', $this->dst);
            $this->dst = str_replace("?><?php", '', $this->dst);
		}





		/* */

		function _compile_include($args)
		{
			return '$this->_include(\'' . $args . '\');';
		}





		/* */

		function _compile_if($args)
		{
			$this->_push_tag('if');

            if($args == '')
            {
                die('missing condition for #if.');
            }

			return 'if(' . $this->_expression($args) . ') {';
		}





		/* */

		function _compile_elseif($args)
		{
            $this->_push_tag('elseif');

            if($args == '')
            {
                die('missing condition for #elseif.');
            }

			return '} else if(' . $this->_expression($args) . ') {';
		}





		/* */

		function _compile_else($args)
		{
            $tag = $this->_push_tag('else');

            if($args != '')
            {
                die('tokens after #else.');
            }

			if($tag == 'loop')
			{
				array_pop($this->block_names);
                return '} } else {';
			}

            return '} else {';
		}





		/* */

		function _compile_endif($args)
		{
            $this->_pop_tag('endif');

            if($args != '')
            {
                die('tokens after #endif.');
            }

			return '}';
		}





		/* */

		function _compile_loop($args)
		{
            $this->_push_tag('loop');

            if($args == '')
            {
                die('missing loopname for #loop.');
            }

            if(!preg_match('#^'.$this->regex_varname.'$#', $args))
            {
                die('wrong loopname for #loop.');
            }

            $block_count = count($this->block_names);

            $v = '$this->data';

            for($j = 0; $j < $block_count; $j++)
            {
                $v .= '[\'' . $this->block_names[$j] . '\'][$this->_i_' . $this->block_names[$j] . ']';
            }

            $v .= '[\'' . $args . '\']';

            array_push($this->block_names, $args);

            return '$this->_c_' . $args . ' = isset(' . $v . ') ? count(' . $v . ') : 0; if($this->_c_' . $args . ' > 0) { for($this->_i_' . $args . ' = 0; $this->_i_' . $args . ' < $this->_c_' . $args . '; $this->_i_' . $args . '++) {';
		}





		/* */

		function _compile_endloop($args)
		{
            $tag = $this->_pop_tag('endloop');

            if($args != '')
            {
                die('tokens after #endloop.');
            }

			if($tag != 'else')
			{
	            array_pop($this->block_names);
				return '} }';
			}

           	return  '}';
		}





		/* */

		function _push_tag($open_tag)
		{
			if(count($this->tag_stack) > 0)
			{
				$last_tag = $this->tag_stack[count($this->tag_stack) - 1];
			}
			else
			{
				$last_tag = '';
			}

			array_push($this->tag_stack, $open_tag);

            if($open_tag == 'elseif' && $last_tag != 'if' && $last_tag != 'elseif')
            {
            	die('no opening #if for #elseif.');
            }

            if($open_tag == 'else' && ($last_tag != 'if' && $last_tag != 'elseif' && $last_tag != 'loop'))
            {
            	die('no opening #if, #elseif or #loop for #else.');
            }

            return $last_tag;
		}





		/* */

		function _pop_tag($close_tag)
		{
			$open_tag = array_pop($this->tag_stack);

			if($open_tag != null)
			{
				if($close_tag == 'endif' && $open_tag == 'if')
				{
					return $open_tag;
				}

				if($close_tag == 'endloop' && $open_tag == 'loop')
				{
					return $open_tag;
				}

				if($close_tag == 'endif' && ($open_tag == 'elseif' || $open_tag == 'else'))
				{
					$this->_pop_tag($close_tag);
					return $open_tag;
				}

				if($close_tag == 'endloop' && $open_tag == 'else')
				{
					$this->_pop_tag($close_tag);
					return $open_tag;
				}

				if($open_tag == 'if' || $open_tag == 'elseif')
				{
					die('mismatched command #'.$close_tag.'. expected #elseif or #endif.');
				}

				if($open_tag == 'loop')
				{
					die('mismatched command #'.$close_tag.'. expected #endloop.');
				}

				if($open_tag == 'else')
				{
					die('mismatched command #'.$close_tag.'. expected #endif or #endloop.');
				}
			}
			else
			{
				if($close_tag == 'endif')
				{
					die('no opening #if for #endif.');
				}

				if($close_tag == 'endloop')
				{
					die('no opening #loop for #endloop.');
				}
			}
		}





		/* */

		function _expression($expr)
		{
            preg_match_all
            (
                '#' . $this->regex_sqstring .
                '|' . $this->regex_blockvarname .
                '|' . $this->regex_varname .
                '|' . $this->regex_hexint .
                '|' . $this->regex_float .
                '|===|!==|==|!=|<<|>>|<=|>=|\&\&|\|\|' .
                '|!|\~|\*|\/|\%|\+|\-|\.|<|>|\&|\^|\||\(|\)' .
                '|\S+#i', $expr, $list
            );

            $list = $list[0];

            for($i = 0; $i < count($list); $i++)
            {
            	switch($list[$i])
            	{
					case '===':
					case '!==':
					case '==':
					case '!=':
					case '<=':
					case '>=':
					case '<<':
					case '>>':
					case '&&':
					case '||':
            		case '!':
            		case '~':
					case '*':
					case '/':
					case '%':
            		case '+':
            		case '-':
					case '.':
                    case '<':
            		case '>':
            		case '&':
            		case '^':
            		case '|':
                    case '(':
                    case ')':
            			break;

            		default:
            			if(preg_match('#^'.$this->regex_sqstring.'$#', $list[$i])
            			|| preg_match('#^'.$this->regex_hexint.'$#', $list[$i])
            			|| preg_match('#^'.$this->regex_float.'$#', $list[$i]))
            			{
							break;
            			}
            			else if(preg_match('#^'.$this->regex_blockvarname.'$#i', $list[$i]))
            			{
            				$lr = explode('.', $list[$i]);

                            $block_count = sizeof($this->block_names);

                            $v = '$this->data';

                            for($j = 0; $j < $block_count; $j++)
                            {
								$v .= '[\'' . $this->block_names[$j] . '\'][$this->_i_' . $this->block_names[$j] . ']';

								if($this->block_names[$j] == $lr[0])
								{
									break;
								}
                            }

							$list[$i] = $v . '[\'' . $lr[1] . '\']';
							break;
            			}
            			else if(preg_match('#^'.$this->regex_varname.'$#i', $list[$i]))
            			{
            				/*if(isset($this->data['.'][$list[$i]]))
            				{*/
								$list[$i] = '$this->data[\'.\'][\'' . $list[$i] . '\']';
							/*}
							else
							{
								die('unknown var "' . $list[$i] . '".');
							}*/

							break;
            			}

						die('unknown token "' . $list[$i] . '".');
            			break;
            	}
            }

            return implode(' ', $list);
		}





		/* */

		function _include($filename)
		{
			global $config;
			global $lang;
			global $style;

			if($this->mail)
			{
				$this->filename = $config['mail_path'] . $filename;
				$this->cachename = $config['cache_path'] . 'mails.' . $lang['dir'] . '.' . $filename . '.php';
			}
			else
			{
				$this->filename = $config['style_path'] . $filename;
				$this->cachename = $config['cache_path'] . 'styles.' . $style['dir'] . '.' . $filename . '.php';
			}

            $this->display();

            return $this->cachename;
		}
	}
?>
Return current item: pkZoos Website