<?php

class DOMWidgetML {
  var 
$widgettomb = array();
  var 
$sql = array();
  var 
$errors = array();
  var 
$selects = array();
  var 
$css = array();
  var 
$js = array();
  var 
$php = array();
  var 
$dom null;
  var 
$site null;
  var 
$page null;
  public function 
__construct($widget_site,$widget_page,$widget_errors=array()){
    
$this->site $widget_site;
    
$this->page $widget_page;
    
$this->errors $widget_errors;
    if(!empty(
$this->page) && !empty($this->site)){
      
$this->widget_generate_page();
      
    };
  }
  public function 
getErrors(){
    return 
$this->errors;
  }


/*****************************************************************************/

function widget_generate_page(){

libxml_use_internal_errors(true);

    
$select "SELECT * FROM ".$this->site."_page INNER JOIN ".$this->site."_init ON FID_WIDGET_INIT=ID_WIDGET_INIT WHERE PAGE_LABEL=0x".bin2hex($this->page);
    if(
$result=mysql_query($select)){
      if(
$fejlec=mysql_fetch_assoc($result)){

          
$this->dom = new DOMDocument('1.0',$fejlec['ENCODING']);
          
$implementation = new DOMImplementation();
          
$this->dom->appendChild($implementation->createDocumentType('html'));
          
$this->dom->formatOutput true;
          
          
          
$select "SELECT ID_WIDGET,WIDGET_TYPE,WIDGET_XML,WIDGET_CSS,WIDGET_JS,WIDGET_PHP FROM ".$this->site."_widgets INNER JOIN ".$this->site."_page_widgets ON FID_WIDGET=ID_WIDGET INNER JOIN ".$this->site."_page ON FID_PAGE=ID_PAGE AND ID_PAGE=".$fejlec['ID_PAGE']." ORDER BY ID_WIDGET";
          if(
$result=mysql_query($select)){
            while(
$sor=mysql_fetch_assoc($result)){
              
$this->widget_prepare($sor['WIDGET_XML']);
              if(!empty(
$sor['WIDGET_CSS'])){
                
$this->css[$sor['WIDGET_TYPE']]=$sor['WIDGET_CSS'];
              };
              if(!empty(
$sor['WIDGET_JS'])){
                
$this->js[$sor['WIDGET_TYPE']]=$sor['WIDGET_JS'];
              };
              if(!empty(
$sor['WIDGET_PHP'])){
                
$this->php[$sor['WIDGET_TYPE']]=$sor['WIDGET_PHP'];
              };
          
              
$this->selects[$sor['WIDGET_TYPE']]=array();
              
$select "SELECT * FROM ".$this->site."_widgets_sql WHERE FID_WIDGET=".$sor['ID_WIDGET'];
              if(
$result2=mysql_query($select)){
                while(
$sor2=mysql_fetch_assoc($result2)){
                  
$this->selects[$sor['WIDGET_TYPE']][$sor2['WIDGET_SQL_LABEL']]=$sor2['WIDGET_SQL'];
                };
              };
          
            };
          };
          
//echo mysql_error();
          
          
$temp $this->dom->createElement('widget');
          
$temp->setAttribute('type',$this->page.'-html');
          
$temp->setAttribute('param:lang',"'".$fejlec['LANG']."'");
          
$temp->setAttribute('param:charset',"'".$fejlec['ENCODING']."'");
          
$temp->setAttribute('param:xmlns',"'".$fejlec['XMLNS']."'");
          
$this->dom->appendChild($temp);
          
$this->widget_apply($temp);
          
//print_r($errors);
          
          
$style $this->dom->createElement('style');
          
$style->appendChild($this->dom->createCDATASection(implode("\n\n/**********************************************/\n\n",$this->css)));
          
$this->dom->getElementsByTagName('body')->item(0)->appendChild($style);
          
          
$script $this->dom->createElement('script');
          
$script->appendChild($this->dom->createCDATASection(implode("\n\n/**********************************************/\n\n",$this->js)));
          
$this->dom->getElementsByTagName('body')->item(0)->appendChild($script);
          
          
          if(
$fejlec['TYPE']=="application/xhtml+xml"){
            
header("Content-Type: application/xhtml+xml; charset=".$fejlec['ENCODING']);

            
//echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 2.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml2.dtd">'."\n";
            
echo $this->dom->saveXML();
          }else{
            
header("Content-Type: text/html; charset=".$fejlec['ENCODING']);
            echo 
"<!DOCTYPE html>\n";
            echo 
$this->dom->saveHTML($this->dom->documentElement);
          };

        
      };
    };

}

/*****************************************************************************/

function widget_prepare($widget){
  
//$widget = iconv("UTF-8","UTF-8//IGNORE",$widget); // "<"."?xml version=\"1.0\" encoding=\"UTF-8\"?".">"
  //$widget= mb_convert_encoding($widget,'UTF-8');
  //echo $widget;
  
$domwidget = new DOMDocument('1.0','UTF-8');
  
$domwidget->loadXML("<"."?xml version=\"1.0\" encoding=\"UTF-8\"?".">".$widget,LIBXML_NOBLANKS);
  if (
$domwidget === false) {
    
$this->errors[] = 'widget_prepare: Error while parsing the document';
    foreach(
libxml_get_errors() as $error){
      
$this->errors[] = $error->message;
    };
    return 
0;
  };
  
  
$domwidget $domwidget->documentElement;
  
$this->dom->importNode($domwidget,true);

  
// widget re-wrap
  
if(!empty($domwidget->getAttribute('nodeName'))){
    
$new $this->dom->createElement($domwidget->getAttribute('nodeName'));
  }else{
    
$new $this->dom->createElement('void');
  };
  
$new->setAttribute('data-widget',$domwidget->getAttribute('type'));
  
$domwidget->removeAttribute('nodeName');
  
$domwidget->removeAttribute('type');
  foreach(
$domwidget->attributes as $attr){
    
$new->setAttribute($attr->name,$attr->value);
  };
  
$elem $domwidget->firstChild;
  while(
$elem){
    
$temp $this->dom->importNode($elem,true);
    
$new->appendChild($temp);
    
$elem $elem->nextSibling;
  };
  
$this->widgettomb[$new->getAttribute('data-widget')] = $new;

}

/*****************************************************************************/

function widget_eval($kulcs,$valtozo,$params,$tomb,$itemstring=""){
  
/*if(preg_match("/\./",$valtozo)){
    $temp = explode(".",$valtozo);
    $tombstring = $temp[0];
    $itemstring = $temp[1];
  };*/
  
if($valtozo==$itemstring && !isarray($tomb)){
    
//exact valtozo
    
return $tomb;
  }elseif(!
preg_match("/'.*'/",$valtozo)){ // nincs benne string
    // prefix eltavolitasa
    
$temp preg_replace("/".$itemstring."\./","",$valtozo);
    if(
array_key_exists($temp,$params)){ //parameter valtozo
      
$temp $params[$temp];
    }elseif(
is_array($params[$itemstring]) && array_key_exists($temp,$params[$itemstring])){ //parameter valtozo
      
$temp $params[$itemstring][$temp];
    }elseif(
is_array($tomb) && array_key_exists($itemstring,$tomb)){ // loop valtozo
      
$temp $tomb[$itemstring][$temp];
    }elseif(empty(
$temp)){
      return 
'';
    };
    
//echo $itemstring;
    //print_r($tomb);
    
return $temp;
  }else{
    return 
preg_replace("/'/","",$valtozo);
  }
}

/*****************************************************************************/

function widget_apply($item,$params=array(),$tomb=array(),$itemstring=""){

  if(
$item->nodeType!=1) { // not a Tag
    
return;
  };

  
// if kezeles
  
if($item->hasAttribute('if') && ($ifstring $item->getAttribute('if'))){
    
$item->removeAttribute('if');
    
$value=preg_replace("/".$itemstring."\./","",$ifstring);
    if(!
$this->widget_eval(null,$value,$params,$tomb,$itemstring)){
      
$item->parentNode->removeChild($item);
      return;
    };
  };
  
// if kezeles vege
  
  // loop kezeles
  
if($item->hasAttribute('loop') && ($loopstring $item->getAttribute('loop'))){
    
$item->removeAttribute('loop');
    
$expr explode(" in ",$loopstring);
    
$tombstring $expr[1];
    
$elemstring $expr[0];
    if(isset(
$tomb[$tombstring]) && sizeof($tomb[$tombstring])){
      foreach(
$tomb[$tombstring] as $kulcs => $ertek){
        
$temp $item->cloneNode(true);
        
$item->parentNode->insertBefore($temp,$item);
        
$temptomb $tomb;
        
$temptomb[$elemstring]=$ertek;
        
$tempparams $params;
        if(
$temp->nodeName=='widget'){
          
$temp->setAttribute('iteration',$elemstring);
          
$tempparams[$elemstring] = $ertek;
        };
        
$this->widget_apply($temp,$tempparams,$temptomb,$elemstring);
      };
    };
    
$item->parentNode->removeChild($item);
    return;
  };
  
// loop kezeles vege
  
  // void kezeles
  
if($item->nodeName=='void'){
    
$temp $item->firstChild;
    while(
$temp){
      
$item->parentNode->insertBefore($temp,$item);
      
$this->widget_apply($temp,$params,$tomb,$itemstring);
      
$temp $item->firstChild;
    };
    
$item->parentNode->removeChild($item);
    return;
  };
  
// void kezeles vege
  
  // widget kezeles
  
if($item->nodeName=="widget"){
    if(
$item->hasAttribute('type') && isset($this->widgettomb[$item->getAttribute('type')])){
      
$elem $this->widgettomb[$item->getAttribute('type')];
      if(
$elem->hasAttribute('once')){
        unset(
$this->widgettomb[$item->getAttribute('type')]);
      }else{
        
$elem $elem->cloneNode(true);
      };
      
$elem->removeAttribute('once');
      if(
$elem->hasAttribute('hidden')){
        
$elem->removeAttribute('data-widget');
        
$elem->removeAttribute('hidden');
      };
      
$item->parentNode->replaceChild($elem,$item);
      
$tempparams = array();
      foreach(
$item->attributes as $kulcs => $ertek){
        if(
preg_match("/^param:/",$ertek->name)){
          
$name=preg_replace("/^param:/","",$ertek->name);
          
$tempparams[$name]=$this->widget_eval($name,$ertek->value,$params,$tomb,$itemstring);
          if(!
$tempparams[$name]){
            
$tempparams[$name]=$ertek->value;
          };
        };
        if(
$ertek->name=='iteration'){
          
$tempparams[$ertek->value] = $params[$ertek->value];
        };
      };

      
$_REQUEST['params']=$tempparams// crappy!!!!
      
$params $tempparams;
      
$temptomb = array();//$tomb = array();
      
if($this->selects[$item->getAttribute('type')]){
        foreach(
$this->selects[$item->getAttribute('type')] as $label => $egysql){
          
$matches = array();
          if(
preg_match_all("/\{\{([^(\{\})]*)\}\}/",$egysql,$matches)){
            foreach(
$matches[1] as $key => $egymatch){
              @eval(
"\$str=".preg_replace('/"/',"",$egymatch).";");
              
$temp preg_replace(array("/\[/","/\]/","/\\$/"),array("\\[","\\]","\\\\$"),$egymatch);
              
$egysql preg_replace("/\{\{".$temp."\}\}/",$str,$egysql);
            };
          };
          
//$egysql = preg_replace_callback("/\{\{([^(\{\})]*)\}\}/",function($matches){@eval("\$str=".preg_replace('/"/',"",$matches[1]).";");return $str;},$egysql);
          //print_r($params);
          
if($result=mysql_query($egysql)){
            while(
$sor=mysql_fetch_assoc($result)){
              
$temptomb[$label][]=$sor;
            };
            
$this->selects[$label]=$temptomb[$label];
            
$tomb[$label]=$temptomb[$label];
          };
        };
      };
      
$tomb $temptomb;
      if(
$this->php[$item->getAttribute('type')]){
        eval(
$this->php[$item->getAttribute('type')]);
      };
      
$this->widget_apply($elem,$params,$tomb,$itemstring);
    }else{
      
$this->errors[] = 'Nem letezo widgettipus: '.$item->getAttribute('type');
    };
    return;
  };
  
// widget kezeles vege
  
  // text kezeles
  
if($item->nodeName=="text"){
    
$value=preg_replace("/".$itemstring."\./","",$item->textContent);
    
$value $this->widget_eval($item->textContent,$value,$params,$tomb,$itemstring);
    if(
$item->getAttribute('inner')=="html"){
      
$temp simplexml_load_string("<temp>".$value."</temp>");
      if(
$temp !== false){
        
$tempdom dom_import_simplexml($temp);
        
$elem $tempdom->firstChild;
        while(
$elem){
          
$tempdom->removeChild($elem);
          
$elem $this->dom->importNode($elem,true);
          
$item->parentNode->insertBefore($elem,$item);
          
$this->widget_apply($elem,$params,$tomb,$itemstring);
          
$elem $tempdom->firstChild;
        };
      }else{
        
$temp $this->dom->createTextNode($value);
        
$item->parentNode->replaceChild($temp,$item);
      };
    }else{
      
$temp $this->dom->createTextNode($value);
      
$item->parentNode->replaceChild($temp,$item);
    };
    return;
  };
  
// text kezeles vege

  // raw kezeles
  
if($item->nodeName=="raw"){
    
$value=preg_replace("/".$itemstring."\./","",$item->textContent);
    
$value $this->widget_eval($item->textContent,$value,$params,$tomb,$itemstring);
    
$temp $this->dom->createCDATASection($value);
    
$item->parentNode->replaceChild($temp,$item);
    return;
  };
  
// raw kezeles vege

  // attributum bind kezeles
  
$ertek $item->attributes->item(0);
  
$temptomb = array();
  while(
$ertek){
    if(
preg_match("/^bind:/",$ertek->name)){
      
$name=preg_replace("/^bind:/","",$ertek->name);
      
$value $this->widget_eval($name,$ertek->value,$params,$tomb,$itemstring);
      if(!empty(
$value)){
        
$item->setAttribute($name,$value);
      };
      
$temptomb[$ertek->name]=$ertek->name;
    };
    
$ertek $ertek->nextSibling;
  };
  foreach(
$temptomb as $ertek){
    
$item->removeAttribute($ertek);
  };
  
// attributum bind kezeles vege


  // childnodes
  
$elem $item->firstChild;
  while(
$elem){
    
$next $elem->nextSibling;
    
$this->widget_apply($elem,$params,$tomb,$itemstring);
    
$elem $next;
  };
  
// childnodes vege

}

/****************************************************************************/

};

?>