<?
$GLOBALS["INCLUDED_LIBS"]["PATTERNIZER"] = true;
/**
* Basic pattern parser
*
* Provides a low-level layer to parse patterns. It searches for commands like <%command%> inside the pattern and executes a specific function with him.
* This command-interpreter is not implemented at this class level, the method command has to be overloaded by an extended, higher-level class, like patternizer_commandparser
*
* @author Llorenç Herrera <hide@address.com>
* @version 1.2
* @package patternizer
*/
class patternizer
{
/**
* @access private
*/
var $tag_start = "<%";
/**
* @access private
*/
var $tag_end = "%>";
/**
* @access private
*/
var $tag_start_length;
/**
* @access private
*/
var $tag_end_length;
/**
* @access private
*/
function patternizer ()
{
$this->tag_start_length = strlen ($this->tag_start);
$this->tag_end_length = strlen ($this->tag_end);
}
/**
* Returns the parsed contents of a file (a pattern)
*
* @see patternizer::parse()
* @param string $filename The file name of the pattern to parse
* @return string The parsed contents of the pattern
*/
function patternize ($filename)
{
$pattern = $this->getfile ($filename);
if (!$pattern)
return $this->error ("Could not access the requested pattern: <b>$filename</b>");
$patternized = $this->parse ($pattern);
return $patternized;
}
/**
* Parses the specified string and returns it
*
* Use this method if you want to parse a specific string, instead of a file.
*
* @see patternizer::patternize()
* @param string $string String to parse
* @return string The parsed string
*/
function parse ($string)
{
$pos = 0;
$lastpos = 0;
while (($pos = strpos ($string, $this->tag_start, $pos)) !== false)
{
$tag_start_pos = $pos;
$tag_end_pos = strpos ($string, $this->tag_end, $pos + strlen ($this->tag_start));
$pos = $tag_end_pos + $this->tag_end_length;
$command = substr ($string, $tag_start_pos + $this->tag_start_length, $tag_end_pos - $tag_start_pos - $this->tag_end_length);
$endstring .= substr ($string, $lastpos, $pos-$lastpos - strlen ($command) - $this->tag_start_length - $this->tag_end_length);
$lastpos = $pos;
$endstring .= $this->command ($command);
}
$endstring .= substr ($string, $lastpos);
return $endstring;
}
/**
* @access private
*/
function getfile ($filename)
{
if (!file_exists (realpath ($filename)) || !$fd = fopen (realpath ($filename), "r"))
return false;
$pattern = fread ($fd, filesize ($filename));
fclose ($fd);
return $pattern;
}
/**
* Sets the start and end tags of the commands
*
* Defaults to <% and %>
*
* @param string $start Start tag, defaults to <%
* @param string $end End tag, defaults to %>
*/
function settags ($start, $end)
{
$this->tag_start = $start;
$this->tag_end = $end;
$this->tag_start_length = strlen ($start);
$this->tag_end_length = strlen ($end);
}
/**
* @access private
*/
function error ($string)
{
return "<div style='font-family: Terminal, Courier, Courier New; font-size: 12px; color: #880000; background-color: #f4f4f4; border-width: 1px; border-style: dotted; padding: 3px;'><b>ERROR:</b> $string</div>";
}
// To be overloaded by patternizer higher-level classes
/**
* Internally called, this performs the specific stuff with the command that are found in the pattern
*
* It has to be overloaded by a higher-level extended class, like patternizer_commandparser {@link patternizer_commandparser}
*
* @param string $command The command that have been found in the pattern and has to be treated
* @return string Whatever the overloaded method returns in relation to the stuff it does with the command
*/
function command ($command)
{
// This patternizer class can't execute commands, this method must be overloaded by higher level classes.
return $this->error ("Command <%$command%> can't be executed at this patternizer class level.");
}
}
?>