<?php
/**
* TplParser - class parse all HTML files and display from
* this files PHP variables
* @access public
* @version 1.2.3
* @date 2007-05-11 09:29:40
*/
class TplParser
{

	var $content;
	var $TplFile;
	var $block;
	var $startBlock;
	var $endBlock;
  var $endBlockLine;
  var $fileContent;	
  var $blockContent;
  var $cache;
  var $directory;

  /**
  * Constructor
  */
	function TplParser( ){
		$this->content 		  = null;
		$this->TplFile 		  = null;
		$this->block			  = null;
		$this->startBlock   = '<!-- BEGIN ';
		$this->endBlock 	  = '<!-- END ';
    $this->endBlockLine = ' -->';
    $this->bTrim        = true;
	} // end function TplParser
	
  /**
  * Display parsed file
  * @return void
  * @param string $sFile - file *.tpl
  * @param bool   $bTrim
  */
	function dHtml( $sFile, $bTrim = true ){
		$this->setFile( $this->directory.$sFile );
    $this->bTrim = $bTrim;

		$this->display( );
    echo $this->content;
    unset( $this->content );
	} // end function dHtml

  /**
  * Return parsed file
  * @return string
  * @param string $sFile - file *.tpl
  * @param bool   $bTrim
  
  */
	function tHtml( $sFile, $bTrim = true ){
		$this->setFile( $this->directory.$sFile );
    $this->bTrim = $bTrim;

		$this->display( );
		return $this->content;
	} // end function tHtml

  /**
  * Display parsed block from file
  * @return void
  * @param string $sFile - file *.tpl
  * @param string $sBlock
  * @param bool   $bTrim
  */
	function dbHtml( $sFile, $sBlock, $bTrim = true ){
		$this->setFile( $this->directory.$sFile );
		$this->setBlock( $sBlock );

    $this->bTrim = $bTrim;

		$this->display( true );
    echo $this->content;
    unset( $this->content );
	} // end function dbHtml
	
  /**
  * Return parsed block from file
  * @return string
  * @param string $sFile - file *.tpl
  * @param string $block
  * @param bool   $cache
  */
	function tbHtml( $sFile, $sBlock, $bTrim = true ){
		$this->setFile( $this->directory.$sFile );
		$this->setBlock( $sBlock );

    $this->bTrim = $bTrim;

		$this->display( true );
		return $this->content;
	} // end function tbHtml

  /**
  * Function execute functions depend by parameter
  * @return void
  * @param bool $bBlock [optional]
  */
	function display( $bBlock = null ){
		if( $this->checkFile( ) ){
			if( isset( $bBlock ) )
				$this->blockParse( );
			else
				$this->allParse( );
		}
	} // end function display
	
	/**
  * Function check if file exists
  * @return boolean
  */
	function checkFile( ){
		if( is_file( $this->TplFile ) ){
	  	return true;
	  }
		else {
      $this->content = null;
			echo 'No template file: <i>'.$this->TplFile.'</i><br />';
			return false;
		}
	} // end function checkFile
	
  /**
  * Function parse $this->content
  * @return boolean
  */
	function parse( ){
    $this->content .= ' ';
    preg_match_all( '/(\$[a-zA-Z_]+[a-zA-Z0-9_]*)(([\[]+[\']*[a-zA-Z0-9_]+[\']*[\]]+)*)/', $this->content, $aResults );
    if( isset( $aResults[1] ) && is_array( $aResults[1] ) ){
      $iCount = count( $aResults[1] );
      for( $i = 0; $i < $iCount; $i++ ){
        $aResults[1][$i] = substr( $aResults[1][$i], 1 );      
        global $$aResults[1][$i];

        // array
        if( isset( $aResults[2] ) && !empty( $aResults[2][$i] ) ){
          if( ereg( '\'', $aResults[2][$i] ) ){
            $aResults[2][$i] = str_replace( '\'', null, $aResults[2][$i] );
            $sSlash = '\'';
          }
          else
            $sSlash = null;

          preg_match_all( '/[a-zA-Z_\'0-9]+/', $aResults[2][$i], $aResults2 );
          $iCount2 = count( $aResults2[0] );
          if( $iCount2 == 2 ){
            if( isset( ${$aResults[1][$i]}[$aResults2[0][0]][$aResults2[0][1]] ) )
              $aReplace[] = ${$aResults[1][$i]}[$aResults2[0][0]][$aResults2[0][1]];
            else
              $aReplace[] = null;
            $aFind[] = '/\$'.$aResults[1][$i].'\['.$sSlash.$aResults2[0][0].$sSlash.'\]\['.$sSlash.$aResults2[0][1].$sSlash.'\]/';
          }
          else{
            if( isset( ${$aResults[1][$i]}[$aResults2[0][0]] ) )
              $aReplace[] = ${$aResults[1][$i]}[$aResults2[0][0]];
            else
              $aReplace[] = null;
            $aFind[] = '/\$'.$aResults[1][$i].'\['.$sSlash.$aResults2[0][0].$sSlash.'\]/';
          }
        }
        else{
          if( !is_array( $$aResults[1][$i] ) ){
            $aReplace[] = $$aResults[1][$i].'\\1';
            $aFind[] = '/\$'.$aResults[1][$i].'([^a-zA-Z0-9])/';
          }
        }
      } // end for
    }

    if( isset( $aFind ) ){
      $this->content = preg_replace( $aFind, $aReplace, $this->content );
    }
    if( isset( $this->bTrim ) )
      $this->content = trim( $this->content );
    return true;
		
	} // end function parse
	
  /**
  * Function return all data from file
  * @return void
  */
	function allParse( ){
    if( isset( $this->fileContent[$this->TplFile] ) ){
      $this->content = $this->fileContent[$this->TplFile];
    }
    else{
      $this->content = $this->getContent( );
    }
		$this->parse( );
	} // end function allParse
	
  /**
  * Get defined block from file
  * @return boolean
  */
	function blockParse( ){
   
    if( isset( $this->blockContent[$this->TplFile][$this->block] ) ){
      $this->content = $this->blockContent[$this->TplFile][$this->block];
    }
    else{
      $this->content = $this->getFileBlock( );
      if( isset( $this->content ) ){
        $this->blockContent[$this->TplFile][$this->block] = $this->content;
      }
    }
    $this->parse( );
	} // end function blockParse

  /**
  * Get file data from file or from cache variable ($this->fileContent)
  * @return array
  * @param bool $bBlock
  */
  function getContent( $bBlock = null ){
    if( isset( $this->fileContent[$this->TplFile] ) ){
      $mReturn = $this->fileContent[$this->TplFile];
    }
    else{
      if( isset( $bBlock ) ){
        $mReturn = $this->getFile( $this->TplFile );
      }
      else{
        $mReturn = $this->getFile( $this->TplFile );
      }

      $this->fileContent[$this->TplFile] = $mReturn;
    }
    return $mReturn;
  } // end function getContent

  /**
  * Return file content
  * @return string
  * @param string $sFile
  */
  function getFile( $sFile ){
    $rFile =  fopen( $sFile, 'r' );
    $iSize =  filesize( $sFile );
    if( $iSize > 0 )
      $sContent = fread( $rFile, $iSize );
    else
      $sContent = null;
    fclose( $rFile );
    return $sContent;
  } // end function getFile

  /**
  * Return block from file
  * @return string
  * @param string $sFile [optional]
  * @param string $sBlock [optional]
  */
  function getFileBlock( $sFile = null, $sBlock = null ){
    if( isset( $sFile ) && isset( $sBlock ) ){
      $this->setFile( $sFile );
      $this->setBlock( $sBlock );
    }

    $sFile = $this->getContent( true );

    $iStart = strpos( $sFile, $this->startBlock.$this->block.$this->endBlockLine );
    $iEnd =   strpos( $sFile, $this->endBlock.$this->block.$this->endBlockLine );

    if( is_int( $iStart ) && is_int( $iEnd ) ){
      $iStart += strlen( $this->startBlock.$this->block.$this->endBlockLine );
      return substr( $sFile, $iStart, $iEnd - $iStart );
    }
    else {
      echo 'No block: <i>'.$this->block.'</i> in file: '.$this->TplFile.' <br />';
      return null;
    }
  } // end function getFileBlock

  /**
  * Return file to array
  * @return array
  * @param string $sFile
  */
  function getFileArray( $sFile ){
    return file( $sFile );
  } // end function getFileArray

  /**
  * Return defined $this->directory variable
  * @return string
  */
  function getDir( ){
    return $this->directory;
  } // end function getDir

  /**
  * Function define $this->directory variable
  * @return void
  * @param string $sDir
  */
  function setDir( $sDir ){
    $this->directory = $sDir;
  } // end function setDir

  /**
  * Function define $this->TplFile variable
  * @return void
  * @param string $sFile
  */
  function setFile( $sFile ){
    $this->TplFile = $sFile;
  } // end function setFile

  /**
  * Function define $this->block variable
  * @return void
  * @param string $sBlock
  */
  function setBlock( $sBlock ){
    $this->block = $sBlock;
  } // end function setBlock

}; // end class TplParser
?>