Location: PHPKode > projects > Simple Way to Usenet > libs/core/parser/blocks/block_logic.class.php
<?php
/**
 * @author  Benjamin Gillissen <hide@address.com>
 * 
 *	**************************************************************

	Copyright (C) 2007  Benjamin Gillissen
	
	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public License
	as published by the Free Software Foundation; either version 2
	of the License, or (at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details at:
	http://www.gnu.org/copyleft/gpl.html

 *	**************************************************************
 */
class block_logic extends tpl_parser {
	
	private static $tagmatch 	= "#(\{--)(LOGIC)(=)([\w\W]+?)(--})#";
	private static $logic		= '4';
		
	private static $logics 		= Array('===', '!==', '==', '!=', '<=', '>=', '<', '>');
	private static $checks 		= Array('null', 'array', 'int', 'num', 'float', 'bool', 'true', 'false', 'empty', 'notempty', 'pair', 'impair');
	
	
	private $arg;
	private $lblk;
	
	/**
	 * Constructor
	 * @param $hdl 		: Ressource, template file handler
	 * @param $tag		: Object, the open tag object that declare this block 
	 * @param $ldata 	: Array, Gived by reference - local data source
	 * @param $gdata 	: Optional Array, Gived by reference - global data source
	 * @return void 	
	 */
	public function __construct($hdl, $tag, $epos, $depth, $of){
		//echo "$depth] New block Logic @ ".$tag->start()."<br/>\n";
		parent::__construct($hdl, $tag->end(), $epos, $depth, $of);
		$this->otag=$tag;
	}

	public function end(){ return $this->ctag->end(); }

	public function load_tagargs($tag=NULL){
		//echo "$this->depth] Block Logic @ ".$this->otag->start()." : Loading tagargs<br/>\n";
		if ( $tag === NULL ){ $tag =$this->otag->read(); } 
		preg_match(self::$tagmatch, $tag, $result);
		if ( !isset($result[self::$logic]) ){ return FALSE; }
		$this->arg = trim($result[self::$logic]);
		//echo "$this->depth] Block Logic @ ".$this->otag->start()." : arg is :$this->arg<br/>\n";
		return TRUE;
	}
	
	public function recurloads(){
		$r = $this->detect_block('LOGIC', TRUE);
		if ( !isset($this->ctag) ){
			//echo "$this->depth] Close tag could not be found for block LOGIC @ ".$this->otag->start()."<br/>\n";
			errors::raise("Close tag could not be found for block LOGIC @ ".$this->otag->start(), CORE_LOG_ERROR, 'TPL');
			return FALSE;
		}
		//echo "$this->depth] Searching for optional Logic-Else tag in loaded blocks<br/>\n";
		$bool=TRUE;
		foreach($this->blocks as $k => $blk ){
			if ( $blk->plugin() === 'logic_else' ){ 
				$bool = FALSE;
			} else {
				$this->lblk[$bool][] = $blk;
			}		 
		}
		unset($this->blocks);
		return $r;
	}
	
	
	/**
	 * return the parsed content of this block
	 * for this is loop through data source, and parse
	 * the block once for each entries
	 * for this block
	 * @param none
	 * @return 	String, the parsed block
	 */
	public function plugparse($l, $g, $return ){
		$bool = $this->compute_logic($l, $g);
		if ( ! isset($this->lblk[$bool]) ){
			if ( $return ){ return ''; }
			return TRUE;
		}
		$this->blocks = & $this->lblk[$bool];
		return $this->parse($l, $g, $return);
	}
	
	public function plugparse_before($l, $g, $return, $bref ){
		$bool = $this->compute_logic($l, $g);
		if ( ! isset($this->lblk[$bool]) ){
			if ( $return ){ return ''; }
			return TRUE;
		}
		$this->blocks = & $this->lblk[$bool];
		return $this->parse_before($l, $g, $return, $bref);
	}
	
	public function plugparse_after($l, $g, $return, $bref ){
		$bool = $this->compute_logic($l, $g);
		if ( ! isset($this->lblk[$bool]) ){
			if ( $return ){ return ''; }
			return TRUE;
		}
		$this->blocks = & $this->lblk[$bool];
		return $this->parse_after($l, $g, $return, $bref);
	}
	
	public function plugparse_between($l, $g, $return, $sbref, $ebref){
		$bool = $this->compute_logic($l, $g);
		if ( ! isset($this->lblk[$bool]) ){
			if ( $return ){ return ''; }
			return TRUE;
		}
		$this->blocks = & $this->lblk[$bool];
		return $this->parse_between($l, $g, $return, $sbref, $ebref);
	}
	
	public function plugparse_once($l, $g, $return, $bref, $data, $key){
		
	}
	
	private function compute_logic($l, $g){
		$logic = $this->getlogic();
		if ( FALSE === $logic ){
			errors::raise("Unknow logic in tag @ ".$this->otag->start(), CORE_LOG_ERROR, 'TPL');
			return FALSE;
		}
		if ( $this->logic_ischecks($logic) ){ return $this->compute_checks($logic, $l, $g); }
		$buf = split($logic, $this->arg);
		$val1 = $this->get_sourceval(trim($buf[0]), $l, $g);
		$val2 = $this->get_sourceval(trim($buf[1]), $l, $g);
		switch( $logic ){
			case '==='	:	return ( $val1 === $val2 );
							break;
			case '!=='	: 	return ( $val1 !== $val2 );
							break;
			case '=='	:	return ( $val1 == $val2 );
							break;
			case '!='	: 	return ( $val1 != $val2 );
							break;
			case '<='	:	return ( $val1 <= $val2 );
							break;
			case '>='	: 	return ( $val1 >= $val2 );
							break;
			case '<'	:	return ( $val1 < $val2 );
							break;
			case '>'	: 	return ( $val1 > $val2 );
							break;
		}
		return FALSE;
	}
	
	private function compute_checks($logic, $l, $g){
		$buf = split('is'.$logic, $this->arg);
		if ( isset($buf[1]) ){
			$buf[1] = trim($buf[1]);
			if ( !empty($buf[1]) ){
				errors::raise('Logic argument is supposed to be before the check keyword ! @ '.$this->otag->start(), CORE_LOG_NOTICE, 'TPL');
				$val1 = $this->get_sourceval($buf[1], $l, $g);
			}
		}
		if (!isset($val1) ){
			$buf[0] = trim($buf[0]); 
			$val1 = $this->get_sourceval($buf[0], $l, $g); 
		}
		unset($buf);
		switch( $logic ){
			case 'null'		:	return is_null($val1);
								break;
			case 'array'	: 	return is_array($val1);
								break;
			case 'int'		:	return is_int($val1);
								break;
			case 'num'		: 	return is_num($val1);
								break;
			case 'real'		: 	return is_real($val1);
								break;
			case 'float'	: 	return is_float($val1);
								break;
			case 'bool'		: 	return is_bool($val1);
								break;
			case 'true'		: 	return ($val1 === TRUE);
								break;
			case 'false'	: 	return ($val1 === FALSE);
								break;
			case 'empty'	: 	return empty($val1);
								break;
			case 'notempty'	: 	return ! empty($val1);
								break;
			case 'pair'		: 	return ! is_float($val1 / 2);
								break;
			case 'impair'	: 	return is_float($val1 / 2);
								break;
		}
		return FALSE;
	}
	
	private function getlogic(){
		foreach(self::$logics as $t){ if ( ereg($t, $this->arg) ){ return $t; }	}
		foreach(self::$checks as $t){ if ( ereg('is'.$t, $this->arg) ){ return $t; }	}
		return FALSE;
	}
	
	private function logic_ischecks($logic){ return (FALSE !== array_search($logic, self::$checks) ); }
	
	
	private function get_sourceval($k, $l, $g){
		if ( $l !== NULL AND FALSE !== strpos($k, '$') ){
			//echo 'Searching in Local Data For '.$k."<br/>\n";
			tpl_data::fetch_reset($l);
			while( FALSE !== ($data = tpl_data::fetch($l) ) ){
				if ( CORE::iserror($data) ){ 
					errors::raise("Invalid Local Data context in logic @ ".$this->otag->start().", no '\$' variable will be available as logic argument !", CORE_LOG_ERROR, 'TPL');
					break;
				} elseif ( '$'.$data[0] == $k ){ return $data[1]; }
			}
			//errors::raise("Logic argument '$k', was not found in this context @ ".$this->otag->start(), CORE_LOG_NOTICE, 'TPL');
		}
		if ( $g !== NULL AND ereg("%", $k) ){
			tpl_data::fetch_reset($g);
			while( FALSE !== ($data = tpl_data::fetch($g) ) ){
				if ( CORE::iserror($data) ){ 
					errors::raise("Invalid Global Data context in logic @ ".$this->otag->start().", no '%' variable will be available as logic argument !", CORE_LOG_ERROR, 'TPL');
					break;
				}
				if ( '%'.$data[0] == $k ){ return $data[1]; }
			}
			//errors::raise("Logic argument '$k', was not found in this context @ ".$this->otag->start(), CORE_LOG_NOTICE, 'TPL');
		}
		return $k;
	}
	
	
}
return 1;
Return current item: Simple Way to Usenet