<?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;